• 通过MAP文件尝试解决Access violation at address错误

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

      2.DELPHI下生成MAP文件的方法: 偶只知道下面两种,如果谁知道其他的方法,敬请告知,多谢!
      生成详细的MAP信息的方法:
      1). project -> options -> Linker -> Map file 选择detailed.
      2). D:\Fred\Code\DELPHI\MyPas\ErrLineByAddr2>dcc32 -GD project1.dpr

      3.示例
      我们的代码为:
      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地址错误....我们这里就是要让它崩溃,让我让你崩溃 ^_^
      然后执行,点击,然后出错,我的机器上,崩溃地址为 00 44 d9 46。

      如果要查找代码行号,需要使用下面的公式做一些十六进制的减法运算:
      崩溃行偏移 = 崩溃地址(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

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

      4.补充
      如果由地址查不到代码行,则将
      Project -> Options -> Compiler 中的 Debugging 的 Use Debug DCUs 勾选上后编译,
      则将调用的系统文件均编译到执行文件中,同时记录在Map文件中.
      这时在查找地址,不信找不到;

      标签: delphi, error

    • 当前暂无评论 »

      • 发表评论: ( 注意:为了防止广告评论,本站链接已经启用nofollow)
      •   您的名字
      •   E-mail
      •   您的网址(选填)

Powered by Typecho)))   ICP:蜀ICP备05009250号