方法之一是用vs自带的map文件和cod文件准确定位到函数名和行号。
看到异常偏移:000113a1 (程序弹出,或者在电脑管理器里找到)
在vs里设置打印map: 工程-属性-c++-输出文件-汇编程序输出,选择/facs, 连接器-调试-是否生成映射文件,选择是,映射文件,自定义名字。确定后重新编译,即可生成map文件和cod文件。
打开目录下的.map文件,看到一行 Preferred load address is 00400000,表示起始地址是00400000,根据崩溃地址=起始地址+偏移地址,即崩溃地址=00400000+000113a1=004113a1,通过这个地址找到第一个比这个地址大的一行的前一行,也就是00411380 ,这个代表出错函数的起始地址,同时可以看到出错函数是errorFun函数。
0002:00000380 ?errorFun@@YAXPAH@Z 00411380 f char_demo.obj
0002:000003c0 _main 004113c0 f char_demo.obj
已经定位到出错函数了,下一步精确定位到出错代码行,打开.cod文件,通过搜索"errorFun"找到:
?errorFun@@YAXPAH@Z PROC; errorFun, COMDAT
; 4 : {
00000 55 push ebp
00001 8b ec mov ebp, esp
00003 81 ec c0 00 00
00 sub esp, 192; 000000c0H
00009 53 push ebx
0000a 56 push esi
0000b 57 push edi
0000c 8d bd 40 ff ff
ff lea edi, DWORD PTR [ebp-192]
00012 b9 30 00 00 00 mov ecx, 48; 00000030H
00017 b8 cc cc cc cc mov eax, -858993460; ccccccccH
0001c f3 ab rep stosd
; 5 : *p=1;
0001e 8b 45 08 mov eax, DWORD PTR _p$[ebp]
00021c7 00 01 00 00
00 mov DWORD PTR [eax], 1
; 6 : }
这里的4,5,6代表源代码的行,比如4在源代码中对应"{"
然后根据:崩溃地址-函数起始地址= 004113a1 -00411380=0x21,在code文件中找到 00021,向前看看到“; 5 : *p=1; ”,即出错代码行数是第5行,代码是*p=1,至此已经成功找到出错的代码。