【发布时间】:2013-04-08 22:18:59
【问题描述】:
我试图弄清楚如何在 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 的人已经这样做了,但我想知道它是如何完成的。
【问题讨论】:
-
您在阅读汇编方面的能力如何? ;-)
-
我一直不明白为什么 RTL 没有内置这个...
-
@WarrenP:相当不错,或者至少足以解决我认为的问题,但我似乎不走运。 :(
-
“我想知道它是怎么做的。” - 阅读来源。 JCL 源是开放的,对于 mORMot 和一些免费的记录器和分析器也是如此。有许多 FLOSS 产品结合了展开堆栈。你可以阅读他们的代码并从中学习。
-
如果您需要做某事而没有时间自己解决,您可以联系 madshi(MadExcept 的作者)并请他设计解决方案。这就是我会做的。这东西很难。
标签: delphi exception stack-trace