好吧,我完全感到沮丧和沮丧。我正在研究I / O Kit RAM磁盘实现,并发现当我的朋友用kextload
加载它并尝试用kextunload
卸载它时,它并没有卸载。原因是没有释放kext分配的OSObject
。但是,在我的计算机(运行Mac OS 10.8.5)和VM(运行Mac OS 10.7)上,一切都按预期工作。
最终,我将问题缩小了很多,以至于我用空白的I / O Kit驱动程序创建了一个新的Xcode项目,并在我朋友的机器上对其进行了测试。瞧,我无法用kextunload
卸载模块,因为它声称我的IOService
子类正在泄漏。我想在我的朋友的机器上测试另一个驱动程序,在该驱动程序中我不重写任何IOService
方法(在我测试的版本中,在将调用传递给IOLog
之前,我重写了一些执行super
的方法)。我将使用收集到的有关其计算机配置的所有其他信息来更新此信息。
这是我的标头(BrokenDriver.h):
#include <IOKit/IOService.h>
#include <IOKit/IOLib.h>
class BrokenDriver : IOService {
OSDeclareDefaultStructors(BrokenDriver)
public:
virtual bool init(OSDictionary * dictionary = NULL);
virtual void free();
virtual bool start(IOService * provider);
virtual void stop(IOService * provider);
};
这是我的实现(BrokenDriver.cpp):
#define super IOService
OSDefineMetaClassAndStructors(BrokenDriver, IOService);
bool BrokenDriver::start(IOService * provider) {
bool success;
IOLog("%s[%p]::%s(%p)\n", getName(), this, __FUNCTION__, provider);
success = super::start(provider);
if (success) {
// Don't worry, the problem persists even if I don't call registerService()
registerService();
}
return success;
}
void BrokenDriver::stop(IOService * provider) {
IOLog("%s[%p]::%s(%p)\n", getName(), this, __FUNCTION__, provider);
super::stop(provider);
}
bool BrokenDriver::init(OSDictionary * dictionary) {
if (!super::init(dictionary)) {
return false;
}
IOLog("%s[%p]::%s(%p)\n", getName(), this, __FUNCTION__, dictionary);
return true;
}
void BrokenDriver::free(void) {
IOLog("%s[%p]::%s()\n", getName(), this, __FUNCTION__);
super::free();
}
另外,由于我知道这可能是问题的根源,因此这里是我的BrokenDriver-Info.plist的XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.aqnichol.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>KEXT</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2013 Alex Nichol. All rights reserved.</string>
<key>IOKitPersonalities</key>
<dict>
<key>BrokenDriver</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.aqnichol.BrokenDriver</string>
<key>IOClass</key>
<string>BrokenDriver</string>
<key>IOKitDebug</key>
<integer>65535</integer>
<key>IOMatchCategory</key>
<string>BrokenDriver</string>
<key>IOProbeScore</key>
<integer>1000</integer>
<key>IOProviderClass</key>
<string>IOResources</string>
<key>IOResourceMatch</key>
<string>IOKit</string>
</dict>
</dict>
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.kpi.iokit</key>
<string>9.0.0</string>
<key>com.apple.kpi.libkern</key>
<string>9.0.0</string>
<key>com.apple.kpi.mach</key>
<string>9.0.0</string>
</dict>
</dict>
</plist>
那么,判决是什么?是我朋友的仁炒的还是我的大脑?他的机器上是否有其他驱动程序试图保留我的kext甚至是遥不可及?
更新:我再次尝试使用EMPTY实现。没错,我完全覆盖了我自己的0个方法。问题仍然存在。这是来自
kextunload
的消息:(kernel) Can't unload kext com.aqnichol.BrokenDriver; classes have instances:
(kernel) Kext com.aqnichol.BrokenDriver class BrokenDriver has 1 instance.
Failed to unload com.aqnichol.BrokenDriver - (libkern/kext) kext is in use or retained (cannot unload).
最佳答案
我不知道这是否是问题,但我注意到IOService
是您班上的一个私人基地。我可以想象这可能会引发Apple运行时类型信息宏中的一些细微问题?
尝试:
class BrokenDriver : public IOService
关于c++ - IOService无缘无故泄漏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19353162/