它的寿命肯定和kext的寿命一样。类上的IOKit init/start/stop/free函数将发生在kext start函数和stop函数之间(您可能没有显式的kext start&stop函数),全局构造函数在kext start函数之前运行,全局析构函数在kext stop函数之后运行。全局/静态变量的内存分配/释放由动态内核链接器在加载和卸载kext代码的同时完成。
我能想到三件事:
-
这个
IOService
start()
和
free()
函数不匹配-
自由()
被称为即使
开始()
从来没人打过电话。例如,如果你有一个
probe()
函数,然后调用并返回
nullptr
,然后
开始()
从来没打过电话,但是
自由()
肯定会,它试图释放一个从未分配过的锁组。同样,如果
init()
函数返回false-
开始()
不会跑,但是
自由()
威尔。相当于
自由()
是
初始化()
成员函数的系列,因此仅无条件销毁(无null ptr签入)
自由()
一切可能的无条件创造
initâ¦
功能。
-
开始()
可以在不同实例上调用任意次数,因此如果始终运行
my_lock_grp = lck_grp_alloc_init()
在里面
开始()
创建了两个实例,
my_lock_grp
只记住最后一个,所以如果您的类的两个实例都被释放,那么您将尝试释放一个锁组两次,而另一个则完全不被释放。这显然是个坏消息。对于初始化/销毁真正的全局状态,我建议使用kext start和stop函数或全局构造函数/析构函数。
-
否则,我怀疑您可能会遇到这样的情况:正在运行的内核的其他部分在kext已经卸载的点上仍然有一个悬挂的引用,例如,如果您创建了一个新的内核线程,而该线程仍在运行,或者如果您还没有注销所有已注册的回调,或者如果回调已注销,但不能保证已完成所有调用。(考斯的听众因后一种情况而臭名昭著)
如果这些听起来都不是问题所在,我建议发布受影响的代码和恐慌日志,如果我们有一些硬数据,也许我们可以更清楚地了解问题。