我已经开发了一个客户,他在进行某项操作时会遇到这样的问题。这不会发生在同一个地方和相同的数据上,而且,它不会发生,也不会发生在我的本地开发机器上,也不会发生在我的测试虚拟机(没有所有开发设备)中。
鉴于这些条件,我决定使用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吗?
答案 0 :(得分:5)
稍微修改程序,使用unhandled exception handler
崩溃时写一个小型转储将新编译的程序提供给客户,当它崩溃时调用MiniDumpWriteDump。
要求客户将此.dmp文件发送给您,然后您只需将其加载到Visual Studio(或WinDbg)中,它就会将符号与程序匹配,并且还会匹配代码。您应该能够看到确切的代码行和所涉及的一些变量。 (如果使用VS,当你加载.dmp文件时,右上角将是&#34的一个选项;开始调试"点击它,因为它将在崩溃时开始调试' )
首先在本地尝试 - 在程序中的某处放置一个div by zero错误,看看是否可以在运行后调试转储。请注意,您必须为程序的每个版本保留完全相同的符号文件 - 它们完全匹配。您不能指望一个构建的符号文件与另一个构建匹配,即使没有任何更改。
有这类内容的教程,例如this one from CodeProject,看起来它描述了你需要的内容。
答案 1 :(得分:3)
在此代码项目文章中,可以很好地解释MAP文件以找出崩溃位置。
http://www.codeproject.com/Articles/3472/Finding-crash-information-using-the-MAP-file
希望有所帮助。答案 2 :(得分:2)
对于事后调试,有一种替代方案不需要使用地图文件。相反,它需要您创建一个简单的注册表脚本,以启用一些WER(Windows错误报告)标记来捕获崩溃转储文件。首先,使用调试符号构建应用程序。然后,按照Collecting User-Mode Dumps的说明操作。基本上,您在“LocalDumps”键下创建一个子键。此子键必须是应用程序的名称,例如“myapplication.exe”。然后,创建“DumpCount”,“DumpType”和“DumpFolder”键/值。让用户运行注册表脚本。这将允许在本地捕获转储。然后,让用户强制崩溃来收集转储文件。然后,用户可以使用您之前创建的符号将转储文件发送给您进行调试。最后,您需要创建一个注册表脚本,删除您添加到注册表中的键/值。