0

地图文件如下所示:

0002:000442e4 00000118H .idata$2                DATA   
0002:000443fc 00000014H .idata$3                DATA   
0002:00044410 00000b7cH .idata$4                DATA   
0002:00044f8c 0000512eH .idata$6                DATA   
0002:0004a0ba 00000000H .edata                  DATA   

崩溃信息如下所示:

Application Error : The instruction at "0x00458ae1" referenced memory at "0x00000074". The memory could not be "read".

我试图在下一次崩溃时获取堆栈转储,但在我看来,这是我们击败堆栈然后返回的情况,这使我们最终执行数据。

不过我并不完全确定,因为我读过一些这样的文章:Under the Hood Article似乎表明这是一个导入方法名称的区域

导入库为导入的 API 提供的数据保存在几个名称都以 .idata 开头的部分中(例如,.idata$4、.idata$5 和 .idata$6)。.idata$5 部分包含一个 DWORD,当可执行文件加载时,它包含导入函数的地址。.idata$6 部分(如果存在)包含导入函数的名称。当将可执行文件加载到内存中时,Win32 加载程序使用此字符串有效地调用导入函数的 GetProcAddress。

没有堆栈回溯,我有点卡住了。我是否以错误的方式看待这次崩溃?

4

1 回答 1

2

忘记 MAP 文件,最好使用 PDB 文件。对于此启用链接器选项/DEBUG - 是的,即使对于发布版本也是如此。/DEBUG 是链接器选项,_DEBUG 是编译器选项。只有 _DEBUG 控制代码,以及源/头文件对此进行的任何条件编译。

调试版本禁用了优化,启用了 _DEBUG 宏。发布版本启用了优化,禁用了 _DEBUG 宏。/DEBUG 只会将调试信息放入 EXE/DLL 中,不会影响其他任何内容。

回到问题,当崩溃发生时。当 WER(Windows 错误报告)说它崩溃时,不要关闭应用程序。而是将其保留在那里,转到任务管理器,转到进程选项卡,选择崩溃/崩溃的进程,然后点击“创建转储文件”。转储文件(完整转储)将在某个本地文件夹中创建(路径将由任务管理器显示)。您现在可以关闭崩溃的应用程序(WER 窗口)。

现在将此 .DMP 文件复制到某个安全位置,最好是包含原始 Release 文件夹的文件夹。在 Visual Studio 或 WinDbg 中打开它。在 VS 上,只需按 F11/F10,就会显示调用堆栈。如果多个线程正在运行(在您崩溃的应用程序中),启动“线程”视图,查看唯一挂起的线程,双击它,您将找到崩溃位置。

您必须具有正确的 PDB 以及所有二进制文件,并且必须具有完全相同的代码才能查看代码,否则调用堆栈将不会很好。

要获取有关 PDB 和其他内容的更多信息,您可以阅读这篇文章

于 2012-02-15T16:56:39.777 回答