2

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

鉴于这些情况,我决定使用 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 吗?

4

3 回答 3

5

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

稍微修改一下程序,在它崩溃时使用未处理的异常处理程序编写一个小型转储

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

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

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

有这类事情的教程,例如来自 CodeProject的教程,看起来它描述了您需要什么。

于 2014-06-03T16:04:19.803 回答
3

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

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

希望有所帮助。

于 2014-06-03T16:24:06.510 回答
2

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

于 2014-06-04T12:32:59.793 回答