2011-06-20 1 views

Odpowiedz

1

Spójrz na JclAddExceptNotifier w jednostce JclHookExcept.

+0

Dzięki stary, to mi bardzo pomogło. Również googled to http://andremussche.blogspot.com/2007/09/adv-debugging-hook-all-exceptions.html –

+0

@Melaum: To chyba bardzo interesujące, ale niestety nie mówię po niemiecku. (Albo jeśli to nie jest niemiecki, cokolwiek to jest, ja też tego nie mówię.) –

+1

to nie jest niemiecki, to holenderski. – jpfollenius

10

To nie jest oparte na JCL, ale jest pełne Open Source i działa od Delphi 5 do XE.

Ten logging mechanism jest w stanie przechwycić każdy wyjątek.

W rzeczywistości, ponieważ Delphi 6, można zdefiniować procedurę globalną w RtlUnwindProc być lauched kiedy każdy jest wyjątek:

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

Ten kod uruchomi następującą funkcję:

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; 

Dla Delphi 5, I had to patch the VCL in-process, ponieważ nie ma globalnego przechwytywacza wyjątku.

+2

+1, interesujące –

+0

Bardzo interesujące, dziękuję za odpowiedź! –

+0

Najnowsze wersje obsługują platformy XE4/XE5 i Win32/Win64. –