Delphi通过Map文件查找内存地址出错代码所在行

什么是MAP文件

      什么是 MAP 文件?简单地讲, MAP 文件是程序的全局符号、源文件和代码行号信息的唯一的文本表示方法,它可以在任何地方、任何时候使用,不需要有额外的程序进行支持。而且,这是唯一能找出程序崩溃的地方的救星。

      如果要查找代码行号,需要使用下面的公式做一些十六进制的减法运算:

      崩溃行偏移 = 崩溃地址(Crash Address) - 基地址(ImageBase Address) - 0x1000

      为什么要这样做呢?我们得到的崩溃地址都是由 偏移地址+ 基地址得来的,所以在计算行号的时候要把基地址减去,一般情况下,基地址的值是 0x00400000 。另外,由于一般的 PE 文件的代码段都是从 0x1000 偏移开始的,所以也必须减去 0x1000 。

二 Delphi 下生成MAP文件的方法

      project   ->   options   ->   Linker   ->   Map   file   选择detailed。  生成的位置在Exe文件所在的目录。

 

三 例子

代码

procedure TForm1.Button1Click(Sender: TObject);
var     
    I,   J:   Integer;
    p:   PChar;
begin
    I   := 10
;
    J   := 0
;
    p   :=
   nil;
    p^   := ‘A‘;   //   41行.  这里会报错

end;

     运行时会报错

 

这里可以发现出错地址是:$004AC0E2

根据:      崩溃行偏移 = 崩溃地址(Crash Address) - 基地址(ImageBase Address) - 0x1000

               =$004AC0E2 - $00400000 -$1000

                                    =$000AB0E2

 

用记事本打开生成的MAP文件

Line numbers for Unit1(Unit1.pas) segment .text

    30 0001:000AB0C4    31 0001:000AB0CE    40 0001:000AB0E0    41 0001:000AB0E2
    42 0001:000AB0E5    44 0001:000AB118    44 0001:000AB11F

 

那么,通过在MAP文件里查找小于或等于$00000A51的最大值就是,我们要得到的崩溃行偏移.

这样得到出错行在, Unit1单元的41行.  正好是这行:   p^   := ‘A‘;   //   36行.  这里会报错

这是一种寻找错误的方式,可以根据自己的map文件快速定位到出错代码行,然后分析错误原因。

时间: 2024-10-29 19:06:24

Delphi通过Map文件查找内存地址出错代码所在行的相关文章

问题-[Delphi]通过Map文件查找内存地址出错代码所在行

一 什么是MAP文件 什么是 MAP 文件?简单地讲, MAP 文件是程序的全局符号.源文件和代码行号信息的唯一的文本表示方法,它可以在任何地方.任何时候使用,不需要有额外的程序进行支持.而且,这是唯一能找出程序崩溃的地方的救星. 如果要查找代码行号,需要使用下面的公式做一些十六进制的减法运算: 崩溃行偏移 = 崩溃地址(Crash Address) - 基地址(ImageBase Address) - 0x1000 为什么要这样做呢?我们得到的崩溃地址都是由 偏移地址+ 基地址得来的,所以在计

VS2005(vs2008,vs2010)使用map文件查找程序崩溃原因

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

VS2005(vs2008,vs2010 VS2012)使用map文件查找程序崩溃原因

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

使用Map文件查找崩溃信息

简介 编写整洁的应用程序是一回事.但是当用户告诉你你的软件已经崩溃时,你知道在添加其他功能之前最好先解决这个问题.如果你够幸运的话,用户会有一个崩溃地址.这将大大有助于解决这个问题.但是你怎么能用这个崩溃地址来判断出了什么问题呢? 创建Map文件 首先,你需要一个Map文件.如果没有,使用崩溃地址几乎不可能找到应用程序崩溃的位置.首先,我将向您展示如何创建一个好的Map文件.为此,我将创建一个新项目(MAPFILE).你也可以这样做,或者调整你自己的项目.我在VC++ 6.0中使用Win32应用

AV 地址错误 map 文件 根据地址报错,查 Delphi 代码

1. 首先需要设置程序生成 map 文件.Project -> Options -> Linker -> Map file , Detailed 2. 计算公式Edit2.Text := IntToHex(StrToInt('$'+ Edit1.Text) - StrToInt('$00400000') - StrToInt('$00001000'), 8) ;将看到的地址错误,输入到 Edit1 中. 3. 从 Map 文件中查这个地址.一般直接查是找不到的.根据获得的 Edit2 中

终于懂了:Delphi的函数名不是地址,取地址必须遵守Object Pascal的语法(Delphi和C的类比:指针、字符串、函数指针、内存分配等)good

这点是与C语言不一样的地方,以前我一直都没有明白这一点,所以总是不明白:函数地址再取地址算怎么回事? ---------------------------------------------------------------------------------------------------------------- 在学习Delphi的时候,一个很好的建议是和C/C++去类比着学习,从指针,到内存管理,到数组,到面向对象……各个方面,都是有很多可以相似和或者也有不同的方,类比着学习,一

如何定位Release 版本中程序崩溃的位置 ---利用map文件 拦截windows崩溃函数

1       案例描述 作为Windows程序员,平时最担心见到的事情可能就是程序发生了崩溃(异常),这时Windows会提示该程序执行了非法操作,即将关闭.请与您的供应商联系.呵呵,这句微软的“名言”,恐怕是程序员最怕见也最常见的东西了. 在一个大型软件的测试过程中,初期出现程序崩溃似乎成了不可避免的事.其实测试中出现程序崩溃并不可怕,反而是测试的成功.作为开发的我们更需要关心的是程序中的哪个函数或哪一行导致了系统崩溃,这样才能有针对性的进行改正. 本文描述了自己总结的几种定位崩溃的办法.

Linux System.map文件【转】

转自:http://blog.csdn.net/ysbj123/article/details/51233618 当运行GNU链接器gld(ld)时若使用了"-M"选项,或者使用nm命令,则会在标准输出设备(通常是屏幕)上打印出链接映像(link map)信息,即是指由链接程序产生的目标程序内存地址映像信息.其中列出了程序段装入到内存中的位置信息.具体来讲有如下信息: 目标文件及符号信息映射到内存中的位置. 公共符号如何放置. 链接中包含的所有文件成员及其引用的符号. 通常我们会把发送

[C] 语言字符串、文件及内存分配函数

一.字符串函数 1.gets() 头文件:#include <stdio.h> 函数原型:char *gets(char *string); 函数说明:从标准输入流(stdin)中读取整行,直至遇到换行符结束,然后丢弃换行符,储存其余字符,并在末尾加上空字符,表示一个字符串: 函数返回值:若成功则返回指向string的指针,否则返回NULL: 备注:与puts()函数配套使用:只知道string的开始出,不知道数组中有多少个元素,超出边界,容易造成缓冲区溢出. 2.fgets() 头文件:in