Macos 导致睡眠-唤醒故障的驱动程序

Macos 导致睡眠-唤醒故障的驱动程序,macos,debugging,kernel,iokit,xnu,Macos,Debugging,Kernel,Iokit,Xnu,作为一项安全研究,我正在编写一个定制的IOKit驱动程序。驱动程序通过电源板向所依赖的驱动程序注册自身。(USB服务)。正在调用setPowerState功能,并且驱动程序自动正确关闭 问题是,它会随机导致睡眠-唤醒故障问题,机器会自动重启。实际上,重置发生在机器进入睡眠后的唤醒过程中(显然是尝试休眠) 问题是,我如何调试或解决它?我正在使用firewire内核调试来查看正在发生的事情,但是调试器和断点导致了睡眠计时机制的延迟,一切都是一团糟 关于这个问题,互联网上的数据非常薄弱,但充满了关于O

作为一项安全研究,我正在编写一个定制的IOKit驱动程序。驱动程序通过电源板向所依赖的驱动程序注册自身。(USB服务)。正在调用
setPowerState
功能,并且驱动程序自动正确关闭

问题是,它会随机导致睡眠-唤醒故障问题,机器会自动重启。实际上,重置发生在机器进入睡眠后的唤醒过程中(显然是尝试休眠)

问题是,我如何调试或解决它?我正在使用firewire内核调试来查看正在发生的事情,但是调试器和断点导致了睡眠计时机制的延迟,一切都是一团糟

关于这个问题,互联网上的数据非常薄弱,但充满了关于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;
}

IOService
的未发布引用导致睡眠序列中出现死锁

我们使用以下代码获取
IOService
指针

mach_timespec time;
time.tv_sec = 0;
time.tv_nsec = 1000;
IOService* service = IOService::waitForService(IOService::serviceMatching(class_name, NULL), &time);
return service; 
IOService::serviceMatching
IOService::waitForService
都增加了引用计数器

更改为以下示例代码:

OSDictionary *dict = IOService::serviceMatching(class_name, NULL);

if (dict == NULL)
    return NULL;

IOService* service = IOService::waitForMatchingService(dict, 1000);

dict->release();

return service;

IOService::waitForMatchingService
不会增加引用计数器,我们会释放
OSDictionary
指针

你确定机器没有内核恐慌吗?此外,可能SMC的编程方式是,尾迹中的长延迟使其认为机器冻结(可能是由于驱动器中的无限循环或其他原因而冻结)。您能否将问题减少到超最小kext?这似乎不是我们可以帮助您在没有任何代码的情况下进行调试的事情。