如何从启用优化(发布模式)构建的二进制文件中分析故障转储?

Posted

技术标签:

【中文标题】如何从启用优化(发布模式)构建的二进制文件中分析故障转储?【英文标题】:How do I analyze a crash dump from a binary built with optimizations enabled (release mode)? 【发布时间】:2011-06-22 04:16:08 【问题描述】:

到目前为止,我一直在项目中使用调试模式二进制文件。因此使用保留的符号文件很容易分析故障转储。

现在我必须在发布模式下发布二进制文件。我们如何分析发布模式二进制文件生成的转储文件。

    有可能吗? 如何识别发布模式下的功能? (是否需要生成和保存地图文件)

【问题讨论】:

即使在发布模式下,您至少仍然可以获得调用堆栈,而这就是您通常从崩溃转储中获得的全部内容。仍然可以为发布模式二进制文件创建调试符号。 (不过我不回答,因为我不熟悉WinDbg) 【参考方案1】:

您需要与可执行文件对应的 .pdb 文件。这会给你符号。

调试发布版本有几个棘手的部分:

    由于优化,操作顺序可能有偏差 整个函数/变量/等。可能会被优化掉 特别是,传递给函数的参数可能不存在(例如,“this”可能是一个寄存器,而不是内存中的某个位置)。不过,Windbg 非常擅长从中获取堆栈跟踪,包括找出参数。

【讨论】:

【参考方案2】:

不需要 MAP 文件。您需要启用“生成调试信息”/DEBUG 标志,即使对于发布版本也是如此。在 VS2008 及更高版本中,即使是发布版本,也会设置 /DEBUG 标志。在早期版本中,您需要明确执行此操作。

这将为您的 .EXE/.DLL 生成 .PDB 文件,并且您必须将它们与您的可执行文件/DLLS 一起保存(您可能会或可能不会提供给客户,这是您的选择)。发生故障转储时,您应该拥有/获取 .DMP 文件。只需从存储 PDB 文件的位置在 Visual Studio 中加载该 DMP 文件。这将显示发生崩溃的调用堆栈。

如果有多个线程,您需要切换到“线程”窗口并查找“已暂停”列。挂起为 1 的列是导致崩溃的线程。

使用它,您可以看到所有正在运行的线程的正确调用堆栈。但是您还需要拥有正确的 源代码 副本才能查看代码!否则它只是组装。 MFC/ATL/STL 等的部分源代码可能是可见的,但不是您的代码,除非您有正确的源代码。

PDB 文件确实存储了源代码的路径,它们将使调试器能够加载源文件,即使源不是来自您放置 PDB 和 DMP 文件的位置。

【讨论】:

以上是关于如何从启用优化(发布模式)构建的二进制文件中分析故障转储?的主要内容,如果未能解决你的问题,请参考以下文章

以下模块是在启用优化或没有调试信息的情况下构建的

删除编译器优化并在发行版中启用 pdb 文件

如何在 Android NDK 项目中包含二进制文件?

在 Android Studio 中分析 Proguard 优化构建的最佳方式?

以下模块是在启用优化或没有调试信息的情况下构建的

如何在 R 中分析和优化已经快速的代码