home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue50 / Except / TestESTUnit1.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-09-05  |  3.5 KB  |  162 lines

  1. unit TestESTUnit1;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  7.   StdCtrls, ExtCtrls;
  8.  
  9. type
  10.   TForm1 = class(TForm)
  11.     Memo1: TMemo;
  12.     Panel1: TPanel;
  13.     AVBtn: TButton;
  14.     RawCheckBox: TCheckBox;
  15.     RaiseBtn: TButton;
  16.     procedure AVBtnClick(Sender: TObject);
  17.     procedure RaiseBtnClick(Sender: TObject);
  18.     procedure RawCheckBoxClick(Sender: TObject);
  19.     procedure FormCreate(Sender: TObject);
  20.   private
  21.     procedure Five;
  22.     procedure Four;
  23.     procedure AppException(Sender: TObject; E: Exception);
  24.   end;
  25.  
  26. var
  27.   Form1: TForm1;
  28.  
  29. implementation
  30.  
  31. {$R *.DFM}
  32.  
  33. uses
  34.   LiPrgInt,
  35.   HVYAST32,
  36.   HVEST;
  37.  
  38. function StackDumpStr: string;
  39. var
  40.   i: integer;
  41.   LocInfo: TLocInfo;
  42. begin
  43.   Result := '';
  44.   if not RTLIAvailable then
  45.     Result := '(NO RTLI AVAILABLE!)'#13#10;
  46.  
  47.   if ESTRaw
  48.   then Result := Result + 'Brute-force trace:'#13#10
  49.   else Result := Result + 'Stackframe-based trace:'#13#10;
  50.  
  51.   Result := Result + 'Physical Logical  Unit                (######) Routine';
  52.   for i := 0 to StackDumpCount-1 do
  53.     with StackDump[i] do
  54.     begin
  55.       GetLocationInfo(Pointer(CallerAdr), LocInfo);
  56.       if LocInfo.liLineNo <> 0 then
  57.         Result := Format('%s'#13#10'%.8x %.8x %20s (%5d) %s.%s',
  58.           [Result, DWORD(CallerAdr), PhysicalToLogical(DWORD(CallerAdr)),
  59.             LocInfo.liFileName, LocInfo.liLineNo, LocInfo.liUnitName, LocInfo.liPubSym1Name])
  60.       else
  61.         Result := Format('%s'#13#10'%.8x %.8x %s.%s',
  62.           [Result, DWORD(CallerAdr), PhysicalToLogical(DWORD(CallerAdr)),
  63.             LocInfo.liUnitName, LocInfo.liPubSym1Name]);
  64.     end;
  65. end;
  66.  
  67. procedure TForm1.AppException(Sender: TObject; E: Exception);
  68. begin
  69.   { Now report the contents of the StackDump array into the memo }
  70.   Memo1.Lines.Clear;
  71.   Memo1.Lines.Add(Format('Exception: %s'#13#10'"%s"', [E.ClassName, E.Message]));
  72.   Memo1.Lines.Add(StackDumpStr);
  73. end;
  74.  
  75. procedure TForm1.FormCreate(Sender: TObject);
  76. begin
  77.   Application.OnException := Self.AppException;
  78. end;
  79.  
  80. {$W+} { Make sure the compiler generates stack frames for the following routines }
  81.  
  82. type
  83.   EMyException = class(Exception);
  84.   
  85. var
  86.   AV: Boolean = false;
  87.  
  88. procedure One;
  89. begin
  90.   if AV then
  91.     PByte(nil)^ := 0
  92.   else
  93.     raise EMyException.Create('Logic error in the freezer!');
  94. end;
  95.  
  96. procedure Two;
  97. begin
  98.   { OOPS! The compiler does not crate a stack-frame
  99.     for all-assembly routines like this one. }
  100.   asm
  101.     { Create a default stack frame manually }
  102.     PUSH EBP
  103.     MOV  EBP, ESP
  104.  
  105.     { Simulate a CALL instruction using PUSH and RET }
  106.     PUSH OFFSET @@ret_addr
  107.     PUSH OFFSET One
  108.     RET
  109.  
  110.     { After the 'call' we get back here }
  111. @@ret_addr:
  112.  
  113.     { Clean up the stack frame }
  114.     POP EBP
  115.   end;
  116. end;
  117.  
  118. procedure Three;
  119. begin
  120.   { Normal procedure call }
  121.   Two;
  122. end;
  123.  
  124. procedure TForm1.Four;
  125. var
  126.   ProcVarCall: procedure;
  127. begin
  128.   { Call through a procedure variable }
  129.   ProcVarCall := Three;
  130.   ProcVarCall;
  131. end;
  132.  
  133. procedure TForm1.Five;
  134. var
  135.   EventCall: procedure of object;
  136. begin
  137.   { Call through an event or method variable }
  138.   EventCall := Four;
  139.   EventCall;
  140. end;
  141.  
  142. procedure TForm1.AVBtnClick(Sender: TObject);
  143. begin
  144.   { Normal method call }
  145.   AV := true;
  146.   Five;
  147. end;
  148.  
  149. procedure TForm1.RaiseBtnClick(Sender: TObject);
  150. begin
  151.   { Normal method call }
  152.   AV := False;
  153.   Five;
  154. end;
  155.  
  156. procedure TForm1.RawCheckBoxClick(Sender: TObject);
  157. begin
  158.   HVEST.ESTRaw := RawCheckBox.Checked;
  159. end;
  160.  
  161. end.
  162.