4

在我的应用程序中,每当我的应用程序崩溃时,我都会使用 MiniDumpWriteDump 函数(请参阅 dbghelp.dll)来编写崩溃转储文件。

我还使用符号服务器来存储我所有的可执行文件和 pdb 文件,这样每当客户向我发送故障转储文件时,调试器就会自动获取正确版本的可执行文件和调试信息。

我还将 Windows DLL(ntdll.dll、kernel32.dll、...)及其调试信息存储在符号服务器中(使用 SymChk)。调试信息是从 Microsoft 的公共符号服务器获取的。

大多数情况下,这很完美,除非:

  • 客户在其中一个 Windows DLL 中崩溃
  • 并且客户使用我没有放入符号服务器的 DLL

这是因为在 Symbol Server 中存储每个 Windows DLL 的每个风格是完全不可撤销的(尤其是每周的补丁)。

因此,如果客户崩溃了,比如说 NTDLL.DLL 的 5.2.123.456 版本,而我没有将这个确切版本的 DLL 放在我的符号服务器中,那么我就被卡住了。甚至微软的公共符号服务器也无济于事,因为它只提供调试信息,而不是 DLL 本身。

我目前的解决方案是向客户索要他的 DLL,但这并不总是那么容易。因此,我正在寻找更好的解决方案。

有没有办法让调试器显示正确的调用堆栈,或者加载特定 DLL 的调试信息,即使您没有 DLL 的确切版本?

或者,有没有办法获得所有(或重要的)Windows DLL(来自 Microsoft)的所有版本?

编辑:

与此同时,我找到了一个非常简单的方法来解决这个问题。使用实用程序 ModuleRescue(请参阅http://www.debuginfo.com/tools/modulerescue.html),您可以从 minidump 文件生成虚拟 DLL。有了这些虚拟 DLL,调试器就满足了,并正确地开始从 Microsoft 服务器加载调试符号。

4

4 回答 4

2

可以放宽WinDbg的符号解析;请参阅我对类似问题的回答另一方面,我在这里提出的解决方案依赖于 DLL相同的事实,除了具有不同的 GUID 来标识它们的调试符号。不同版本的 DLL 可能会有不同的二进制文件,因此即使您可以加载这些符号,它们也可能不会正确匹配。

于 2010-03-06T08:14:15.157 回答
1

我很确定微软的符号服务器也提供了二进制文件。我在我的商店里寻找,我看到了大量的 Microsoft .dll 文件。我将 _NT_SYMBOL_PATH 定义为

SRV*F:\Symbols\Microsoft*http://msdl.microsoft.com/download/symbols

这样,它会先搜索我的本地商店,然后再尝试从 Microsoft 的公共服务器上复制它们。

于 2010-02-26T20:30:05.837 回答
1

您的符号路径中可以有多个符号服务器。因此,只需将符号路径设置为指向您自己的服务器以用于您自己的私有模块,并指向公共 MS 服务器以用于 OS 模块,请参阅符号路径

通过使用以下初始设置,可以轻松地将其与 Microsoft 公共符号存储组合:

_NT_SYMBOL_PATH=srv*c:\mysymbols*http://msdl.microsoft.com/download/symbols;cache*c:\mysymbols

Microsoft 公共符号存储记录为http://msdl.microsoft.com/download/symbols

于 2010-03-05T23:18:27.337 回答
0

? 哪个部分不工作?

确切地说,我从来没有遇到过你的情况,但我希望调试器能够为你提供代码中调用堆栈的正确部分,直到调用暗 dll。当然,从那里到实际的崩溃符号都将不可用,但是您看不到正在调用哪个 NTDLL API 以及将哪些参数传递给该调用?

您没有说您使用哪个工具进行小型转储调试:WinDBG 或 VS。

于 2010-03-04T21:25:02.237 回答