【发布时间】:2015-04-13 16:54:03
【问题描述】:
作为一项安全研究,我正在编写一个自定义 IOKit 驱动程序。驱动程序通过电源层将自身注册到它所依赖的驱动程序。 (USB 服务)。正在调用setPowerState 函数并且驱动程序正确地自行关闭。
问题是,它会随机导致睡眠唤醒失败问题,并且机器会自行重启。实际上重置发生在机器进入睡眠后唤醒期间(显然试图休眠)
问题是,我该如何调试或解决它?我正在使用火线内核调试来查看发生了什么,但是调试器和断点导致睡眠计时机制出现延迟,一切都一团糟。
互联网上的数据在这个问题上相当薄弱,但充满了关于 OSX 机器在干净的机器中导致睡眠唤醒失败的抱怨。
我正在各种机器和内核版本上对其进行测试,并且它是持久的。
任何线索都会有所帮助。
编辑:附加代码
enum
{
kOffPowerState, kStandbyPowerState, kIdlePowertState, kOnPowerState, kNumPowerStates
};
static IOPMPowerState gPowerStates[kNumPowerStates] =
{
//kOffPowerState
{kIOPMPowerStateVersion1, 0,0,0,0,0,0,0,0,0,0,0},
//kStandbyPowerState
{kIOPMPowerStateVersion1, kIOPMPowerOn, kIOPMPowerOn, kIOPMPowerOn, 0,0,0,0,0,0,0,0},
//kIdlePowerState
{kIOPMPowerStateVersion1, kIOPMPowerOn, kIOPMPowerOn, kIOPMPowerOn, 0,0,0,0,0,0,0,0},
//kOnPowerState
{kIOPMPowerStateVersion1, kIOPMPowerOn | kIOPMDeviceUsable, kIOPMPowerOn, kIOPMPowerOn, 0,0,0,0,0,0,0,0}
};
bool driver::start(IOService* provider)
{
IOLog("driver::start\n");
if (IOService::start(provider) == false)
return false;
PMinit();
provider->joinPMtree(this);
makeUsable();
changePowerStateTo(0);
registerPowerDriver(this, gPowerStates, kNumPowerStates);
registerService();
return true;
}
IOReturn driver::setPowerState (unsigned long whichState, IOService * whatDevice)
{
IOLog("driver::setPowerState (%lu)\n", whichState);
if (whichState == 0)
IOLog("driver: shutdown (%lu)\n", whichState);
return kIOPMAckImplied;
}
【问题讨论】:
-
你确定机器没有内核恐慌吗?也可能 SMC 的编程方式是,在唤醒过程中的长时间延迟使其认为机器已冻结(并且可能由于您的驱动程序中的无限循环或其他原因而被冻结)。
-
你能把问题减少到一个超级最小的 kext 吗?这似乎不是我们可以在没有任何代码的情况下帮助您调试的事情。
标签: macos debugging kernel iokit xnu