Есть ли способ перехватить все исключения (даже обработанные) с помощью JCLDebug? - PullRequest
9 голосов
/ 20 июня 2011

Я хочу использовать JCLDebug для регистрации всех возникших исключений, включая те, которые были обработаны.

Возможно ли это сделать?

Ответы [ 2 ]

11 голосов
/ 20 июня 2011

Он не основан на 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 , потому что нет глобального перехватчика исключений.

2 голосов
/ 20 июня 2011

Взгляните на JclAddExceptNotifier в блоке JclHookExcept.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...