Is there a way to catch all exceptions (even those handled) with JCLDebug?

后端 未结 2 1762
孤城傲影
孤城傲影 2020-12-06 11:47

I want use JCLDebug to log all exceptions raised, including the ones that are handled.

Is it possible to do that?

相关标签:
2条回答
  • 2020-12-06 12:00

    It's not JCL based, but it's full Open Source and works from Delphi 5 up to XE.

    This logging mechanism is able to intercept any exception.

    In fact, since Delphi 6, you can define a global procedure in RtlUnwindProc to be lauched when any exception is raised:

    {$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;
    

    This code will launch the following function:

    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;
    

    For Delphi 5, I had to patch the VCL in-process, because there is no global exception interceptor.

    0 讨论(0)
  • 2020-12-06 12:01

    Take a look at JclAddExceptNotifier in the JclHookExcept unit.

    0 讨论(0)
提交回复
热议问题