gpt4 book ai didi

Delphi在异常后获取堆栈跟踪

转载 作者:行者123 更新时间:2023-12-03 14:40:45 25 4
gpt4 key购买 nike

我试图弄清楚如何在 Delphi 中抛出异常后获取堆栈跟踪。但是,当我尝试使用下面的函数读取 Application.OnException 事件中的堆栈时,堆栈似乎已经被刷新并被抛出过程替换。

function GetStackReport: AnsiString;
var
retaddr, walker: ^pointer;
begin

// ...

// History of stack, ignore esp frame
asm
mov walker, ebp
end;

// assume return address is present above ebp
while Cardinal(walker^) <> 0 do begin
retaddr := walker;
Inc(retaddr);
result := result + AddressInfo(Cardinal(retaddr^));
walker := walker^;
end;
end;

这是我得到的结果:

001A63E3: TApplication.HandleException (Forms)
00129072: StdWndProc (Classes)
001A60B0: TApplication.ProcessMessage (Forms)

这显然不是我想要的,尽管它是正确的。我想检索抛出异常之前的堆栈,或者换句话说,在 OnException 调用之前(之后也可以)的内容。

有什么办法可以做到这一点吗?

我知道我正在重新发明轮子,因为 madExcept/Eurekalog/jclDebug 的人们已经做到了这一点,但我想知道它是如何完成的。

最佳答案

无法从 OnException 事件内部手动获取可行的堆栈跟踪。正如您已经注意到的,当事件被触发时,错误发生时的堆栈已经消失了。您要查找的内容需要获取引发异常时的堆栈跟踪。第三方异常记录器(例如 MadExcept、EurekaLog 等)通过 Hook RTL 本身内部的关键函数和核心异常处理程序来为您处理这些详细信息。

在最近的 Delphi 版本中,SysUtils.Exception 类现在确实具有公共(public) StackTraceStackInfo 属性,这在OnException 事件,但 Embarcadero 由于未知原因选择不在 native 实现这些属性。它需要第三方异常记录器将处理程序分配给 Exception 类公开的各种回调,以生成属性的堆栈跟踪数据。但是,例如,如果您安装了 JclDebug,那么您可以在自己的代码中提供自己的回调处理程序,使用 JCL 的堆栈跟踪函数来生成属性的堆栈数据。

关于Delphi在异常后获取堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15890029/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com