Debugging 在macOS 10.14中,Kext在线程上下文切换中触发死机。

Debugging 在macOS 10.14中,Kext在线程上下文切换中触发死机。,debugging,kernel,kernel-extension,xnu,macos-mojave,Debugging,Kernel,Kernel Extension,Xnu,Macos Mojave,最近,我在10.14上测试了我的kext,它似乎平稳运行了一段时间。但经过几分钟的随机时间后,会产生以下恐慌: thread_invoke: preemption_level -1, possible cause: unlocking an unlocked mutex or spinlock" 这一点我已经运行了我的代码好几次,并注意到恐慌可能是由调用psynch_cvwait sys调用时的用户空间守护程序触发的,或者是在调用msleep函数后触发上下文切换时直接从内核扩展触发的 以下是内

最近,我在10.14上测试了我的kext,它似乎平稳运行了一段时间。但经过几分钟的随机时间后,会产生以下恐慌:

thread_invoke: preemption_level -1, possible cause: unlocking an
unlocked mutex or spinlock"
这一点我已经运行了我的代码好几次,并注意到恐慌可能是由调用psynch_cvwait sys调用时的用户空间守护程序触发的,或者是在调用msleep函数后触发上下文切换时直接从内核扩展触发的

以下是内核的跟踪:

frame #4: 0xffffff800afe24a3 kernel`panic(str=<unavailable>) at debug.c:620 [opt]
frame #5: 0xffffff800affef06 kernel`thread_invoke(self=0xffffff801b7a4030, thread=0xffffff801afe4540, reason=0) at sched_prim.c:2261 [opt]
frame #6: 0xffffff800affdaff kernel`thread_block_reason(continuation=<unavailable>, parameter=<unavailable>, reason=<unavailable>) at sched_prim.c:3088 [opt]
frame #7: 0xffffff800b4fcfe1 kernel`_sleep [inlined] thread_block(continuation=<unavailable>) at sched_prim.c:3104 [opt]
frame #8: 0xffffff800b4fcfd6 kernel`_sleep(chan=<unavailable>, pri=0, wmsg=<unavailable>, abstime=1299691844730, continuation=0x0000000000000000, mtx=0x0000000000000000) at kern_synch.c:251 [opt]
frame #9: 0xffffff800b4fd352 kernel`msleep(chan=0x01000004001ddd89, mtx=0x0000000000000000, pri=0, wmsg="", ts=<unavailable>) at kern_synch.c:346 [opt]
接下来是从用户空间守护进程sys调用触发的堆栈跟踪:

frame #4: 0xffffff800afe24a3 kernel`panic(str=<unavailable>) at debug.c:620 [opt]
frame #5: 0xffffff800affef06 kernel`thread_invoke(self=0xffffff80176f5a50, thread=0xffffff8019a5de60, reason=0) at sched_prim.c:2261 [opt]
frame #6: 0xffffff800affdaff kernel`thread_block_reason(continuation=<unavailable>, parameter=<unavailable>, reason=<unavailable>) at sched_prim.c:3088 [opt]
frame #7: 0xffffff7f8cbf5080
frame #8: 0xffffff7f8cbf6dcf
frame #9: 0xffffff800b499c3c kernel`psynch_cvwait(p=<unavailable>, uap=<unavailable>, retval=<unavailable>) at pthread_shims.c:397 [opt]
其中缺失的帧属于扩展com.apple.kec.pthread1.0[C69B97C1-505D-3629-9D64-7B7BC6D780A8]@0xffffff7f8cbf3000->0xffffff7f8cbfafff

起初我认为这可能是由随机内存损坏引起的,但看起来在我所有的复制之后,除了我刚才提到的2之外,没有其他实体触发了恐慌

如果我查看紧急消息,它连接到每个处理器的%gs寄存器中的值,其中保留了抢占级别。然而,在lldb中,我没有任何权限访问这个寄存器,我怀疑它是否映射到我的驱动程序内存

因此,我留下的是评论我的驱动程序的一些部分,看看问题是否仍然存在。。也许你们中有谁对如何解决这个问题有更多的见解

谢谢

我相信下面的lldb命令应该与所有其他命令一起打印gs寄存器:

register read

我以前只在处理自旋锁时遇到过这种恐慌,因为它们禁用了抢占。如果您的kext不使用自旋锁,并且没有通过内联汇编显式禁用抢占,这可能是macOS中的一个错误,我会尽快向Apple报告。

我实际上在代码中使用自旋锁执行非常基本的任务。但是我假设如果spinlock触发负抢占级别,我应该在showallstacks中正好看到一个线程,其回溯包含spinlock函数。但是,到目前为止,我还没有跟踪这样的线程。另外,关于%gs寄存器,我可以使用register read读取它,它显示gs=0x000000009da40000。从源代码看,gs寄存器似乎用作cpu_data_t区域的基址,每个cpu使用不同的地址作为基址。。。但是,我无法使用内存读取从lldb读取它,错误为4