我在基于iokit的驱动程序中使用了一些全局变量,即主类实例之外的变量。但是,这会在驱动程序启动时引起一些意外的恐慌,原因是使用了未初始化的全局变量,或者试图在拆卸时双倍释放全局变量。
在iokit驱动程序生命周期中,全局变量的生命周期是什么?如果我在声明时设置一个全局变量,
例如,如果我有lck_grp_t * my_lock_grp
类型的全局变量.
::start
方法时进行设置?(my_lock_grp = lck_grp_alloc_init("my-locks", my_lock_grp_attr);
)::free
方法上释放全局变量时,我是否可以假设它仍然有效?(lck_grp_free(my_lock_grp)
)发布于 2018-08-06 15:43:58
它的生存期肯定与kext的生存期相同。类上的IOKit init/ start / stop /free函数将发生在kext启动函数和停止函数之间(您可能没有显式的kext启动和停止函数),全局构造函数在kext启动函数之前运行,同样,全局析构函数在kext停止函数之后运行。全局/静态变量的内存分配/去分配是由动态内核链接器在加载和卸载kext代码的同时完成的。
我能想到三件事:
IOService
、start()
和free()
函数不匹配--即使从未调用start()
,也会调用free()
。例如,如果您有一个probe()
函数,并且这个函数被调用并返回nullptr
,那么start()
永远不会被调用,但是free()
肯定会调用,它试图释放一个从未分配过的锁组。类似地,如果一个init()
函数返回false - start()
将永远不会运行,但是free()
将运行。与free()
等价的是成员函数的init()
族,因此在free()
中只无条件地销毁(没有nullptr检查)在所有可能的init…
函数中无条件创建的内容。start()
可以在不同实例上被多次调用,因此如果您总是在start()
中运行my_lock_grp = lck_grp_alloc_init()
,并且创建了2个实例,my_lock_grp
只会记住最后一个实例,因此如果您的类的两个实例都被释放,那么您将尝试释放一个锁组两次,而另一个则完全不释放。这显然是个坏消息。对于初始化/破坏真正的全局状态,我建议使用kext开始和停止函数或全局构造函数/析构函数。如果这些听起来都不像问题所在,我建议张贴受影响的代码和恐慌日志,如果我们有一些硬数据,也许我们可以更好地理解这个问题。
https://stackoverflow.com/questions/51708837
复制相似问题