VC程序错误定位方法

原创 2005年03月30日 15:38:00

KB:Visual C++
Q196755 - HOWTO: Determine the Location of a Crash
如何定位程序崩溃的地方

概述
本文档说明如何根据错误消息中的地址来找到错误发生的地方。例如,某个用户报告使用RELEASE版程序时发生崩溃,唯一的信息就是发生错误的地址。

【技巧一:使用MAP文件】

    通过使用MAP文件,你可以定位包含错误代码的函数。要产生MAP文件,就要在工程选项中打开"/MAP"链接开关值,其设置步骤如下:
1、打开工程选项设置,设置RELEASE的选项。
2、选择"Link"页的"General"节,选择"Generate debug info"。
3、重新编译程序。

    举例来说,假设错误信息如下:

testcrash.exe - Application Error
The instruction at "0x004011a9" referenced memory at "0x00000000". The
memory could not be "written"

    错误地址为0x004011a9,检查MAP文件中的"Rva+Base"值(函数的起始位置),找到最匹配的位置。假设MAP文件内容如下:

   <... lines removed ...>
     Address            Publics by Value              Rva+Base   Lib:Object
  
    0001:00000000
   ?_GetBaseMessageMap@CTestcrashApp@@KGPBUAFX_MSGMAP@@XZ 00401000 f
   testcrash.obj
    0001:00000010       ?GetMessageMap@CTestcrashApp@@MBEPBUAFX_MSGMAP@@XZ
   00401010 f testcrash.obj
    0001:00000020       ??0CTestcrashApp@@QAE@XZ      00401020 f
   testcrash.obj
    0001:00000080       ??_ECTestcrashApp@@UAEPAXI@Z  00401080 f
   testcrash.obj
    0001:00000080       ??_GCTestcrashApp@@UAEPAXI@Z  00401080 f
   testcrash.obj
    0001:00000170       ?InitInstance@CTestcrashApp@@UAEHXZ 00401170 f
   testcrash.obj
    0001:00000210       ??1CTestcrashDlg@@UAE@XZ      00401210 f
   testcrash.obj
    0001:00000260       ?Serialize@CObject@@UAEXAAVCArchive@@@Z 00401260 f
   testcrash.obj
   <... lines removed ...>

    我们发现,函数?InitInstance@CTestcrashApp@@UAEHXZ的起始地址为00401170,下一个函数??1CTestcrashDlg@@UAE@XZ的起始地址,错误地址0x004011a9位于两者之间,那么可以断定错误出现在函数InitInstance中。

    使用MAP文件可以定位错误函数,但是它不能将范围缩小到发生错误的语句。

【技巧二:使用PDB文件】

    使用PDB文件可以准确定位错误发生的语句,其设置步骤如下:
1、保存在技巧一里面生成的MAP文件。
2、打开工程选项设置,设置RELEASE的选项。
3、选择"C/C++"页的"General"节,在"Debug Info"中选择"Program Database" ( 缺省为NULL )。
4、选择"Link"页的"General"节,选择"Generate debug info"。
5、选择"Link"页的"Customize"节,选择"Use program database"。
6、重新编译程序。
7、用Windiff或FC对照新产生的MAP文件和前面产生的MAP文件。
8、比较问题函数的"Rva+Base"是否发生变化,如果没有变化,跳过步骤9。
9、计算"Rva+Base"的差值,然后用这个值去修正错误地址,这样才得到新执行文件中的地址。

    现在你就有了一个PDB文件,它可以用来决定错误发生的具体位置,步骤如下:
1、在VC里面打开工程
2、按F11单步执行程序
3、按ALT+F9打开断点对话框
4、以错误的地址设置一个断点(注意:地址前面要加0x)
5、打开包含错误函数的文件,这时你就能看到断点所在就是错误的语句。

【参考】
    想了解调试技巧的更多内容,请参看VC在线文档中的“Using Visual C++ -- VC++ User's Guide -- Debugger”节。

VC程序异常崩溃源代码位置查找助手

  • 2011年03月02日 17:52
  • 8KB
  • 下载

VC下发布的Release版程序崩溃后的异常捕捉与查找

寻找Release版程发生异常退出的地方比Debug版麻烦得多。发生异常的时候windows通常会弹出一个错误对话框,点击详细信息,我们能获得出错的地址和大概的出错信息,然后可以用以下办法分析我们的程...
  • nokianasty
  • nokianasty
  • 2013-01-15 10:17:03
  • 7667

关于动态库中在release下创建资源崩溃的问题。

相信大家在学习动态库(尤其是MFC动态库)的初期,肯定会遇到在DLL中创建资源崩溃的问题。今天小白就遇到了这个问题,搞了好些日子,终于想明白了是怎么回事,顺便来记录一下。 造成这类崩溃错误的原因有很...
  • BestRiven999
  • BestRiven999
  • 2017-05-24 17:59:17
  • 374

VC++使用dump定位release程序崩溃问题

包含生成dump的头文件,头文件见文章末尾全局声明宏DECLARE_DUMPGEN初始化函数中使用宏INIT_DUMPGEN(随便定义一个名字)写一个必然崩溃的按钮响应代码运行程序调用响应函数使程序崩...
  • jiyanglin
  • jiyanglin
  • 2018-03-22 21:09:35
  • 11

VC根据崩溃内存地址,查找异常代码位置

经过下面四步,轻松解决程序发生了崩溃难题: 第一:生成MAP文件; 第二:查找崩溃的内存地址; 第三:定位异常代码出错函数; 第四:定位出错行号。...
  • fjh_tigerMan
  • fjh_tigerMan
  • 2015-01-06 22:09:39
  • 2499

确切定位c++代码中异常抛出位置的两个方法 (以VS2010调试为例)

有时候程序crash了,但是不能定位具体的exception在哪里throw的(因为可能函数调用很深,并且有很多try--catch),举个简单的例子: class Test { public:...
  • chuwachen
  • chuwachen
  • 2011-09-17 11:15:15
  • 3877

如何根据异常提示信息找出程序出错代码(VC6)

看到网上说在debug下可以找到预料的崩溃地址行,但是实际上没有什么用呀。(既然在debug下,那直接用调试器找不更好吗?费这么大劲干什么)(转的文章在后面)Release版本(指编译器优化后的),要...
  • luxiaoyu_sdc
  • luxiaoyu_sdc
  • 2011-06-01 13:10:00
  • 4843

VC6.0 通过崩溃地址中找到异常代码行

这是从“VC编程经验总结7”中转出来的借花献佛——如何通过崩溃地址找到出错的代码行作为程序员,我们平时最担心见到的事情是什么?是内存泄漏?是界面不好看?……错啦!我相信我的看法是不会有人反对的--那就...
  • mydeardingxiaoli
  • mydeardingxiaoli
  • 2014-03-03 14:13:44
  • 3320

VC中debug行号定位错误

前两天在linux下写了一个小程序,后来想在windows下编译,方便调试。经过一通修改终于编译过去了。但是DEGUG时下的断点的行号总是不对,比如我下在timer函数的断点,在运行时会显示到另一个函...
  • zhaoguangjun33
  • zhaoguangjun33
  • 2015-04-03 10:30:05
  • 513

利用MAP文件精确定位代码中出错的代码行

作为程序员,我们平时最担心见到的事情是什么?是内存泄漏?是界面不好看?……错啦!我相信我的看法是不会有人反对的——那就是,程序发生了崩溃! “该程序执行了非法操作,即将关闭。请与你的软件供应商联系。...
  • qing666888
  • qing666888
  • 2016-12-22 17:29:06
  • 903
收藏助手
不良信息举报
您举报文章:VC程序错误定位方法
举报原因:
原因补充:

(最多只允许输入30个字)