多年来,我在许多游戏项目中都使用了minidumps,在这些项目中,它们似乎有约50%的机会具有有效的调用堆栈。那么,我该怎么办才能使它们具有更好的调用堆栈呢?
我尝试将最新的dbghelp.dll放入exe目录中,这似乎对一些情况有所帮助。
使用Visual Studio 2008或2010是否更好?(我还在使用VS 2005)
我使用的代码看起来像这个示例。
您可以做的一件事是使用除Visual Studio之外的调试器,特别是使用WinDbg或其他使用dbgeng.dll(而不是Visual Studio使用的“Visual Studio Debugger”调试引擎)的工具,以提高在转储中找到的调用堆栈的准确性。
从我们的经验来看,WinDbg能够从相同的转储中生成良好的调用堆栈,并且可靠度达到100%,而在这些情况下,Visual Studio会产生无法使用或极其不准确的调用堆栈。据我所知,在未处理的异常是崩溃源的情况下,WinDbg会自动执行重建/恢复异常调用堆栈的棘手过程,但Visual Studio则不行(或无法?)。这两个调试器使用不同的启发式算法解释堆栈
WinDbg可能一开始会让人望而却步,因此这是我关于如何使其更容易甚至避免直接使用它的快速指南。
一个普通人提取良好调用堆栈的指南
这些选项按从“最快/最简单”到“最慢/最难解释”的顺序排列。
这是一个鲜为人知的工具,自动化了许多常见问题的分析,足够简单易懂,即使是非程序员或客户也可以使用。它快速且几乎无误,已成为我快速分析传入崩溃转储的“首选”工具。
几秒钟到几分钟后,它将输出一个漂亮的.mhtml文件,其中包含有关问题的分析、所有相关线程的信息、完整的调用堆栈等。所有内容都带有超链接,易于使用。
DebugDiag甚至自动化了一些在WinDbg中可能很复杂但痛苦的分析(比如追踪应用程序中的350个线程中哪一个负责死锁)。
注意:由于安全原因,Chrome不会下载或打开.mhtml文件,因此您必须在Internet Explorer或Microsoft Edge中打开才能使用。这很麻烦,我已向DebugDiag团队(dbgdiag@microsoft.com)提出了更改格式为纯HTML的请求
!analyze -v
并按Enter键。稍等片刻,WinDbg将输出崩溃调用堆栈,以及其对问题来源的估计。如果您正在分析死锁,则可以尝试!analyze -v -hang
,WinDbg通常会显示涉及的依赖链。
此时您可能已经获得所需的所有信息!但是,如果您想在Visual Studio调试器中检查进程状态,可以执行以下其他步骤:
如果您需要堆栈转储,请关闭帧指针优化。帧指针用于显式定义堆栈帧。没有帧指针,调试器必须推断每个帧的位置。
!vc7fpo - toggles some of the windbg heuristics.
!stackdbg d, 7, f - turns on windbg stack walk
k1 - walks one level of the stack, spitting diagnostics as controlled by !stackdbg
dds esp - dumps the raw contents of the stack, doing a symbol lookup on each pointer
我不使用小型转储,而是通过“手动”将堆栈转储到日志文件中(请参见www.ddj.com/cpp/185300443和How to Log Stack Frames with Windows x64)。
我遇到了与您类似的行为:有时存在有效的调用堆栈,有时则没有。在少数情况下,堆栈可能真的已经损坏了。在所有情况中,安装的异常处理程序都没有被调用!我猜这可能是Windows结构化异常处理的问题。