加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Delphi在异常后获取堆栈跟踪

发布时间:2020-12-15 09:49:39 所属栏目:大数据 来源:网络整理
导读:我试图弄清楚如何在Delphi中抛出异常后获取堆栈跟踪.但是,当我尝试使用下面的函数在Application.OnException事件中读取堆栈时,堆栈似乎已被刷新并被抛出过程替换. function GetStackReport: AnsiString;var retaddr,walker: ^pointer;begin // ... // Histor
我试图弄清楚如何在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等,通过挂钩RTL本身内部的关键函数和核心异常处理程序来处理这些细节.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读