2011-06-20 58 views

回答

1

看看JclAddExceptNotifierJclHookExcept單位。

+0

謝謝你,這對我很有幫助。我也google了這個http://andremussche.blogspot.com/2007/09/adv-debugging-hook-all-exceptions.html –

+0

@Melaum:這可能非常有趣,但不幸的是我不會說德語。 (或者,如果那不是德國人,不管它是什麼,我也不會這麼說。) –

+1

這不是德國人,而是荷蘭人。 – jpfollenius

10

這不是基於JCL的,但它是完整的開放源代碼,並從Delphi 5直到XE。

logging mechanism是能夠攔截任何異常。

事實上,自從德爾福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,I had to patch the VCL in-process,因爲沒有全局異常攔截器。

+2

+1,有趣的 –

+0

非常有趣,謝謝你的回答! –

+0

最新版本支持XE4/XE5和Win32/Win64平臺。 –