PDB无法显示发布版本崩溃的确切行号,但在二进制调试版本的情况下显示精确行号

PDB Fails to show the exact line number for release version crash but shows precise line number in case of debug version of binary

本文关键字:版本 显示 二进制 情况下 调试 崩溃 布版本 PDB      更新时间:2023-10-16

我在Windows上使用/DEBUG选项构建了应用程序,这样我就可以分析应用程序崩溃时生成的崩溃转储。使用WinDBG(!analyze-v),我只能看到一些不精确的堆栈跟踪。然而,当我创建调试构建并且我的应用程序崩溃时,WinDBG告诉我崩溃发生的确切行号。

我提前对我的问题进行了一种抽象的总结,对此我深表歉意,但我正在寻找不同的观点,以及世界各地的开发人员如何发布他们的C++应用程序的构建,以便可以分析应用程序中任何崩溃的转储,以获得崩溃的精确行号

我正在寻找关于这一点的不同观点,以及世界确实发布了他们的C++应用程序的内部版本,以便转储可以对应用程序中的任何崩溃进行相应的分析,以获得精确的崩溃的行号

欢迎来到死后调试的世界。您的问题是优化版本构建应用程序的典型问题,因此,您需要利用所有可用的工具。大多数情况下,实际的行号将不可用。我有一些建议。

不要仅仅依赖WinDbg。我使用Windbg和Visual Studio来分析崩溃转储。我发现,通过使用两者,我可以更全面地了解潜在的问题。您可能还想研究使用DebugDiag作为分析崩溃转储的附加工具。

为了帮助确定崩溃原因,我在报告中添加了一个额外的文件。除了转储文件外,我还收集了一个日志文件,该文件详细说明了用户在崩溃时所做的事情的上下文。它并不完美,但它有助于了解执行了哪些类型的函数以及如何输入这些函数。报告可以自定义为包含任何类型的有用信息。

最后,您可以安装自己的未处理异常过滤器,以收集任何有助于解决崩溃原因的其他信息。

构建正确的符号

有几种类型的符号(按可用信息排序):

  • 没有符号
  • 导出符号
  • 公共标志
  • 专用符号

调试构建通常会创建包含大多数信息的专用符号,因此信息非常准确。对于发布版本,在很长一段时间内,默认设置是根本不生成符号。

因此,请检查您是否构建了正确类型的符号。

检查符号

请检查您的符号是否包含私人信息。WinDbg带来了SymChk。这样使用:

Symchk /if <exe> /s <pdbdir> /av /od /pf

重要的是/pf。这将检查是否包含私人信息。

您也可以在WinDbg中检查它。首先确保有问题的模块(exe)已加载,然后检查符号状态:

0:003> ld myExe
Symbols loaded for myExe
0:003> lm m myExe
start    end        module name
002d0000 002d8000   myExe    C (private pdb symbols)  E:...myExe.pdb

如果WinDbg说"私有pdb符号",那应该没问题。

内存损坏

如果堆栈不正确,还可能存在堆栈溢出或欠载或其他内存损坏。试着打开一些GFlags(WinDbg附带的工具),以接近真正的问题。

GFlags可以在运行时检查内存损坏和崩溃,这样调用堆栈可能在您的代码中,而不是在其他人的代码中。

就我个人而言,我从未见过转储文件不正确。它只是崩溃时内存的副本。如果内容与我预期的不匹配,那么内存不同总是有原因的,例如内存泄漏。

优化

最后,如果您做了所有正确的事情,但仍然看到不正确的结果,这可能是由优化引起的。在优化过程中,汇编级的语句可能会被重新排列,甚至被删除,方法可能会内联等。因此,最终,它与代码(就代码行而言)不再是1:1的关系。