不少程序员都会遇到发布的程序出现异常崩溃,却苦于找不到问题所在。若是在固定的条件下出错,尚且好办;但随机出现,就很伤脑筋了。为此推荐给大家一个好方法——使用Map文件对照查找问题的源头。
1. 生成Map文件
首先将你的项目配置成Release版,修改(IDE:VS2003):项目属性->C/C++->常规->调试信息格式:仅限行号(/Zd)、 C7
兼容(/Z7) 或者 程序数据库(/Zi),这3项任选一项就可以。如图:
兼容(/Z7) 或者 程序数据库(/Zi),这3项任选一项就可以。如图:
也可以打开“Project Settings”选项页,选择 C/C++ 选项卡,并在最下面的 Project Options 里面输入:/Zd 。
其次设置生成Map文件,如图:
也可以选择 Link 选项卡,在最下面的 Project Options 里面输入:/mapinfo:lines
和 /map:Project_Name.map。
和 /map:Project_Name.map。
2.查找出错代码行
程序崩溃后会出现弹框,记录下出错地址,假如为0x00401258,舍掉后两位偏移量,在Map文件中查找>=0x00401200的最接近地址,假如为0001:00000250
_WinMain@16 00401250 f mapRun.obj。则说明问题出现在mapRun.obj里的WinMain函数内。
_WinMain@16 00401250 f mapRun.obj。则说明问题出现在mapRun.obj里的WinMain函数内。
接下来继续在Map文件里搜索mapRun.obj,找到对应的cpp文件,如图:
由于崩溃地址都是由 偏移地址(Rva)+ 基地址(Base) 得来的,所以在计算行号的时候
要把基地址减去,一般情况下,基地址的值是 0x00400000 。另外,由于一般的 PE 文件
的代码段都是从 0x1000 偏移开始的,所以也必须减去 0x1000 。
公式:
崩溃行偏移 = 崩溃地址(Crash address)-基地址(Preferred load address)- 0x1000。
在本例中为崩溃行偏移 = 0x00401258 - 0x00400000 - 0x1000 = 0x258,
舍去末尾1位,找到>=0x250的最接近地址为
30 0001:00000250,即问题出在maprun.cpp文件里的第30行。
问题找到,剩下的就是你的事了。