2011-06-20 24 views

Trả lời

1

Hãy xem JclAddExceptNotifier trong đơn vị JclHookExcept.

+0

Cảm ơn người đàn ông, điều này giúp tôi rất nhiều. Tôi cũng googled http://andremussche.blogspot.com/2007/09/adv-debugging-hook-all-exceptions.html –

+0

@Melaum: Điều đó có lẽ rất thú vị, nhưng tiếc là tôi không nói tiếng Đức. (Hoặc nếu đó không phải là tiếng Đức, bất kể nó là gì, tôi cũng không nói điều đó.) –

+1

nó không phải là tiếng Đức, nó là tiếng Hà Lan. – jpfollenius

10

Nó không phải dựa trên JCL, nhưng nó là nguồn mở đầy đủ và hoạt động từ Delphi 5 đến XE.

logging mechanism này có thể chặn bất kỳ ngoại lệ nào.

Trong thực tế, kể từ Delphi 6, bạn có thể định nghĩa một thủ tục toàn cầu trong RtlUnwindProc được chạy khi bất kỳ ngoại lệ xảy ra:

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

Mã này sẽ khởi động chức năng sau:

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; 

Đối với Delphi 5, tôi had to patch the VCL in-process, bởi vì không có kẻ chặn ngoại lệ toàn cầu.

+2

+1, thú vị –

+0

Rất thú vị, cảm ơn câu trả lời của bạn! –

+0

Phiên bản mới nhất hỗ trợ các nền tảng XE4/XE5 và Win32/Win64. –

Các vấn đề liên quan