如何从小转储提取堆栈跟踪?

我有一大堆的小型转储通过MiniDumpWriteDump在应用程序运行时logging下来。 微型转储器是在一台机器上创build的,它的操作系统版本与我的开发机器不同。

现在我正试图编写一个程序来使用dbghelp.dll从小型转储中提取堆栈跟踪。 我走MINIDUMP_MODULE_LIST并调用SymLoadModule64,但是这不能从公共符号服务器下载pdbs(kernel32等)。 如果我将“C:\ Windows \ System32”添加到符号path中,它会finddll并下载符号,但是当然它们不匹配来自minidump的dll,所以结果是无用的。

那么如何告诉dbghelp.dll下载并使用正确的pdbs?

[编辑]

我忘了声明SymLoadModule64只接收一个文件名,没有版本/校验和信息,所以很显然,单独使用SymLoadModule64,dbghelp无法确定要下载哪个pdb。

该信息实际上在MINIDUMP_MODULE_LIST中可用,但我不知道如何将其传回给dbghelp API。

有SymLoadModuleEx需要额外的参数,但我不知道如果这是我需要什么,或者我应该传递额外的参数。

[编辑]

到目前为止没有运气,但我注意到在debuggingSDK中也有dbgeng.dll和dbghelp.dll一起分发。 MSDN看起来相当有据可查,并说这是一个windbg使用的引擎。 也许我可以使用它来提取堆栈跟踪。

如果有人能指点我一些使用dbgeng.dll来处理小型转储的介绍,这可能也会有所帮助,因为MSDN只logging单个组件,而不是它们如何一起工作。

以防其他人想要自动从转储中提取堆栈跟踪,这是我最终做的:

就像我在更新中提到的,可以使用dbgeng.dll而不是dbghelp.dll,这似乎与WinDbg使用的引擎相同。 经过一些试验和错误,这里是如何获得与WinDbg相同的符号加载机制的良好的堆栈跟踪。

  • 调用DebugCreate来获取调试引擎的一个实例
  • 查询IDebugClient4,IDebugControl4,IDebugSymbols3
  • 使用IDebugSymbols3.SetSymbolOptions来配置如何加载符号(请参阅WinDbg选项的MSDN )
  • 使用IDebugSymbols3.SetSymbolPath来设置符号路径,就像你在WinDbg中做的那样
  • 使用IDebugClient4.OpenDumpFileWide打开转储
  • 使用IDebugControl4.WaitForEvent等待转储加载
  • 使用IDebugSymbols3.SetScopeFromStoredEvent来选择存储在转储中的异常
  • 使用IDebugControl4.GetStackTrace来获取最后几个堆栈帧
  • 使用IDebugClient4.SetOutputCallbacks注册接收解码的堆栈跟踪的侦听器
  • 使用IDebugControl4.OutputStackTrace处理堆栈帧
  • 使用IDebugClient4.SetOutputCallbacks注销回调
  • 释放接口

对WaitForEvent的调用似乎很重要,因为没有它,以下调用将无法提取堆栈跟踪。

也似乎有一些内存泄漏在那里,不能告诉是否我没有正确清理或dbgeng.dll内部的东西,但我可以重新启动过程每20个转储左右,所以我没有调查更多。

一个简单的自动分析多个小型转储文件的方法是使用John Robbins在他的文章“用WinDBG和PowerShell自动分析Minidump文件中的吨” (您可以在GitHub上获取代码 )编写的脚本。

如果默认设置不够,这很容易调整,以使其执行任何WinDbg命令。