为什么windbg无法在内核模式转储中显示我的用户模式调用堆栈?

问题描述

我用Visual C ++编写了一个程序,它使Windows崩溃。幸运的是,我有一个故障转储!

!analyze -v指出错误的进程确实是我的程序,并向我显示了内核模式调用堆栈。但是,我需要了解用户模式程序的状态才能理解它。

根据此处的其他答案(例如this one),它应该可以正常工作。

但是我无法从windbg中获取任何此类信息。所有调用堆栈仅以nt!KiSystemServicecopyEnd+0x28结尾。作为最小的示例,从标准Win32线程池调用我的一个空闲工作线程的堆栈:

nt!KiSwapContext+0x76
nt!KiSwapThread+0xbfd
nt!KiCommitThreadWait+0x144
nt!KeRemoveQueueEx+0x27e
nt!IoRemoveIoCompletion+0x99
nt!NtWaitForWorkViaWorkerFactory+0x25e
nt!KiSystemServicecopyEnd+0x28 (TrapFrame @ ffff820d`2a2dfb00)
0x00007ff8`08a1fa54

我至少希望RtlUserThreadStart在某个地方,但是看不到任何东西。

有问题的程序已在Visual C ++ 2019 for x64中使用调试信息进行编译。该程序和PDB文件仍然存在,自崩溃以来没有发生变化。崩溃时已附加了Visual Studio调试器,但是我还有一个没有调试器的调试器,这也不好。

有趣的是,如果我选择崩溃期间运行的其他进程,并且碰巧碰到了未分页的进程(例如firefox),它们的调用堆栈也将以nt!KiSystemServicecopyEnd+0x28结尾。

在崩溃期间如何恢复程序状态?

解决方法

RbMm是正确的-转储不包括任何用户地址空间,因此windbg不会显示任何内容。

使用windbg打开转储文件时,请注意输出的前几行。应该有类似Kernel Bitmap Dump File: Kernel address space is available,User address space may not be available的消息,说明一切。