JCLDebug能否捕获所有异常(即使是已处理的)?

11

我想使用JCLDebug记录所有引发的异常,包括那些被处理的异常。

这是否可行?

2个回答

12

这不是基于JCL的,但是它是完全开源的,并且适用于Delphi 5到XE。

这个日志机制能够拦截任何异常。

事实上,自Delphi 6以来,可以在RtlUnwindProc中定义一个全局过程以在引发任何异常时启动:

{$ifdef DELPHI5OROLDER}
procedure RtlUnwind; external kernel32 name 'RtlUnwind';
{$else}
var
  oldUnWindProc: pointer;
{$endif}

procedure SynRtlUnwind(TargetFrame, TargetIp: pointer;
  ExceptionRecord: PExceptionRecord; ReturnValue: Pointer); stdcall;
asm
  pushad
  cmp  byte ptr SynLogExceptionEnabled,0
  jz   @oldproc
  mov  eax,TargetFrame
  mov  edx,ExceptionRecord
  call LogExcept
@oldproc:
  popad
  pop ebp // hidden push ebp at asm level
{$ifdef DELPHI5OROLDER}
  jmp RtlUnwind
{$else}
  jmp oldUnWindProc
{$endif}
end;


oldUnWindProc := RTLUnwindProc;
RTLUnwindProc := @SynRtlUnwind;

这段代码将会调用以下函数:

type
  PExceptionRecord = ^TExceptionRecord;
  TExceptionRecord = record
    ExceptionCode: DWord;
    ExceptionFlags: DWord;
    OuterException: PExceptionRecord;
    ExceptionAddress: PtrUInt;
    NumberParameters: Longint;
    case {IsOsException:} Boolean of
    True:  (ExceptionInformation : array [0..14] of PtrUInt);
    False: (ExceptAddr: PtrUInt; ExceptObject: Exception);
  end;
  GetExceptionClass = function(const P: TExceptionRecord): ExceptClass;

const
  cDelphiExcept = $0EEDFAE0;
  cDelphiException = $0EEDFADE;

procedure LogExcept(stack: PPtrUInt; const Exc: TExceptionRecord);
begin
  LastError := GetLastError;
     (...) intercept the exception
  SetLastError(LastError); // code above could have changed this
end;

对于Delphi 5,我不得不在进程内修补VCL,因为没有全局异常拦截器。


最新版本支持XE4/XE5和Win32/Win64平台。 - Arnaud Bouchez
@Arnaud Bouchez:我需要下载哪些东西才能在Delphi2006上使用您的SynLog助手,记录未处理的异常日志?您提供的链接没有明确说明需要哪些.pas文件。 - Whome
1
最简单的方法是下载mORMot夜间版本构建档案,然后使用SynCommons.pas / SynLZ.pas / Synopse.inc / SynopseCommit.inc。要构建日志查看器,您需要整个mORMot框架,因为它用于远程调试。或者,您可以从http://synopse.info/files/LogView.zip下载LogView工具的编译版本。 - Arnaud Bouchez
使用这段代码,我能够拦截异常,但是如何获取堆栈跟踪信息的 stack: PPtrUInt? - Miguel Febres
@MiguelFebres 你有几种方法 - 可以看看 SynLog.pas 是如何实现的。 - Arnaud Bouchez

3

请查看JclHookExcept单元中的JclAddExceptNotifier


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接