通用内核扩展无法释放 OSObject 派生类

2023-12-22

我有通用内核扩展,它是在 C++ 示例中实现的开始和结束例程,而所有其他逻辑都存储在继承自的专用类中OSObject.

它在模块启动例程时创建类,并在停止例程时释放它,如下面的代码所示:

class com_my_driver : public OSObject { ... };

...
..
.

com_my_driver *gDriver = NULL;

extern "C" kern_return_t my_driver_start(kmod_info_t * ki, void *d)
{
    gDriver = new com_my_driver;
    gDriver->init();
    return KERN_SUCCESS;
}

extern "C" kern_return_t my_driver_stop(kmod_info_t *ki, void *d)
{
    gDriver->release();
    gDriver = nullptr;
    return KERN_SUCCESS;
}

但是,当尝试卸载服务时,它无法到达停止例程,因为该类仍在被引用(我假设它到达了我释放此类的停止例程)。这是确切的日志消息:

(kernel) Can't unload kext com.my.driver; classes have instances:
(kernel)     Kext com.my.driver class com_my_driver has 1 instance.
Failed to unload com.my.driver - (libkern/kext) kext is in use or retained (cannot unload).

是否还有其他地方可以让我在参考检查之前的停止例程之前释放我的班级?

thanks


我最近遇到了同样的问题,然后我放弃了(在 kext stop 函数中释放我的类)。
我认为 OSObject 及其派生类不适用于此类用例。

创建和删除(释放)必须在另一个地方完成,例如:

// do new in connect(), release in disconnect().
#include <sys/kern_control.h>
...
static kern_ctl_ref g_ctl_ref;
static kern_ctl_reg g_ctl;

...
static errno_t setup() {
    g_ctl.ctl_id = 0;
    g_ctl.ctl_flags = CTL_FLAG_REG_ID_UNIT /*| CTL_FLAG_REG_SOCK_STREAM */;
    g_ctl.ctl_connect = connect_handler;
    g_ctl.ctl_send = send_handler;
    g_ctl.ctl_disconnect = disconnect_handler;
    g_ctl.ctl_getopt = getopt_handler;
    g_ctl.ctl_setopt = setopt_handler;

    strcpy(g_ctl.ctl_name, "kext_control_name");
    g_ctl.ctl_unit = 0;

    return ctl_register(&g_ctl, &g_ctl_ref);
}

static errno_t connect_handler(kern_ctl_ref ctlref, struct sockaddr_ctl *sac, void **unitinfo)
{
    gDriver = new com_my_driver;
    gDriver->init();
    // just my pattern, if your driver class has connect method..
    return gDriver->connect(ctlref, sac, unitinfo);
}

static errno_t disconnect_handler(kern_ctl_ref ctlref, unsigned int unit, void *unitinfo)
{
    // just my patter, if your class has disconnect method.
    gDriver->disconnect(ctlref, unit, unitinfo);
    gDriver->release();

    return 0;
}
...
// other handlers...
extern "C" kern_return_t com_my_driver_start(kmod_info_t * ki, void *d)
{
    setup();
}
// 

官方对内核控制的描述是:https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/NKEConceptual/control/control.html https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/NKEConceptual/control/control.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通用内核扩展无法释放 OSObject 派生类 的相关文章

随机推荐