有没有办法用JCLDebug捕获所有异常(甚至是那些处理过的异常)?

时间:2011-06-20 17:45:33

标签: delphi exception

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

有可能吗?

2 个答案:

答案 0 :(得分:11)

它不是基于JCL的,但它是完整的开源,从Delphi 5到XE。

logging mechanism能够拦截任何异常。

事实上,自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,我had to patch the VCL in-process,因为没有全局异常拦截器。

答案 1 :(得分:2)

查看JclAddExceptNotifier单元中的JclHookExcept