我通过执行以下操作设置未处理的异常过滤器: SetUnhandledExceptionFilter(UnhandledException)
在我的UnhandledException函数中,我使用MiniDumpWriteDump编写了一个minidump:
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),hFile, MiniDumpNormal,excpInfo? & eInfo: NULL,NULL,NULL);
当我查看WinDbg中的堆栈跟踪时,我看不到多少:
0:023> kb ChildEBP RetAddr Args to Child WARNING: Stack unwind information not available. Following frames may be wrong. 15e7e7dc 08f00150 08f00a78 08f00000 08f00150 ntdll!ZwGetContextThread+0x12 15e7e7fc 777d301e 6f00016e 00000044 627e056a 0x8f00150 15e7e890 777d2ffa 777d2bf2 00000000 00650000 ntdll!RtlInterlockedFlushSList+0x889 15e7e894 777d2bf2 00000000 00650000 077e1b88 ntdll!RtlInterlockedFlushSList+0x865 15e7e8b4 772b14d1 08f00000 00000000 077e0c48 ntdll!RtlInterlockedFlushSList+0x45d 15e7e8d0 777ce023 077e1b88 08f00138 00000001 kernel32!HeapFree+0x14 15e7e8e8 777d48c6 777bfafa 777d419a ffffffff ntdll!RtlFreeHeap+0x7e 15e7e914 777e9ed7 ffffffff 15e7e938 15e7e944 ntdll!RtlImageNtHeader+0xe2 15e7e93c 777e9e49 00010000 00000000 08c70000 ntdll!RtlDestroyHeap+0x139 15e7e958 75d5458e 08f00000 00000000 08ccfe46 ntdll!RtlDestroyHeap+0xab 15e7e9c4 777ce023 104d9250 104d91f0 104d9250 KERNELBASE!HeapDestroy+0xe 00000000 00000000 00000000 00000000 00000000 ntdll!RtlFreeHeap+0x7e
MiniDumpWriteDump文档提到strack trace可能不太好,但我真的不明白我应该怎么做: http://msdn.microsoft.com/en-us/library/ms680360%28v=vs.85%29.aspx
任何帮助表示赞赏!
答案 0 :(得分:2)
您无法从当前正在执行的线程获取可靠的调用堆栈。为了从转储文件获取调用堆栈,WinDbg从转储文件中提取线程上下文记录(CONTEXT结构,它基本上是线程的所有寄存器的快照)。基于寄存器(特别是RIP和RSP)和符号,它可以遍历堆栈并提取调用堆栈。对于运行线程,无法获得一致的CONTEXT结构,因为它会更改每条指令。
您在MSDN上查看的链接提到了为当前正在执行的线程获取一致的CONTEXT的简单方法。代码如下所示:
__try
{
RaiseException(0, 0, 0, 0);
}
__except (
MyStackTraceFilter(GetExceptionInformation()->ContextRecord)))
{
// do nothing in the handler
}
这里的工作是在MyStackTraceFilter中完成的 - 你必须提供这个功能。输入参数将是您可以依赖的CONTEXT记录 - 当引发exceptin时特定时间的当前线程的快照。实际上,您可以编写代码来在MyStackTraceFilter中遍历堆栈,并获得正在运行的线程的良好调用堆栈。如果您只对调用堆栈感兴趣,这可能会为您解决。
在大多数情况下,可以从不一致的CONTEXT结构中获得“更好”的调用堆栈。如果您可以依赖RSP / esp或多或少是正确的,那么您所做的就是
答案 1 :(得分:1)
如果您从未处理的异常过滤器调用MinidumpWriteDump,那么您应该有一个有效的EXCEPTION_POINTERS来传入MINIDUMP_EXCEPTION_INFORMATION参数。如果你已经这样做了,那么minidump将包含一个异常流,它包含一个特殊的CONTEXT,它表示崩溃线程的状态。在WinDBG中加载这样的转储时,它将显示以下消息: 此转储文件存储在其中的异常例外。 存储的异常信息可以通过.ecxr。
访问您需要输入.ecxr命令来加载该上下文,以便从该点开始显示堆栈跟踪。