调试Release发布版程序的Crash错误(一)

  在Windows平台下用C++开发应用程序,最不想见到的情况恐怕就是程序崩溃,而要想解决引起问题的bug,最困难的应该就是调试release版本 了。因为release版本来就少了很多调试信息,更何况一般都是发布出去由用户使用,crash的现场很难保留和重现。本文将给出几个解决方案,完成对 release版应用程序crash错误的调试。(本文只讨论Windows平台MSVC环境下的调试,对于其他平台和开发环境没有关注,请大家自己借鉴 和尝试。)

 

    方案一:崩溃地址 + MAP 文件

    这种方案只能对VC7 以前的版本开发的程序使用。 

    1 、崩溃地址

      所谓崩溃地址就是引起程序崩溃的内存地址,在 WinXP 下应用程序 crash 的对话框如下图:

调试Release发布版程序的Crash错误(一)

调试Release发布版程序的Crash错误(一)

调试Release发布版程序的Crash错误(一)

    上面第 2 张图中画红线的值为 crash 的代码偏移地址,第 3 张图为即 crash 绝对地址;一般引起 crash 的原因多为内存操作错误,我们用这两个地址和 MAP 文件就能定位出错的代码行。

    2 MAP 文件

    MAP 文件是记录应用程序信息的文件(文本文件),里面大概包含了程序的全局符号、源码模块名、源码文件和行号等信息,而这些信息能够帮助我们定位出错的代码行。

    怎样生成MAP 文件呢?以VC6 为例,在 Project Settings -> C/C++ -> Debug info 中,选择 Line Numbers Only ;在 Project Settings -> Link 中,选择 Generate mapfile 项,并在Project Options 里面输入 /MAPINFO:LINES /MAPINFO:EXPORTS ,重新编译程序就会生成.map 文件。

    以上设置对应的编译链接选项分别分:

    /Zi — 表示生成pdb 调试信息;

    /MAP[:filename] — 表示生成map 文件名;

    /MAPINFO:EXPORTS  — 表示生成的map 文件中加入exported functions (生成DLL 文件时);

    /MAPINFO:LINES  — 表示生成的map 文件中加入代码行信息。

    由于/MAPINFO:LINES 选项在VC8 以后的版本中不再支持,因此通过MAP 文件中的信息和crash 地址定位出错代码行就比较困难了,所以这种方案只能在VC7 及以前的版本中使用。

     一个 MAP 文件片段示例如下:  

    调试Release发布版程序的Crash错误(一)    

    调试Release发布版程序的Crash错误(一)

    图中 Rva+Base 列的地址为该行函数对应的函数绝对地址, Address 列中冒号后面的地址为函数相对偏移地址。    

    3 、定位 crash 代码

    有了上面的介绍,定位crash 代码就很简单了。用下面的公式来进行定位:

    崩溃行偏移 = 崩溃地址 - 崩溃函数绝对地址 + 函数相对偏移

    我们首先根据崩溃地址(绝对地址),按照找到第2 张图中Rva+Base 列的地址找到发生崩溃的函数(即崩溃地址大于该函数行的Rva+Base 地址且小于下个函数的地址),然后找到该行对应的函数相对偏移地址,带入公式中,就得到了崩溃行偏移,该值表示崩溃行的代码相对于代码所在函数的偏移量。用该值去与第3 张图中对应函数冒号后面的偏移量去比较,最接近的值前面的那个十进制数即为代码所在函数中的行号。

    ok ,到此我们已经成功找到了崩溃的代码行,只不过这种方法还是比较费力,并且限制比较多,我们看看下面的方案。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值