欢迎来到天天文库
浏览记录
ID:30448650
大小:85.92 KB
页数:14页
时间:2018-12-30
《调试release发布版程序的crash错误》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、调试Release发布版程序的Crash错误在Windows平台下用C++开发应用程序,最不想见到的情况恐怕就是程序崩溃,而要想解决引起问题的bug,最困难的应该就是调试release版本了。因为release版本来就少了很多调试信息,更何况一般都是发布出去由用户使用,crash的现场很难保留和重现。本文将给出几个解决方案,完成对release版应用程序crash错误的调试。(本文只讨论Windows平台MSVC环境下的调试,对于其他平台和开发环境没有关注,请大家自己借鉴和尝试。)方案一:崩溃地址+MAP文件这种方案只能对VC7以前的版本开发的程序使用。1
2、、崩溃地址所谓崩溃地址就是引起程序崩溃的内存地址,在WinXP下应用程序crash的对话框如下图:上面第2张图中画红线的值为crash的代码偏移地址,第3张图为即crash绝对地址;一般引起crash的原因多为内存操作错误,我们用这两个地址和MAP文件就能定位出错的代码行。2、MAP文件MAP文件是记录应用程序信息的文件(文本文件),里面大概包含了程序的全局符号、源码模块名、源码文件和行号等信息,而这些信息能够帮助我们定位出错的代码行。怎样生成MAP文件呢?以VC6为例,在ProjectSettings-C/C++-Debuginfo中,选择LineNum
3、bersOnly;在ProjectSettings-Link中,选择Generatemapfile项,并在ProjectOptions里面输入/MAPINFO:LINES和/MAPINFO:EXPORTS,重新编译程序就会生成.map文件。以上设置对应的编译链接选项分别分:/Zi-表示生成pdb调试信息;/MAP[:filename]-表示生成map文件名;/MAPINFO:EXPORTS-表示生成的map文件中加入exportedfunctions(生成DLL文件时);/MAPINFO:LINES-表示生成的map文件中加入代码行信息。由于/MAPINF
4、O:LINES选项在VC8以后的版本中不再支持,因此通过MAP文件中的信息和crash地址定位出错代码行就比较困难了,所以这种方案只能在VC7及以前的版本中使用。一个MAP文件片段示例如下:图中Rva+Base列的地址为该行函数对应的函数绝对地址,Address列中冒号后面的地址为函数相对偏移地址。3、定位crash代码有了上面的介绍,定位crash代码就很简单了。用下面的公式来进行定位:崩溃行偏移=崩溃地址-崩溃函数绝对地址+函数相对偏移我们首先根据崩溃地址(绝对地址),按照找到第2张图中Rva+Base列的地址找到发生崩溃的函数(即崩溃地址大于该函数行
5、的Rva+Base地址且小于下个函数的地址),然后找到该行对应的函数相对偏移地址,带入公式中,就得到了崩溃行偏移,该值表示崩溃行的代码相对于代码所在函数的偏移量。用该值去与第3张图中对应函数冒号后面的偏移量去比较,最接近的值前面的那个十进制数即为代码所在函数中的行号。ok,到此我们已经成功找到了崩溃的代码行,只不过这种方法还是比较费力,并且限制比较多,我们看看下面的方案。上篇给出的方案一还要补充几句。通过"crash地址+MAP文件"来定位出错代码位置虽然需要经过比较复杂的地址计算,但却是最简单实现的方式。如果仅仅想通过崩溃地址定位出错的函数,就更加方便了
6、。我在网上找到一个解析MAP文件的小工具,可以非常清晰的列出每个函数的地址,并且可以将分析表格导出为Excel文件。工具下载地址:,工具目录下VCMapper.exe。另外上篇主要参考两篇文章:方案二:崩溃地址+MAP文件+COD文件由于VC8以后的版本都不再支持MAP文件中产生代码行信息,因此我们寻找另一种定位方式:COD文件。1、COD文件COD文件是一个包含了汇编码、二进制机器码和源代码对应信息的文件,每一个cpp都对应一个COD文件。通过这个文件,我们可以非常方便地进行定位。在VC6中生成COD文件的设置方式为:ProjectSettings-C/
7、C++,在Category中选ListingFiles,在Listingfiletype组合框中选Assembly,Machinecode,andsource。在VC8中生成COD文件的设置方式为:ProjectProperties-C/C++-OutputFiles-AssemblerOutput项,选择Assembly,Machinecode,andSource(/Facs)。2、定位崩溃行下面通过举例进行说明。现在我有一个基于对话框的MFC应用程序CrashTest,在CCrashTestDlg:OnInitDialog函数中写入导致crash的代码
8、语句(第99行),源文件如下:根据崩溃地址(0x004012A3)
此文档下载收益归作者所有