根据内存提示定位错误代码

 

一般程序崩溃可以通过debug,找到程序在那一行代码崩溃了,最近编一个多线程的程序,都不知道在那发生错误,多线程并发,又不好单行调试,终于找到一个比较好的方法来找原因,通过生成map文件,由于2005取消map文件生成行号信息(vc6.0下是可以生成行号信息的,不知道microsoft怎么想的,在2005上取消了),只能定位在那个函数发生崩溃。这里可以通过生成cod文件,即机器码这一文件,具体定位在那一行崩溃。

1 .  首先配置vc2005生成map文件和cod文件:

(1).map文件:property->Configuration Properties->Linker->Debugging 中的Generate Map File选择Yes(/MAP);

(2).cod文件:property->Configuration Properties->C/C++->output Files中Assembler OutPut中选择Assembly,Maching Code and Source(/FAcs),生成机器,源代码。

 

2.生成测试代码

     创建一个默认的对话框文档,添加一个按钮的单击事件:

   void CTESTDlg::OnBnClickedButton1()
{
     AfxGetApp()->GetMainWnd()->SetWindowText(_T("Crash"));  //乱七八糟的代码,主要是为后面异常提供一个偏移量
     int* pTest = NULL;
     *pTest = 0; // 为空指针赋值,程序将崩溃
}

在release下运行代码,点击,跳出错误对话框: 提示内存 0x0040146f错误,该内存....你懂的

3. 阅读map文件:

  3.1  Preferred load address is 00400000  //虚地址,实际的错误地址是0x0040146f - 00400000 = 146f;

 偏移地址(Rva)+ 基地址(Base)  比如:

 0001:00000440       ?OnQueryDragIcon@CTESTDlg@@IAEPAUHICON__@@XZ 00401440 f   TESTDlg.obj

 0001:00000450       ?OnBnClickedButton1@CTESTDlg@@QAEXXZ 00401450 f   TESTDlg.obj
 0001:00000480       ?Create@CDialog@@UAEHIPAVCWnd@@@Z 00401480 f i TESTDlg.obj

 

   3.2  推理出出错函数

       00401450 f  中的 0040就是高位, 1450就是低位,高位就不参与计算了,主要是对比低位, 注意后面变态的f,大家都认为是16进制的f,其实别管他,老子也不知道是哪请来的临时演员。

这里的 1450  < 146f <1480,所以错误时产生在函数OnBnClickedButton1中的。 到这里,你已经成功一半了,哈哈

 

4.定位到具体的代码行

因为上面的错误函数在TESTDlg.obj里,也就是在TESTDLG.cpp中,我们打开它的 .cod文件

用146f - 1450 = 1f (注意是16进制的计算, 如果找不到xp的计算器可在路径C:\WINDOWS\system32\dllcache\calc.exe 下找);

然后在 .cod文件里的0001f 89 00处找到 157行代码 *pTest = 0; // 为空指针赋值,程序将崩溃

; 156  :  int* pTest = NULL;

  0001d 33 c0   xor  eax, eax

; 157  :  *pTest = 0; // 为空指针赋值,程序将崩溃

  0001f 89 00   mov  DWORD PTR [eax], eax

; 158  : }

  00021 c3   ret  0

 

有时候错误可能没有这么明显,需要自己上下文判断一下。

 

Linux下Debug版本定位崩溃代码行:

ulimit -c unlimited
echo "/opt/kdm/pui/core-%e-%p" > /proc/sys/kernel/core_pattern
gcc -o main -g a.c
gdb main /opt/kdm/pui/core-main-10815


 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值