Delphi 的 Exception 机制浅探(4)

2019-08-30 15:37

(EClass: ESafecallException; EIdent: SSafecallException) );

function GetExceptionClass(P: PExceptionRecord): ExceptClass; var

ErrorCode: Byte; begin

ErrorCode := Byte(MapException(P)); Result := ExceptMap[ErrorCode].EClass; end;

{ cContinuable = 0; } { cNonContinuable = 1; } { cUnwinding = 2; } { cUnwindingForExit = 4; } { cUnwindInProgress = cUnwinding or cUnwindingForExit; }

{ SysUtils.pas }

function GetExceptionObject(P: PExceptionRecord): Exception; var

ErrorCode: Integer;

function CreateAVObject: Exception; var

AccessOp: string; // string ID indicating the access type READ or WRITE AccessAddress: Pointer;

MemInfo: TMemoryBasicInformation; ModName: array[0..MAX_PATH] of Char; begin

with P^ do begin

if ExceptionInformation[0] = 0 then AccessOp := SReadAccess else

AccessOp := SWriteAccess;

AccessAddress := Pointer(ExceptionInformation[1]);

VirtualQuery(ExceptionAddress, MemInfo, SizeOf(MemInfo)); if (MemInfo.State = MEM_COMMIT) and

(GetModuleFileName(THandle(MemInfo.AllocationBase), ModName, SizeOf(ModName)) <> 0) then

Result := EAccessViolation.CreateFmt(sModuleAccessViolation, [ExceptionAddress, ExtractFileName(ModName), AccessOp, AccessAddress]) else

Result := EAccessViolation.CreateFmt(SAccessViolationArg3, [ExceptionAddress, AccessOp, AccessAddress]); end; end;

begin

ErrorCode := Byte(MapException(P)); case ErrorCode of 3..10, 12..21:

with ExceptMap[ErrorCode] do Result := EClass.Create(EIdent); 11: Result := CreateAVObject; else

Result := EExternalException.CreateFmt(SExternalException, [P.ExceptionCode]);

end;

if Result is EExternal then EExternal(Result).ExceptionRecord := P; end;

=============================================================================== ⊙ try...except 的编译器实现

===============================================================================

测试代码: begin try

raise Exception.Create('Exception'); except

on E: Exception do begin

ShowMessage(E.Message); end; end; end;

Unit1.pas.28: begin

004520C0 55 push ebp 004520C1 8BEC mov ebp,esp

004520C3 51 push ecx // 生成异常变量 E 的堆栈空间 004520C4 53 push ebx 004520C5 56 push esi 004520C6 57 push edi

Unit1.pas.29: try

// 以下 5 行在堆栈中生成异常处理结构 (try 指令的编译器实现) 004520C7 33C0 xor eax,eax

004520C9 55 push ebp // 设置 TExcFrame.hEBP 004520CA 68F5204500 push $004520f5 // 设置 TExcFrame.desc 004520CF 64FF30 push dword ptr fs:[eax] // 设置 TExcFrame.next 004520D2 648920 mov fs:[eax],esp // 安装 新建的异常处理结构

Unit1.pas.30: raise Exception.Create('Exception');

004520D5 B928214500 mov ecx,$00452128 // 错误信息字符串的地址 004520DA B201 mov dl,$01

004520DC A1286D4000 mov eax,[$00406d28] // Exception 类的 VMT ptr 004520E1 E86A91FBFF call Exception.Create

004520E6 E89D17FBFF call @RaiseExcept // raise 的编译器实现

// 以下 5 行恢复上面安装的的异常处理结构 (try 指令的编译器实现) 004520EB 33C0 xor eax,eax

004520ED 5A pop edx // TExcFrame.next(原结构地址) 004520EE 59 pop ecx 004520EF 59 pop ecx

004520F0 648910 mov fs:[eax],edx

004520F3 EB24 jmp +$24 (00452119) // 退出 try...except 块

// 以下 6 行是编译器生成的 TExeDesc 结构 (try 指令的编译器实现)

004520F5 E9CE15FBFF jmp @HandleOnException // 异常发生时的处理函数 004520FA 0100 add [eax],eax // ?? 004520FC 0000 add [eax],al 004520FE 286D40 sub [ebp+$40],ch 00452101 0006 add [esi],al

00452103 214500 and [ebp+$00],eax

Unit1.pas.32: on E: Exception do

00452106 8945FC mov [ebp-$04],eax

Unit1.pas.34: ShowMessage(E.Message);

00452109 8B45FC mov eax,[ebp-$04] 0045210C 8B4004 mov eax,[eax+$04] 0045210F E85052FDFF call ShowMessage 00452114 E8EB17FBFF call @DoneExcept 00452119 5F pop edi 0045211A 5E pop esi 0045211B 5B pop ebx 0045211C 59 pop ecx 0045211D 5D pop ebp 0045211E C3 ret


Delphi 的 Exception 机制浅探(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:滇池调研报告

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: