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


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

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

  1、崩溃地址

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

iOS开发bugly增加崩溃标识 ios release 崩溃_crash

  

  2、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文件中加入代码行信息。

  

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

     

iOS开发bugly增加崩溃标识 ios release 崩溃_windows_02

  

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

  3、定位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