【问题标题】:Using MAP file VS2010 MFC使用 MAP 文件 VS2010 MFC
【发布时间】:2014-06-03 15:55:55
【问题描述】:

我开发了一个程序,由一位正在体验某项操作的客户开发。这并不总是发生在同一个地方和相同的数据上,而且,它既没有发生在我的本地开发机器中,也没有发生在我的测试虚拟机(没有所有开发设备)中。

鉴于这些情况,我决定使用 MAP(在配置属性-> 链接器-> 带有选项 /MAP 的调试器中启用)进行编译,以查看导致崩溃的函数。

如果我理解正确,当程序崩溃时,我必须检查偏移错误,然后在我的 MAP 中的 RVA+BASE 列下搜索:

     Address                         Publics by Value                                      Rva+Base       Lib:Object
 0001:00037af0       ?PersonalizzaPlancia@CDlgGestioneDatiProgetto@MosaicoDialogs@@IAEXXZ 00438af0 f   DlgGestioneDatiProgetto.obj
 0001:00038000       ?SalvaTemporanei@CDlgGestioneDatiProgetto@MosaicoDialogs@@IAEXXZ 00439000 f   DlgGestioneDatiProgetto.obj

实际上,我的崩溃发生在偏移量:

00038C90
所以我应该认为它在方法中的某个地方:
MosaicoDialogs::CDlgGestioneDatiProgetto::PersonalizzaPlancia

但这不是绝对可能的,所以假设电脑不会出错,我就是做错的人。

有人可以解释一下如何正确阅读 MAP 吗?

【问题讨论】:

  • 您考虑过某种形式的日志记录吗?
  • 是的,我已经排除了,因为这需要大量的工作和大量的日志。
  • “大量的工作和大量的日志。” - pffft!好的仪器就是好的仪器

标签: c++ visual-studio-2010 mfc map-files


【解决方案1】:

不要打扰 - 相反,构建启用符号的项目并将它们剥离到 pdb 文件中。

稍微修改一下程序,当它崩溃时使用unhandled exception handler写一个minidump

将新编译的程序交给客户,当它崩溃时调用MiniDumpWriteDump。

请客户将此 .dmp 文件发送给您,然后您只需将其加载到 Visual Studio(或 WinDbg)中,它就会将符号与程序匹配,也会匹配代码。您应该能够看到确切的代码行和涉及的一些变量。 (如果使用VS,当您加载.dmp文件时,右上角将是“开始调试”的选项,点击它会在崩溃点“开始调试”)

首先在本地尝试 - 在程序中的某处放置一个 div by zero error,看看是否可以在运行转储后对其进行调试。请注意,您必须为程序的每个版本保留完全相同的符号文件 - 它们完全匹配。您不能期望一个构建的符号文件与另一个构建匹配,即使没有任何更改。

有这类事情的教程,例如this one from CodeProject,它看起来像是描述了您的需求。

【讨论】:

  • 谢谢,我去看看。
  • 使用符号构建项目时,您最终会得到一个单独的 pdb 文件。如答案here中所述,没有将它们剥离到pdb文件中。但您确实想保存使用您正在部署的 .exe 创建的 pdb,以便它们匹配。
  • IIRC 符号是编译后的二进制文件的一部分,但是当链接器将所有内容链接到您的 exe 或 dll 时,“make pdb”步骤会将它们剥离到自己的 pdb 文件中。
【解决方案2】:

这篇代码项目文章很好地解释了读取 MAP 文件以找出崩溃位置。

http://www.codeproject.com/Articles/3472/Finding-crash-information-using-the-MAP-file

希望有所帮助。

【讨论】:

  • 这是完成这项工作的正确方法。我无法解决这个问题,因为错误实际上发生在 dll 中。
【解决方案3】:

对于事后调试,有一个替代方法不需要需要使用映射文件。相反,它需要您创建一个简单的注册表脚本来启用一些WER(Windows 错误报告)标志来捕获故障转储文件。首先,使用调试符号构建您的应用程序。然后,按照Collecting User-Mode Dumps 的说明进行操作。基本上,您在“LocalDumps”键下创建一个子键。此子键必须是您的应用程序的名称,例如“myapplication.exe”。然后,创建“DumpCount”、“DumpType”和“DumpFolder”键/值。让用户运行注册表脚本。这将启用在本地捕获转储。然后,让用户强制崩溃以收集转储文件。然后,用户可以将转储文件发送给您,以使用您之前创建的符号进行调试。最后,您需要创建一个注册表脚本来删除您添加到注册表中的键/值。

【讨论】:

  • 通过“使用调试符号构建您的应用程序”意味着在项目设置中为您的发布构建配置创建符号;这并不意味着调试构建(只是认为可能需要澄清)。除此之外,我认为这是一个很好的建议;仅通过注册表启用本地转储是获取转储文件的简单方法。确保从您部署的构建中保存 PDB;它必须匹配 .exe/.dll。
猜你喜欢
  • 2013-12-26
  • 2012-04-22
  • 2012-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多