좋아요, 완전히 엉망이고 좌절되었습니다. I/O Kit RAM Disk를 구현하고 있는데 친구가 kextload
을로드 한 다음 언로드하려고 시도한 후 kextunload
으로 언로드하려고 시도했음을 발견했습니다. 그 이유는 kext가 할당 된 OSObject
중 아무 것도 해제되지 않았기 때문입니다. 그러나 내 컴퓨터 (Mac OS 10.8.5 실행)와 VM (Mac OS 10.7 실행) 모두 예상대로 작동했습니다.아무 이유없이 IOService가 누출 됨
필자는 문제를 너무 좁혀 좁은 I/O Kit 드라이버로 새 Xcode 프로젝트를 만들고 내 친구의 컴퓨터에서 테스트했습니다. 자, 내 IOService
하위 클래스가 누출되었다고 주장했기 때문에 모듈을 kextunload
으로 언로드 할 수 없었습니다. 친구의 컴퓨터에서 IOService
메서드를 재정의하지 않은 다른 드라이버를 테스트하고 싶습니다. 테스트 한 버전에서는 super
에 전화하기 전에 IOLog
초를 오버라이드합니다. 그의 기계 구성에 관해 수집 한 추가 정보로이를 업데이트 할 것입니다. 여기
#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 구현을 시도했습니다. 맞습니다. 저는 제 자신의 방법을 정확히 무시했습니다. 문제가 지속됩니다. 여기 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).