2011-06-20 11 views

Respuesta

1

Eche un vistazo a JclAddExceptNotifier en la unidad JclHookExcept.

+0

Gracias hombre, esto me ayuda mucho. También busqué en Google este http://andremussche.blogspot.com/2007/09/adv-debugging-hook-all-exceptions.html –

+0

@Melaum: Eso es probablemente muy interesante, pero desafortunadamente no hablo alemán. (O si eso no es alemán, sea lo que sea, tampoco hablo de eso.) –

+1

no es alemán, es holandés. – jpfollenius

10

No está basado en JCL, pero es de código abierto completo y funciona desde Delphi 5 hasta XE.

Este logging mechanism es capaz de interceptar cualquier excepción.

De hecho, desde Delphi 6, se puede definir un procedimiento global en RtlUnwindProc ser inicializado cuando se levanta ninguna excepción:

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

Este código se lanzará la siguiente función:

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; 

Para Delphi 5, I had to patch the VCL in-process, porque no hay un interceptor de excepción global.

+2

+1, interesante –

+0

Muy interesante, gracias por su respuesta! –

+0

Las últimas versiones admiten plataformas XE4/XE5 y Win32/Win64. –

Cuestiones relacionadas