分析堆栈,处理异常

来源:互联网 发布:硬盘数据销毁软件 编辑:程序博客网 时间:2024/05/17 01:57
  相信很多程序员头疼的是软件在家里测试没有问题,拿给客户后莫名其妙出现异常,而客户又描述不清楚,然后跑去现场调试,跟踪半天又重现不了问题。有一种方法可以精确定位异常代码,就是查找堆栈表。

本文只针对WINDOWS平台软件,当软件发生异常时,会弹出“遇到问题需要关闭,要查看这个错误报告包含的数据,请单击此处”,点击之后弹出一些详细信息,下面就来讲一下如何根据Offset来跟踪异常代码。

首先,在工程中
设置Listing Files->Listing file type->Assembly, Machine Code, and Source,
再勾选Generate map file
这样每次编译都会生成map文件以及相应模块的cod文件。
当软件发布后,请保留这些堆栈表,用于跟踪错误代码。

然后,当软件发生错误,查看到Offset值,
例如:Offset: 00001469
先打开map文件,找到与该地址最相近又不大于值的,
例如?OnButton1@CZzzzDlg@@IAEXXZ 00401450 f   zzzzDlg.obj
(注意头4位0040是Preferred load address is 00400000)
可以得知错误发生在zzzzDlg对象的OnButton1函数中,
然后计算出代码偏移位置:00001469-00401450=19(十六进制),
打开zzzzDlg.cod找到OnButton1对应代码处,
例如:
; 181  :     char* p = NULL;
; 182  :
; 183  :     char* abc = new char[20];
  00002 6a 14   push  20   ; 00000014H
  00004 33 ff   xor  edi, edi
  00006 e8 00 00 00 00  call  ??2@YAPAXI@Z  ; operator new
  0000b 8b f0   mov  esi, eax
  0000d 83 c4 04  add  esp, 4
; 184  :
; 185  :     for (a = 0; a < 20; a++)
  00010 33 c0   xor  eax, eax
; 186  :     {
; 187  :         abc[a] = a;
; 188  :
; 189  :         p[a] = 1;
  00012 33 d2   xor  edx, edx
  00014 b9 01 01 01 01  mov  ecx, 16843009  ; 01010101H
  00019 89 0a   mov  DWORD PTR [edx], ec        <-------------就是这一行
对应代码p[1]=1(错误就是这一句)
现在我们来分析一下代码
char* p = NULL;         (p为空指针)
p[a]=1;                     (往空指针内写数据, 肯定会异常)

不对的地方欢迎大家批评指正
原创粉丝点击