根据崩溃地址确定错误代码行

(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),生成机器,源代码。


程序崩溃时的绝对地址或者偏移地址


1. 假设异常偏移地址: 0x0001152f

计算异常的绝对地址

打开程序的map文件, 找到类似下行

Preferred load address is 00400000

00400000 是程序的基地址

异常的绝对地址为: 0x00400000+0x1152f=0x0041152f

2. 定位异常发生所在的函数, 打开map 文件

   找到第一个接近0x0041152f,但小于0x0041152f的值,因为异常如果发生在某个函数中时,异常地址0x0041152f肯定高于函数的起始地址
  
   所要找的列为Rva+Base,可以看出004114d0复合要求,那么异常就是发生在Test函数中
  
   Address         Publics by Value              Rva+Base       Lib:Object

 0000:00000000       ___safe_se_handler_count   00000000     <absolute>
 0000:00000000       ___safe_se_handler_table   00000000     <absolute>
 0000:00000000       ___ImageBase               00400000     <linker-defined>
 0001:00000000       __enc$textbss$begin        00401000     <linker-defined>
 0001:00010000       __enc$textbss$end          00411000     <linker-defined>
 0002:000004d0       ?Test@@YAXXZ               004114d0 f   DumpTest1.obj
 0002:00000570       _wmain                     00411570 f   DumpTest1.obj
 


3. 打开.cod文件,找到函数
	?Test@@YAXXZ PROC					; Test, COMDAT

; 17   : {

  00000	55		 push	 ebp
  00001	8b ec		 mov	 ebp, esp
  00003	81 ec cc 00 00
	00		 sub	 esp, 204		; 000000ccH
  00009	53		 push	 ebx
  0000a	56		 push	 esi
  0000b	57		 push	 edi
  0000c	8d bd 34 ff ff
	ff		 lea	 edi, DWORD PTR [ebp-204]
  00012	b9 33 00 00 00	 mov	 ecx, 51			; 00000033H
  00017	b8 cc cc cc cc	 mov	 eax, -858993460		; ccccccccH
  0001c	f3 ab		 rep stosd

; 18   : 	st *temp = (st *)malloc(sizeof(st));


   第一行

   其中"0000"表示相对于函数开始地址后的偏移,在debug版本中,这个数据为相对于函数起始地址的偏移(此时每个函数第一条语句相对偏移为0000);release版本中为相对于代码段第一条语句的偏移(即代码段第一条语句相对偏移为0000,而以后的每个函数第一条语句相对偏移就不为0000了)

   "55"为编译后的机器代码," push ebp"为汇编代码。
   从"cod"文件中我们可以看出,一条(c/c++)语句通常需要编译成数条汇编语句 。
   此外有些汇编语句太长则会分两行显示如:
  
4. 确定错误的代码行

计算异常行的地址 = 异常绝对地址--函数起始地址==0x0041152f--00x004114d0==5f
    异常发生在相对于函数首地址偏移5f的位置
	; 23   : 
	; 24   : 	temp->age = 30;

	0005c	8b 45 f8	 mov	 eax, DWORD PTR _temp$[ebp]
	0005f	c7 40 0c 1e 00
	00 00		 mov	 DWORD PTR [eax+12], 30	; 0000001eH
	

5. 只有崩溃的决定地址,找出Release版的奔溃处

对于release版的程序,如果崩溃的话,我查找对应源代码的办法是:
首先记下程序崩溃的地址,这个程序崩溃时windows会提示0X.......。
然后,把源程序加上 /FAcs 选项再重新编译一下,加上该选项可以生成一个源代码、汇编代码、机器码都含有的文件。
然后,用olydlg之类的反汇编软件找到崩溃地址对应的汇编代码和机器码,
用UE之类的文本编辑软件打开含有源代码、汇编代码、机器码都含有的文件,用搜索功能查找反汇编软件中崩溃地址附近的机器码也就是十六进制数,很快就可以找到位置了。
一般我几分钟就可以定位。
使用的人只要把崩溃地址告诉我,我就可以修改程序了。

你可能感兴趣的:(代码)