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.