Chcę użyć JCLDebug do rejestrowania wszystkich podniesionych wyjątków, w tym tych, które są obsługiwane.Czy istnieje sposób przechwycenia wszystkich wyjątków (nawet tych obsługiwanych) za pomocą JCLDebug?
Czy można to zrobić?
Chcę użyć JCLDebug do rejestrowania wszystkich podniesionych wyjątków, w tym tych, które są obsługiwane.Czy istnieje sposób przechwycenia wszystkich wyjątków (nawet tych obsługiwanych) za pomocą JCLDebug?
Czy można to zrobić?
Spójrz na JclAddExceptNotifier
w jednostce JclHookExcept
.
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.
+1, interesujące –
Bardzo interesujące, dziękuję za odpowiedź! –
Najnowsze wersje obsługują platformy XE4/XE5 i Win32/Win64. –
Dzięki stary, to mi bardzo pomogło. Również googled to http://andremussche.blogspot.com/2007/09/adv-debugging-hook-all-exceptions.html –
@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ę.) –
to nie jest niemiecki, to holenderski. – jpfollenius