I'm writing an OSX kernel extension for an audio device driver (it's software, but emulates a hardware device).
During development, it'd be convenient to completely uninstall existing old versions and then build and install the new version from scratch. However, this occasionally seems to not be possible without a system restart.
The program itself is not running and the source files have been deleted from the /System/Library/Extensions/
dir.
But kextstat
reveals a single instance:
$ kextstat | grep 'com.foo.driver.bar'
219 0 0xfff123 0x5000 0x5000 com.foo.driver.bar (0.0.1) <102 5 4 3>
(...meaning:)
Index Refs Address Size Wired Name (Version) <Linked Against>
So there are 0 Refs to my driver instance, but kextunload
will sometimes fail, complaining of existing instances:
$ 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).
When this happens, there's no way to "force" unload the kext (that I know of).
Am I right in guessing that this single instance still exists because of a reference held in memory by the running OS kernel? That doesn't seem right, because then kextunload
would always fail. So why does kextunload
only sometimes require a system restart to "fully" unload all driver instances?