windows - 在 windbg 中进行内核调试时无法获得完整的用户模式堆栈跟踪

标签 windows debugging windbg stack-trace symbols

我在 Windows 10 主机上有一台虚拟 Windows 7 x64 机器,我使用 windbg 10.0.10586.567 对它进行内核调试。我在上面运行我自己的应用程序,我有完整的源代码和私有(private)符号。每当我中断并请求应用程序线程的堆栈跟踪时,当我的应用程序的一个二进制文件被“命中”时,回溯总是停止。

例如,如果我闯入,切换到进程,并使用 !thread [thread address] 1f 请求堆栈跟踪,我会得到类似这样的结果(注意“早期”零返回地址在最后一行):

fffff880`0534e870 fffff800`026d6992 nt!KiSwapContext+0x7a
fffff880`0534e9b0 fffff800`026d81a2 nt!KiCommitThreadWait+0x1d2
fffff880`0534ea40 fffff800`029c7a2e nt!KeDelayExecutionThread+0x186
fffff880`0534eab0 fffff800`026d08d3 nt!NtDelayExecution+0x59
fffff880`0534eae0 00000000`76e7165a nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ fffff880`0534eae0)
00000000`00276708 000007fe`fcf91203 ntdll!NtDelayExecution+0xa
00000000`00276710 00000001`410e7dd9 KERNELBASE!SleepEx+0xab
00000000`002767b0 00000000`00000000 MyApp!MainMessageLoop+0x4b1 [d:\whatever\path\myapplication.cpp @ 3024]

这看起来与您在调试 x64 进程的用户模式转储(缺少展开数据)时丢失二进制文件非常相似,除了在那种情况下堆栈跟踪通常不会“突然”停止,而是它在那个时候误入歧途,并显示虚假值。

一些额外的信息/我尝试过的事情:

  • 我设置了正确的符号路径(Microsoft 符号服务器和主机上具有匹配 PDB 的本地文件夹,即使仅堆栈跟踪不需要后者)
  • 我设置了一个二进制路径 (.exepath),其中包含主机上匹配的二进制文件(我对此非常确定;将二进制文件直接从 guest 复制到主机)
  • 如果我在应用程序的一个导出 DLL 函数中放置一个断点,那么当调试器进入时,我会得到一个单行堆栈跟踪,如下所示:0000000000274b40 0000000000000000 MyAppDLL!SomeExportedFunction+0x32 [d:\whatever\path\myapplicationDLL.cpp @232]
  • 我几乎尝试了所有命令组合来获取堆栈跟踪信息(.process/i.process/r/p!process -1 7, .reloads, .reload/users, .reload/f MyApp.exe, !thread [地址] 1f 等)没有成功
  • 也尝试使用旧版本的 windbg (6.11.0001.404),结果相同
  • 还尝试在 Windows 8.1 上以访客身份使用完全相同的二进制文件,结果相同
  • !sym noisy 输出(省略不相关的行):

    0: kd>.process/i [地址] 0:kd>g 0: kd>.reload/用户 0: kd> !process -1 2 0: kd> !thread [地址] 1f [...] DBGHELP: d:\symbolcache\MyApp.pdb\76931C5A6C284779AD2F916CA324617E1\MyApp.pdb 已缓存 DBGHELP:MyApp - 私有(private)符号和线条 [...]

  • lmvm MyApp 输出:

    [...] 加载的符号图像文件:MyApp.exe 图片路径:C:\MyApp\MyApp.exe [...]

有什么想法吗?

最佳答案

我不小心发现了一个解决这个问题的链接器开关:/DEBUGTYPEPDATA 参数。如果您使用此开关链接您的二进制文件,展开信息将被复制到您的 PDB 中。

我使用 /DEBUGTYPE:CV,PDATA 重新编译/重新链接了有问题的应用程序(/DEBUGTYPE:CV 是默认值,如果 /DEBUG已指定,请参阅 documentation ),现在一切正常,我总是获得完整的调用堆栈。

其中一个奇怪的方面:windbg 愉快地使用在 PDB 中找到的展开数据,但忽略了映射二进制文件中的相同数据(都在主机上)。

关于windows - 在 windbg 中进行内核调试时无法获得完整的用户模式堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36583442/

相关文章:

.net - WinDbg 地址汇总

windbg - 在 WinDbg 中查看根对象

windows - 为什么 Curl Powershell Windows 10 比命令提示符慢?

windows - Ansible win_shell 临时语法

c - 我的分数计算变量的值异常增加

C++ - Eclipse 行为在调试和运行时是不同的

c++ - 用任务管理器杀死时如何防止内存泄漏

C++:控制台窗口有奇怪的边框..?

ios - XCODE 8.2 错误地检测到锁定的设备

c# - Windbg 和查看 AppDomain 内容