读书人

Delphi怎的打印函数调用堆栈信息

发布时间: 2013-07-16 22:38:04 作者: rapoo

Delphi怎样打印函数调用堆栈信息
我想问下,在Delphi中怎样在出异常后打印出函数调用堆栈,包括行号,函数名。

我知道Eurekalog有这个的完整功能,我想自己实现一套,看了下Eurekalog的源码,功能太复杂,没搞明白。
有谁有自己实现这一套的代码吗? Delphi 栈 异常 堆栈
[解决办法]
这个是系统级的东西了。。。。

每个函数执行后,首先往一个stack压入直接的函数名——行号似乎都没有直接的办法能得到
[解决办法]
调试时调试窗口不就能查看栈信息了,你是要自己写调试器跟踪器么?有啥意义嘛?

// 用断言来获得行号这是最简单的,也可以自己扩展异常类


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure Test(Sender: TClass; i: Integer; str: string);
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

var
procName: ShortString;

procedure ErrorProc(const msg, fileName: string; lineNum: Integer; errorAddr: Pointer);
var
li: TStringList;
begin
li := TStringList.Create;
try
li.Add('程序出现错误,相关信息:');
li.Add('所在文件: ' + fileName);
li.Add('所在行号: ' + IntToStr(lineNum));
li.Add('所在函数: ' + procName);
li.Add('函数地址: $' + IntToHex(Integer(errorAddr), 8));
li.Add('______________________________________________________' + #10);
li.Add('是否终止程序?');

if Application.MessageBox(PChar(li.Text), PChar(msg), MB_OKCANCEL + MB_ICONWARNING +
MB_DEFBUTTON2) = IDOK then


begin
FreeAndNil(li);
Halt(1);
end;
finally
procName := '';
FreeAndNil(li);
end;

end;

procedure TForm1.Test(Sender: TClass; i: Integer; str: string);
begin
AssertErrorProc := @ErrorProc;
procName := 'TForm1.Test'; // 也可以通过rttl获取函数名
Assert(i = 100); // 断言 i=100
ShowMessage(str);
end;

procedure TForm1.btn1Click(Sender: TObject);
begin
Test(TButton, 200, '啥也不干,我就看看');
end;

end.



Delphi怎的打印函数调用堆栈信息
[解决办法]
是否没意义,如果真有很难处理的运行期问题,你可以crash dump,然后把此版本的map转为dbg到win debug去查看,没有map夜市不行的,exe中没有函数名。
[解决办法]
可能吧,你可以关闭ek,然后到Linker选项里设置连接时生成详细map就可以了。
[解决办法]
你自己看下调试原理,(ce原代码里有调试器的 原理的话去看 软件调试)
要打印堆栈信息 一定要用到调试器的,因为要监视变量。

读书人网 >.NET

热点推荐