[转]通过崩溃地址找错误行数之Delphi版

无聊的时候翻了一下收藏夹,看到了“通过崩溃地址找错误行数之Delphi版”,但地址已经失效了。通过Google找了一下,原来是CSDN的beyondtkl(大龙驹<*好久没来了,兄弟们好吧。*>)发在论坛中的。

整理一下,放在这里备份。

原地址:http://topic.csdn.net/t/20041130/12/3601416.htm


以前看了"通过崩溃地址找错误行数之VC版"那时候还没用DELPHI,昨晚刚好又看到了,所以就试了一下DELPHI的,与大家共享。^_^

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

DELPHI下生成MAP文件的方法:偶只知道下面两种,如果谁知道其他的方法,敬请告知,多谢!

生成详细的MAP信息的方法:

  1. project -> options -> linker -> Map file 选择detailed.
  2. D:\Fred\Code\DELPHI\MyPas\ErrLineByAddr2>dcc32 -GD project1.dpr
我们的代码为:

unit Unit1;

//{$D+,L+}

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Button1: TButton;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

var

I, J: Integer;

p: PChar;

begin

I := 10;

J := 0;

//I := I div J; // 32

//ShowMessage(IntToStr(I));

p := nil;

p^ := 'A'; // 38

end;

end.

想必大家看到了,会有返回0地址错误....我们这里就是要让它崩溃,让我让你崩溃!!^_^

然后执行 -> 点击 -> 然后出错 -> 我的机器上 -> 崩溃地址为0044d946

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

  • 崩溃行偏移 = 崩溃地址(Crash Address) - 基地址(ImageBase Address) - 0x1000
0044d946 - 00400000 = 0004d946 - 00001000 = 0004c946

0004C946 就是它了,我们用UltraEdit32之类的工具打开.map文件,搜索"0004C94",找到了,然后就找0004c946的那个地址,然后看到了:

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

37 0001:0004C944 38 0001:0004C946 39 0001:0004C949 41 0001:0004C97C

41 0001:0004C983

O Yeah..<星际里面注射兴奋剂的声音 ^_^>..

"38 0001:0004C946"就是它了!!unit1.pas的第38行!!去代码里看一下,果然就是38行。^_^.....

共享ing...如果有不妥之处,敬请之处!多谢....