Tôi muốn sử dụng JCLDebug để đăng nhập tất cả các ngoại lệ được nêu ra, bao gồm cả các ngoại lệ được xử lý.Có cách nào để bắt tất cả các ngoại lệ (ngay cả những trường hợp được xử lý) với JCLDebug không?
Có thể thực hiện điều đó không?
Tôi muốn sử dụng JCLDebug để đăng nhập tất cả các ngoại lệ được nêu ra, bao gồm cả các ngoại lệ được xử lý.Có cách nào để bắt tất cả các ngoại lệ (ngay cả những trường hợp được xử lý) với JCLDebug không?
Có thể thực hiện điều đó không?
Hãy xem JclAddExceptNotifier
trong đơn vị JclHookExcept
.
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.
+1, thú vị –
Rất thú vị, cảm ơn câu trả lời của bạn! –
Phiên bản mới nhất hỗ trợ các nền tảng XE4/XE5 và Win32/Win64. –
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 –
@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 đó.) –
nó không phải là tiếng Đức, nó là tiếng Hà Lan. – jpfollenius