我正在努力学习WinDbg。在简单的程序中,我在Critical Section
无限期等待。我的程序挂起,我使用任务管理器转储程序。
现在,每当我使用kc
或k
命令进行堆栈跟踪时,它就会给我以下堆栈跟踪。
wow64cpu!CpupSyscallStub
wow64cpu!Thunk0ArgReloadState
wow64!RunCpuSimulation
wow64!Wow64LdrpInitialize
ntdll!LdrpInitializeProcess
ntdll!_LdrpInitialize
ntdll!LdrInitializeThunk
现在,为什么它没有显示我的实际代码的堆栈跟踪。我怎么理解我的程序到底在哪里?
答案 0 :(得分:3)
关于捕获32位转储的先前答案是可以的。但是,如果您没有机会创建另一个转储(例如,如果问题难以重现),请尝试WOW64扩展:
0:000> k
Child-SP RetAddr Call Site
00000000`0008e2e8 00000000`7449aeac wow64win!NtUserGetMessage+0xa
...
00000000`0008f7d0 00000000`00000000 ntdll!LdrInitializeThunk+0xe
0:000> .load wow64exts
0:000> !sw
Switched to 32bit mode
0:000:x86> k
ChildEBP RetAddr
00141568 755f790d user32!NtUserGetMessage+0x15
00141584 004aa378 user32!GetMessageW+0x33
00141634 00400000 notepad__+0xaa378
...
注意输入提示如何更改为0:000:x86>
并且正确显示了callstack。
!sw
向前和向后切换时,您还可以使用.effmach x86
和.effmach amd64
更具体。
答案 1 :(得分:2)
请使用ProcessExplorer来捕获dmp。从版本15.13开始,它生成dumps with the correct bitness。
它还会创建与目标位数匹配的转储文件 过程
现在打开Windbg.exe中符合位数的转储并运行!analyze -v -hang
-hang
告诉命令执行挂起分析。这应该会向您展示代码的一部分。
答案 2 :(得分:1)
您的程序是一个在64位Windows上运行的32位应用程序。您应该使用32位WinDbg来调试它。在典型的Windows SDK安装中,它将位于C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x86\windbg.exe
。
答案 3 :(得分:1)
欢迎来到Windbg世界。与具有出色GUI的现代调试器不同,Windbg更基于命令行,因此可能具有更陡峭的学习曲线。但是一旦掌握了它 - 它的辉煌!
在你的问题上:
列文已经暗示了一下。我会详细说明一下。
您可能已经在示例应用中运行了多个线程。
~
将列出所有主题。
~* k
将转储所有线程的堆栈。
接下来,您可以使用
移动到您希望使用的线程 ~ <thread ID>s
This是在Windbg中开始使用不同命令的绝佳资源。
答案 4 :(得分:0)
使用!analyze -hang
或!locks
或¬cs -s -o -l
查看您是否遇到死锁情况。后者是我喜欢的。
至于为什么当你打开转储它显示一个不相关的线程调用堆栈时,你的程序可能在创建转储时处于任何中间位置,它并不总是感兴趣的线程,这就是为什么你需要做一些分析
从!locks
的输出中,它将转储所有被锁定的关键部分,你要查找的是2个threadId正在等待彼此的资源,然后使用~~[TID]s
kb切换到这些线程转储调用堆栈然后查找ntdll!RtlEnterCriticalSectionfunction
,第一个参数将是它正在等待的关键部分的地址,你应该发现你的2个线程正在等待彼此的关键部分。然后,您需要转到代码并了解锁定机制是否存在缺陷。