我目前正在尝试调试系统死锁,但我很难理解这一点。
Child-SP RetAddr : Args to Child : Call Site
fffff880`035cb760 fffff800`02ecef72 : 00000000`00000002 fffffa80`066e8b50 00000000`00000000 fffffa80`066a16e0 : nt!KiSwapContext+0x7a
fffff880`035cb8a0 fffff800`02ee039f : fffffa80`0b9256b0 00000000`000007ff 00000000`00000000 00000000`00000000 : nt!KiCommitThreadWait+0x1d2
fffff880`035cb930 fffff880`0312a5e4 : 00000000`00000000 fffff800`00000000 fffffa80`079a3c00 00000000`00000000 : nt!KeWaitForSingleObject+0x19
为什么 KeWaitForSingleObject 的第一个参数为 null?
除非我误解了,第一个参数不是正在等待的对象吗?
死锁仅仅是因为该线程没有等待任何东西还是这是普通行为?
此外,我看到另一个进程(services.exe)显示类似的堆栈跟踪:
1: kd> .thread fffffa800d406b50
Implicit thread is now fffffa80`0d406b50
1: kd> kv
*** Stack trace for last set context - .thread/.cxr resets it
Child-SP RetAddr : Args to Child : Call Site
fffff880`09ed4800 fffff800`02ecef72 : fffffa80`0d406b50 fffffa80`0d406b50 00000000`00000000 fffff8a0`00000000 : nt!KiSwapContext+0x7a
fffff880`09ed4940 fffff800`02ee039f : 00000000`000000b4 fffffa80`0b1df7f0 00000000`0000005e fffff800`031ae5e7 : nt!KiCommitThreadWait+0x1d2
fffff880`09ed49d0 fffff800`031d1e3e : fffffa80`0d406b00 00000000`00000006 00000000`00000001 00000000`093bf000 : nt!KeWaitForSingleObject+0x19f
fffff880`09ed4a70 fffff800`02ed87d3 : fffffa80`0d406b50 00000000`77502410 fffff880`09ed4ab8 fffffa80`0b171a50 : nt!NtWaitForSingleObject+0xde
这个线程本质上是在等待自己吗?
您正在调试 64 位进程。
记住 x64 调用约定,对此进行了解释here http://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention。前 4 个参数在寄存器中传递。之后,参数被压入堆栈。
很遗憾,kv
盲目地显示堆栈参数。事实上,它很难(有时甚至不可能)确定调用时前 4 个参数实际上是什么,因为它们可能没有存储在任何可以恢复的地方。
所以,你正在看第五个参数nt!NtWaitForSingleObject http://msdn.microsoft.com/en-us/library/windows/hardware/ff553350%28v=vs.85%29.aspx,其中一个nullptr
是一个非常典型的论点Timeout
.
幸运的是,对于我们调试类型来说,一切都没有丢失!有一个 Windbg 扩展,它会在调用函数时尽力重建参数。扩展名为CMKD http://www.codemachine.com/tool_cmkd.html。您可以将扩展 DLL 放入您的winext
文件夹并像这样调用它:
0:000> !cmkd.stack -p
Call Stack : 7 frames
## Stack-Pointer Return-Address Call-Site
00 000000a408c7fb28 00007ffda95b1148 ntdll!NtWaitForSingleObject+a
Parameter[0] = 0000000000000034
Parameter[1] = 0000000000000000
Parameter[2] = 0000000000000000
Parameter[3] = (unknown)
01 000000a408c7fb30 00007ff7e44c13f1 KERNELBASE!WaitForSingleObjectEx+98
Parameter[0] = 0000000000000034
Parameter[1] = 00000000ffffffff
Parameter[2] = 0000000000000000
Parameter[3] = 00007ff7e44cba28
02 000000a408c7fbd0 00007ff7e44c3fed ConsoleApplication2!main+41
Parameter[0] = (unknown)
Parameter[1] = (unknown)
Parameter[2] = (unknown)
Parameter[3] = (unknown)
请注意,它并不总是能成功找到论点,因为其中一些论点是(unknown)
。但是,它做得非常好,并且在调试 64 位代码时可以成为一个非常宝贵的工具。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)