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

 上篇给出的方案一还要补充几句。通过“crash地址 + MAP文件”来定位出错代码位置虽然需要经过比较复杂的地址计算,但却是最简单实现的方式。如果仅仅想通过崩溃地址定位出错的函数,就更加方便了。我在网上找到一个解析MAP文件的小工具,可以非常清晰的列出每个函数的地址,并且可以将分析表格导出为Excel文件。工具下载地址:http://e.ys168.com/?tinyfun,工具目录下VCMapper.exe。

    另外上篇主要参考两篇文章:

    http://www.vckbase.com/document/viewdoc/?id=908

    http://www.vckbase.com/document/viewdoc/?id=1473

 

    方案二:崩溃地址 + MAP文件 + COD文件

    由于VC8以后的版本都不再支持MAP文件中产生代码行信息,因此我们寻找另一种定位方式:COD文件。

    1、COD文件

    COD文件是一个包含了汇编码、二进制机器码和源代码对应信息的文件,每一个cpp都对应一个COD文件。通过这个文件,我们可以非常方便地进行定位。

    在VC6中生成COD文件的设置方式为:Project Settings -> C/C++,在 Category 中选 Listing Files,在 Listing file type 组合框中选 Assembly,Machine code,and source。在VC8中生成COD文件的设置方式为:Project Properties -> C/C++ -> Output Files -> Assembler Output 项,选择 Assembly,Machine code,and Source(/Facs)。

   

    2、定位崩溃行

    下面通过举例进行说明。现在我有一个基于对话框的MFC应用程序CrashTest,在CCrashTestDlg::OnInitDialog函数中写入导致crash的代码语句(第99行),源文件如下:

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

    根据崩溃地址(0x004012A3)以及MAP文件(定位片段图片如下),定位crash函数为OnInitDialog;并且我们可以很容易地计算出崩溃地址相对于崩溃函数的偏移量为 0x004012A3 - 0x004011E0 = 0xC3。

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

    再来看看CrashTestDlg.cod文件,我们根据文件中源码信息找到OnInitDialog函数信息片段:

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

    可以看到图片中第一行为OnInitDialog函数汇编代码的起始行;找到“int * p = NULL;”这一句源码,其前面的98表示这行代码在源文件中的行号,下面的000c1表示相对于函数开始位置的偏移量,后面的“33 c0”为机器码,“xor eax,eax”为汇编码。那么我们根据前面算出来的偏移量0xC3,找到对应出错的语句为99行:“*p = 5;”。

    总结一下定位步骤:

    1) 根据公式 崩溃语句在函数中偏移地址 = 崩溃地址 - 崩溃函数地址 计算出偏移量X;

    2) 根据公式 崩溃语句在COD文件中地址 = 崩溃函数在COD文件中地址 + X 计算出地址Y。其中崩溃函数在COD文件中地址为COD文件中函数起始括号“{”后面表明的地址,一般情况下为0x0000;

    3) 根据Y在COD文件中找到对应代码行。

   

    ok,方案二介绍完了。这种方法最大的好处是没有VC开发环境版本限制,而且COD文件里面包含的信息更加丰富,不但可以帮助我们定位crash,还能帮我们分析很多东西。当然,这也导致编译生成了很多信息文件。

 

转自 http://blog.sina.com.cn/s/blog_48f93b530100fv7y.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值