2012-11-23 36 views
9

我正在为音频设备驱动程序(它是软件,但模拟硬件设备)编写OSX内核扩展。无法卸载内核扩展;类有实例

在开发过程中,完全卸载现有的旧版本然后从头开始构建和安装新版本会很方便。但是,如果没有系统重启,偶尔会出现这种情况。

程序本身未运行,源文件已从/System/Library/Extensions/目录中删除。

kextstat揭示了一个实例:

$ kextstat | grep 'com.foo.driver.bar' 
219 0 0xfff123 0x5000 0x5000 com.foo.driver.bar (0.0.1) <102 5 4 3> 

(...这意味着:)

Index Refs Address Size Wired Name (Version) <Linked Against> 

因此,有0至参考文献我的司机实例,但有时kextunload会失败,抱怨现有实例:

$ sudo kextunload -b com.foo.driver.bar 
(kernel) Can't unload kext com.foo.driver.bar; classes have instances: 
(kernel)  Kext com.foo.driver.bar class FooBarDriver has 1 instance. 
(kernel)  Kext com.foo.driver.bar class com_foo_driver_bar has 1 instance. 
Failed to unload com.foo.driver.bar - (libkern/kext) kext is in use or retained (cannot unload). 

发生这种情况时, ere无法“强制”卸载kext(我知道)。

我是否正确地猜测这个单一实例仍然存在,因为运行的操作系统内核在内存中保存了一个引用?这看起来不正确,因为然后kextunload总是会失败。那么为什么kextunload只有时需要系统重启才能“完全”卸载所有驱动程序实例?

回答

10

对于IOKit kext将运行kextunload(如果没有其他kexts依赖它)会导致内核尝试terminate()该kext中I/O Kit注册表中的任何类的实例。然后它会等一会儿,检查是否有任何kext的类仍然有实例。如果没有,它将卸载kext。如果实例仍然存在,则kextunload失败(被终止的实例保持终止状态,但这意味着I/O套件匹配不会在其提供程序上重新运行)。

所以不知何故,你仍然结束了活的实例。

  • 一种可能性是您的物体拒绝terminate()。如果他们的客户不会放弃控制权,就会发生这种情况。您无法卸载驱动程序以安装文件系统顶部的磁盘。另一个示例是,不响应终止消息的用户空间客户端。

  • 否则,实例将终止,但不会被释放。由于他们似乎是你的两个主要驾驶员类别,如果你没有任何不会放弃他们声明的用户客户,我会立刻出去并建议你可能有一个循环参考。如果不是这样,你只需要寻找与release()不匹配的retain()。我提供一些关于如何跟踪这些下降in this answer的提示。

如果实例终止,都被注销,他们将不再出现在ioreg命令行工具的输出,所以这是检查的一个简单的方法,其中两例适用于这里。

+0

有帮助。谢谢! – pje