home *** CD-ROM | disk | FTP | other *** search
- unit TestESTUnit1;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, ExtCtrls;
-
- type
- TForm1 = class(TForm)
- Memo1: TMemo;
- Panel1: TPanel;
- AVBtn: TButton;
- RawCheckBox: TCheckBox;
- RaiseBtn: TButton;
- procedure AVBtnClick(Sender: TObject);
- procedure RaiseBtnClick(Sender: TObject);
- procedure RawCheckBoxClick(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- private
- procedure Five;
- procedure Four;
- procedure AppException(Sender: TObject; E: Exception);
- end;
-
- var
- Form1: TForm1;
-
- implementation
-
- {$R *.DFM}
-
- uses
- LiPrgInt,
- HVYAST32,
- HVEST;
-
- function StackDumpStr: string;
- var
- i: integer;
- LocInfo: TLocInfo;
- begin
- Result := '';
- if not RTLIAvailable then
- Result := '(NO RTLI AVAILABLE!)'#13#10;
-
- if ESTRaw
- then Result := Result + 'Brute-force trace:'#13#10
- else Result := Result + 'Stackframe-based trace:'#13#10;
-
- Result := Result + 'Physical Logical Unit (######) Routine';
- for i := 0 to StackDumpCount-1 do
- with StackDump[i] do
- begin
- GetLocationInfo(Pointer(CallerAdr), LocInfo);
- if LocInfo.liLineNo <> 0 then
- Result := Format('%s'#13#10'%.8x %.8x %20s (%5d) %s.%s',
- [Result, DWORD(CallerAdr), PhysicalToLogical(DWORD(CallerAdr)),
- LocInfo.liFileName, LocInfo.liLineNo, LocInfo.liUnitName, LocInfo.liPubSym1Name])
- else
- Result := Format('%s'#13#10'%.8x %.8x %s.%s',
- [Result, DWORD(CallerAdr), PhysicalToLogical(DWORD(CallerAdr)),
- LocInfo.liUnitName, LocInfo.liPubSym1Name]);
- end;
- end;
-
- procedure TForm1.AppException(Sender: TObject; E: Exception);
- begin
- { Now report the contents of the StackDump array into the memo }
- Memo1.Lines.Clear;
- Memo1.Lines.Add(Format('Exception: %s'#13#10'"%s"', [E.ClassName, E.Message]));
- Memo1.Lines.Add(StackDumpStr);
- end;
-
- procedure TForm1.FormCreate(Sender: TObject);
- begin
- Application.OnException := Self.AppException;
- end;
-
- {$W+} { Make sure the compiler generates stack frames for the following routines }
-
- type
- EMyException = class(Exception);
-
- var
- AV: Boolean = false;
-
- procedure One;
- begin
- if AV then
- PByte(nil)^ := 0
- else
- raise EMyException.Create('Logic error in the freezer!');
- end;
-
- procedure Two;
- begin
- { OOPS! The compiler does not crate a stack-frame
- for all-assembly routines like this one. }
- asm
- { Create a default stack frame manually }
- PUSH EBP
- MOV EBP, ESP
-
- { Simulate a CALL instruction using PUSH and RET }
- PUSH OFFSET @@ret_addr
- PUSH OFFSET One
- RET
-
- { After the 'call' we get back here }
- @@ret_addr:
-
- { Clean up the stack frame }
- POP EBP
- end;
- end;
-
- procedure Three;
- begin
- { Normal procedure call }
- Two;
- end;
-
- procedure TForm1.Four;
- var
- ProcVarCall: procedure;
- begin
- { Call through a procedure variable }
- ProcVarCall := Three;
- ProcVarCall;
- end;
-
- procedure TForm1.Five;
- var
- EventCall: procedure of object;
- begin
- { Call through an event or method variable }
- EventCall := Four;
- EventCall;
- end;
-
- procedure TForm1.AVBtnClick(Sender: TObject);
- begin
- { Normal method call }
- AV := true;
- Five;
- end;
-
- procedure TForm1.RaiseBtnClick(Sender: TObject);
- begin
- { Normal method call }
- AV := False;
- Five;
- end;
-
- procedure TForm1.RawCheckBoxClick(Sender: TObject);
- begin
- HVEST.ESTRaw := RawCheckBox.Checked;
- end;
-
- end.
-