通用内核扩展无法释放OSObject派生类 [英] Generic kernel Extension Cannot release OSObject derived class
问题描述
我有通用内核扩展,它在C ++示例中为开始和结束例程实现,而所有其他逻辑都存储在从OSObject
继承的专用类中.
I've got Generic Kernel Extension which is implemented in C++ example for the start and end routines, whereas all the other logic is stored within a dedicated class inherit from OSObject
.
它在模块启动例程时创建该类,并在停止例程中释放该类,如下面的代码所示:
it creates the class upon module start routine, and release it upon stop routine as can be shown in the code below :
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;
}
但是,当尝试卸载服务时,由于仍在引用该类,因此它无法到达停止例程(我以为它到达了释放该类的停止例程).这是确切的日志消息:
However, when trying to unload the service, It cannot reach the stop routine since the class is still being referenced (I assumed it reach to the stop routine where I release this class). Here's the exact log message:
(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).
在进行参考检查之前,我还可以在停止程序之前放开课程吗?
Is there any other even where I can release my class prior to the stop routine before the reference inspection ?
谢谢
推荐答案
我最近遇到了同样的问题,然后我放弃了(在kext stop函数中释放我的类).
我认为OSObject及其派生类不适用于这种用例.
I recently encountered just same problem, then I gave up(to release my class in kext stop function).
The OSObject and its derived classes are not for such use case I think.
创建和删除(发布)必须在另一个地方进行,例如:
The creation and deletion(release) has to be done another place for example:
// 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();
}
//
The official description of kernel controls are: https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/NKEConceptual/control/control.html
这篇关于通用内核扩展无法释放OSObject派生类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!