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”节。

相关文章推荐

windows 程序异常崩溃等错误定位

MAP/映射文件 1.      MAP 映射文件的作用:MAP文件可以查找崩溃或者程序异常地址,然后就可以精确地定位到源代码中出错的代码行。 2.VS中生成MAP文件的方法,项目属性...
  • mfc5158
  • mfc5158
  • 2016年07月07日 16:25
  • 2065

程序异常VC调试器无法定位的处理

原文:http://www.cppblog.com/sunicdavy/archive/2013/06/27/201339.html 最近调试程序发现空指针老无法定位, 使用一个最简单的main...

vc++调试---利用PDB和dump文件定位问题并进行调试(VS2010)

如何得到PDB 二、 选中取消即可会出现如下: 即可得到如下所示:...

程序崩溃的调试方法及原因分类

作者 邵发 官网 http://afanihao.cn 本文是 C/C++学习指南(补充篇)- 单步调试 的官方文档。。。程序崩溃的原因分类 1. 函数栈溢出 一个变量未初化、未赋值,就读取它的值...

实战:结合Dr.Watson系统日志和Vc6来定位多线程环境下程序异常退出的错误

转自于:http://blog.csdn.net/coding_hello/article/details/2994158   当开发的软件发布以后,在客户那运行时可能会因为各种原因导致程序退出。...
  • mail_cm
  • mail_cm
  • 2012年03月16日 09:41
  • 360

实战:结合Dr.Watson系统日志和Vc6来定位多线程环境下程序异常退出的错误

 实战:结合Dr.Watson系统日志和Vc6来定位多线程环境下程序异常退出的错误    当开发的软件发布以后,在客户那运行时可能会因为各种原因导致程序退出。这种情况很尴尬,很明显我们无法在客户机器上...
  • Augusdi
  • Augusdi
  • 2011年05月06日 16:01
  • 930

How to handle crash problem? (1.结合Dr.Watson系统日志和Vc6来定位多线程环境下程序异常退出的错误)

本文转载,实战:结合Dr.Watson系统日志和Vc6来定位多线程环境下程序异常退出的错误 www.firnow.com    时间 : 2008-10-08  作者:佚名 编辑:本站 点击:  8...

MS-VC 使用MAP文件快速定位错误行 .

****************************************************************************************************...
  • QQIANQQ
  • QQIANQQ
  • 2011年07月05日 16:32
  • 1621

解决VC6.0打开文件错误的方法

  • 2013年02月02日 16:39
  • 3.26MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:VC程序错误定位方法
举报原因:
原因补充:

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