秋·风

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::
1、勾选project-->Options-->debugging-->other debugging info
注意:一定要勾上Generate info for the debugger(slower/increases exe-size),否则展开后看不到行号信息。


在lpr文件添加:

SetHeapTraceOutput('heaptrc.trc')

如果不保存为文件,将在屏幕显示相应的内存泄漏信息。

program Project1;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  {$IFDEF HASAMIGA}
  athreads,
  {$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, Unit1, LanZouAPI
  { you can add units after this };

{$R *.res}

begin
  SetHeapTraceOutput('heaptrc.trc');//将Heapttrc的输出保存为日志文件
  RequireDerivedFormResource:=True;
  Application.Scaled:=True;
  {$PUSH}{$WARN 5044 OFF}
  Application.MainFormOnTaskbar:=True;
  {$POP}
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

2、利用日志文件查看具体出错位置对应的代码行

1)打开View-->Leaks and Traces


2)打开日志文件:

 点"Resolve"会提示打开相应的文件(如果你的调试信息包含在可执行文件,就选可执行文件。如果是外部调试信息 就选外部调试信息的gdb文件)

 展开相应的call Trace 列表然后双击相应对行就可以在lazarus IDE打开对应文件位置,这就是存在内存泄漏的代码。

 
======================================================================================
以下是阿D处理并显示出错信息的方法:

//显示错误信息
procedure DumpExceptionCallStack(E: Exception);
var
  I: integer;
  Frames: PPointer;
  Report: string;
begin
  Report := 'Program exception! ' + LineEnding + 'Stacktrace:' +
    LineEnding + LineEnding;
  if E <> nil then
  begin
    Report := Report + 'Exception class: ' + E.ClassName + LineEnding +
      'Message: ' + E.Message + LineEnding;
  end;
  Report := Report + BackTraceStrFunc(ExceptAddr);
  Frames := ExceptFrames;
  for I := 0 to ExceptFrameCount - 1 do
    Report := Report + LineEnding + BackTraceStrFunc(Frames[I]);
  ShowMessage(Report);
  Halt; // End of program execution
end;

 

procedure TForm1.Button4Click(Sender: TObject);
begin
  try
    raise Exception.Create('Test error');
  except
    on E: Exception do
      DumpExceptionCallStack(E);
  end;
end;

 

ExceptFrameCount              //异常回溯中包含的帧数
ExceptFrames                  //返回当前异常堆栈帧
ExceptAddr                    //当前异常地址.
ExceptObject                  //当前异常对象.
ExceptProc                    //当前异常处理程序.
get_caller_addr(get_frame);   // 得到调用者的地址
get_caller_frame(get_frame);  // 得到调用者的栈帧

 

以上方法是从谷草及阿D那学到的,谢谢2位的无私分享!

posted on 2025-05-26 07:07  秋·风  阅读(212)  评论(2)    收藏  举报