1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
program ExceptTestPrg;
uses sysutils;
{off $DEFINE With_Implicit_Finally}
type
MyExceptionIgnore = class(Exception) end;
var
TestVal: integer;
ControlRecurseStep3Outer, ControlRecurseRaise: Integer;
procedure Nop;
begin
Freemem(GetMem(1));
end;
procedure MyRaise;
begin
if ControlRecurseRaise >= 0 then begin
ControlRecurseRaise := 0;
raise Exception.create('a'); // TEST_BREAKPOINT=BrkMyRaise
end;
Freemem(GetMem(1));
end;
procedure Step3Finally; forward;
procedure Step3FinallyOuter; forward;
procedure Step3FinallyOuterRecurse;
begin
ControlRecurseStep3Outer := 0; // only one recursion
if ControlRecurseRaise > 0 then ControlRecurseRaise := -1;
Step3FinallyOuter;
end;
procedure Step3Finally;
{$IFDEF With_Implicit_Finally}
var
a: Ansistring; // currently stepping into implicit finally handlers
{$ENDIF}
begin
try
try
Nop;
try
Nop;
{$IFDEF With_Implicit_Finally}
a := 'a';
{$ENDIF}
MyRaise;
Nop; // TEST_BREAKPOINT=BrkDeadCode3Fin
finally
Nop; // TEST_BREAKPOINT=BrkStep3Fin_A
{$IFDEF With_Implicit_Finally}
a := a + 'b';
{$ENDIF}
TestVal := TestVal + 1;
if ControlRecurseStep3Outer = 1 then
Step3FinallyOuterRecurse;
nop; end; // TEST_BREAKPOINT=BrkStep3Fin_A_END
finally
Nop; // TEST_BREAKPOINT=BrkStep3Fin_B
TestVal := TestVal + 1;
//if ControlRecurseStep3Outer = XXX then
// Step3FinallyOuterRecurse;
nop; end; // TEST_BREAKPOINT=BrkStep3Fin_B_END
finally
Nop; // TEST_BREAKPOINT=BrkStep3Fin_C
TestVal := TestVal + 1;
if ControlRecurseStep3Outer = 2 then
Step3FinallyOuterRecurse;
nop; end; // TEST_BREAKPOINT=BrkStep3Fin_C_END
Nop; // TEST_BREAKPOINT=BrkStep3Fin_Body
Nop;
Nop; // TEST_BREAKPOINT=BrkStep3Fin_IMPLICIT
end; // TEST_BREAKPOINT=BrkStep3Fin_IMPLICIT_1
procedure Step3FinallyOuter;
{$IFDEF With_Implicit_Finally}
var
a: Ansistring;
{$ENDIF}
begin
try
try
Nop;
try
Nop;
{$IFDEF With_Implicit_Finally}
a := 'a';
{$ENDIF}
Step3Finally;
Nop; // TEST_BREAKPOINT=BrkDeadCode3FinOuter
finally
Nop; // TEST_BREAKPOINT=BrkStep3FinOuter_A
{$IFDEF With_Implicit_Finally}
a := a + 'b';
{$ENDIF}
TestVal := TestVal + 1;
if ControlRecurseStep3Outer = 3 then
Step3FinallyOuterRecurse;
nop; end; // TEST_BREAKPOINT=BrkStep3FinOuter_A_END
finally
Nop; // TEST_BREAKPOINT=BrkStep3FinOuter_B
TestVal := TestVal + 1;
//if ControlRecurseStep3Outer = XXX then
// Step3FinallyOuterRecurse;
nop; end; // TEST_BREAKPOINT=BrkStep3FinOuter_B_END
finally
Nop; // TEST_BREAKPOINT=BrkStep3FinOuter_C
TestVal := TestVal + 1;
if ControlRecurseStep3Outer = 4 then
Step3FinallyOuterRecurse;
nop; end; // TEST_BREAKPOINT=BrkStep3FinOuter_C_END
Nop; // TEST_BREAKPOINT=BrkStep3FinOuter_IMPLICIT
end; // TEST_BREAKPOINT=BrkStep3FinOuter_IMPLICIT_1
procedure NestedExcept(a: integer = 0);
begin
try // TEST_BREAKPOINT=BrkStepNestedExcept_TRY
try
MyRaise;
nop; // TEST_BREAKPOINT=BrkStepNestedExcept_DEAD
finally
nop; // TEST_BREAKPOINT=BrkStepNestedExcept_Finally
nop;
if a = 0 then
NestedExcept(1); // TEST_BREAKPOINT=BrkStepNestedExcept_Finally_BEFORE
nop; // TEST_BREAKPOINT=BrkStepNestedExcept_Finally_AFTER
nop;
nop; end; // TEST_BREAKPOINT=BrkStepNestedExcept_Finally_END
nop; except // some fpc versions put debug line for except, at the end of previous statement
nop; // TEST_BREAKPOINT=BrkStepNestedExcept
nop;
nop; end; // TEST_BREAKPOINT=BrkStepNestedExcept_END
end;
var
RecStep, RecRaise: Integer;
begin
(* RecRaise
0 : Step in => Raise nested except and debugger breaks at except, step to finally
1 : Step in => Raise nested except but debugger continues at except, step ends in finally
2 : Step in => do NOT raise nested except. Step through all the finally
3 : Step over => Raise nested except but debugger continues at except => nested finally NOT paused by debugger
*)
for RecRaise := 0 to 3 do // ignore or break at recurse
for RecStep := 0 to 4 do
if (RecRaise = 0) or (RecStep in [0,1,4]) then
begin
try
ControlRecurseStep3Outer := RecStep;
ControlRecurseRaise := 0;
if RecRaise = 2 then
ControlRecurseRaise := 1; // do not raise in recurse, but enter all the finally without stopping
TestVal := 1;
Step3FinallyOuter;
nop; // TEST_BREAKPOINT=BrkMainDeadCode1
nop; except // some fpc versions put debug line for except, at the end of previous statement
nop; // TEST_BREAKPOINT=BrkStepMainExcept1
nop;
TestVal := TestVal + 1;
end;
Nop; // TEST_BREAKPOINT=BrkStepMainAfterExcept1
end;
ControlRecurseRaise := 0;
NestedExcept;
Nop;
ControlRecurseRaise := 0;
NestedExcept;
Nop;
// Do NOT step to finally, but set a breakpoint in it. Then step to next finally
nop;
nop; // TEST_BREAKPOINT=BrkMain1
ControlRecurseStep3Outer := 0;
ControlRecurseRaise := 0;
TestVal := 1;
try
Step3FinallyOuter;
except
end;
end.
|