mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-09 20:43:50 +01:00
FpDebug: Test for stepping over an breakpoint that continues (condition/auto-continue/...) / stepping over recursive calls
git-svn-id: trunk@61884 -
This commit is contained in:
parent
52a25d352c
commit
bfb0ff05df
@ -29,6 +29,16 @@ begin
|
||||
x := 1;
|
||||
end;
|
||||
|
||||
Procedure MyNested(ALvl: Integer = 0);
|
||||
begin
|
||||
if ALvl > 3 then exit;
|
||||
if ALvl = 0 then
|
||||
x := 1; // TEST_BREAKPOINT=BrkNested
|
||||
x := 3; MyNested(ALvl + 1); x := 4; if ALvl = 0 then // only reach "AfterNested" in most outer recurse
|
||||
x := 2; // TEST_BREAKPOINT=AfterNested
|
||||
x := 1;
|
||||
end;
|
||||
|
||||
Procedure MySleep;
|
||||
begin
|
||||
Sleep(50);
|
||||
@ -79,8 +89,10 @@ begin
|
||||
sleep(50); // TEST_BREAKPOINT=AfterStepSleepProc
|
||||
MyBrkDis; // TEST_BREAKPOINT=AfterStepSleep
|
||||
MyBrkHitCnt; // TEST_BREAKPOINT=AfterStepBrkDis
|
||||
x := 1; // TEST_BREAKPOINT=AfterStepBrkHitCnt
|
||||
MyBrkDis; // TEST_BREAKPOINT=AfterStepBrkHitCnt
|
||||
x := 1; // TEST_BREAKPOINT=AfterStepBrkDisAgain
|
||||
x := 1;
|
||||
MyNested; // TEST_BREAKPOINT=CallNested
|
||||
|
||||
|
||||
T1 := 0;
|
||||
|
||||
@ -27,12 +27,13 @@ type
|
||||
- TODO: ignored exception: caught caught outside the step (step to except/finally)
|
||||
*)
|
||||
procedure TestStepOver;
|
||||
procedure TestStepOverInstr;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
var
|
||||
ControlTest, ControlTestStepOver: Pointer;
|
||||
ControlTest, ControlTestStepOver, ControlTestStepOverInstr: Pointer;
|
||||
|
||||
procedure TTestStepping.TestLocation(ATestName, ABrkName: String;
|
||||
ABreakHitCount: Integer);
|
||||
@ -72,11 +73,11 @@ begin
|
||||
MainBrk := Debugger.SetBreakPoint(Src, 'BrkStart');
|
||||
Debugger.SetBreakPoint(Src, 'BrkThreadCreateInStep');
|
||||
Debugger.SetBreakPoint(Src, 'BrkInterfereByThread');
|
||||
Debugger.SetBreakPoint(Src, 'BrkNested');
|
||||
|
||||
BrkDis := Debugger.SetBreakPoint(Src, 'BrkDisabled');
|
||||
BrkHitCnt := Debugger.SetBreakPoint(Src, 'BrkHitCnt');
|
||||
BrkDis.Enabled := False;
|
||||
BrkHitCnt.Enabled := False;
|
||||
BrkHitCnt.BreakHitCount := 999;
|
||||
AssertDebuggerNotInErrorState;
|
||||
|
||||
@ -85,41 +86,72 @@ BrkHitCnt.Enabled := False;
|
||||
TestLocation('Init', 'BrkStart');
|
||||
ThreadIdMain := dbg.Threads.CurrentThreads.CurrentThreadId;
|
||||
|
||||
// Step over a line
|
||||
Debugger.RunToNextPause(dcStepOver);
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStep', 'AfterStep', -1);
|
||||
|
||||
// Step over a longer line
|
||||
Debugger.RunToNextPause(dcStepOver);
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStepLongLine', 'AfterStepLongLine', -1);
|
||||
|
||||
// Step over a subroutine call
|
||||
Debugger.RunToNextPause(dcStepOver);
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStepProc', 'AfterStepProc', -1);
|
||||
|
||||
// Step over a several subroutine calls
|
||||
Debugger.RunToNextPause(dcStepOver);
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStepProcLong', 'AfterStepProcLong', -1);
|
||||
|
||||
// Step over a subroutine call, with sleep
|
||||
Debugger.RunToNextPause(dcStepOver);
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStepSleepProc', 'AfterStepSleepProc', -1);
|
||||
|
||||
// Step over a call to sleep
|
||||
Debugger.RunToNextPause(dcStepOver);
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStepSleep', 'AfterStepSleep', -1);
|
||||
|
||||
// Step over a subroutine call, with a disabled breakpoint
|
||||
Debugger.RunToNextPause(dcStepOver);
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStepBrkDis', 'AfterStepBrkDis', -1);
|
||||
|
||||
// Step over a subroutine call, with a breakpoint that continues
|
||||
Debugger.RunToNextPause(dcStepOver);
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStepBrkHitCnt', 'AfterStepBrkHitCnt', -1);
|
||||
|
||||
TestEquals('No Hit for disabled break', 0, BrkDis.HitCount);
|
||||
//TestEquals('No Hit for skipped break', 1, BrkHitCnt.HitCount);
|
||||
TestEquals('No Hit for skipped break', 1, BrkHitCnt.HitCount);
|
||||
|
||||
BrkDis.Enabled := True;
|
||||
// Step over a subroutine call, BUT STOP at the breakpoint within it
|
||||
Debugger.RunToNextPause(dcStepOver);
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At BrkDisabled', 'BrkDisabled', -1);
|
||||
// And do another step
|
||||
Debugger.RunToNextPause(dcStepOver);
|
||||
AssertDebuggerState(dsPause);
|
||||
|
||||
TestEquals('No Hit for disabled break', 1, BrkDis.HitCount);
|
||||
TestEquals('No Hit for skipped break', 1, BrkHitCnt.HitCount);
|
||||
|
||||
|
||||
// Step over a RECURSIVE subroutine call
|
||||
Debugger.RunToNextPause(dcRun);
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At BrkNested', 'BrkNested', -1);
|
||||
|
||||
Debugger.RunToNextPause(dcStepOver);
|
||||
AssertDebuggerState(dsPause);
|
||||
Debugger.RunToNextPause(dcStepOver);
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterNested', 'AfterNested', -1);
|
||||
|
||||
|
||||
(* The debugger will encounter a thread create event, during the stepping
|
||||
@ -148,6 +180,106 @@ BrkHitCnt.Enabled := False;
|
||||
TestEquals('ThreadId AfterInterfereByThread', ThreadIdMain, dbg.Threads.CurrentThreads.CurrentThreadId);
|
||||
|
||||
|
||||
dbg.Stop;
|
||||
finally
|
||||
Debugger.ClearDebuggerMonitors;
|
||||
Debugger.FreeDebugger;
|
||||
|
||||
AssertTestErrors;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestStepping.TestStepOverInstr;
|
||||
procedure StepInstrToNextLine(AName: String; MaxSteps: integer = 50);
|
||||
var
|
||||
lc: TDBGLocationRec;
|
||||
begin
|
||||
lc := Debugger.LazDebugger.GetLocation;
|
||||
repeat
|
||||
Debugger.RunToNextPause(dcStepOverInstr);
|
||||
AssertDebuggerState(dsPause, 'step instr '+AName);
|
||||
dec(MaxSteps);
|
||||
until (lc.SrcLine <> Debugger.LazDebugger.GetLocation.SrcLine) or (MaxSteps <= 0);
|
||||
end;
|
||||
|
||||
var
|
||||
ExeName: String;
|
||||
MainBrk, BrkDis, BrkHitCnt: TDBGBreakPoint;
|
||||
ThreadIdMain: Integer;
|
||||
begin
|
||||
if SkipTest then exit;
|
||||
if not TestControlCanTest(ControlTestStepOverInstr) then exit;
|
||||
Src := GetCommonSourceFor(AppDir + 'StepOverPrg.pas');
|
||||
TestCompile(Src, ExeName);
|
||||
|
||||
TestTrue('Start debugger', Debugger.StartDebugger(AppDir, ExeName));
|
||||
dbg := Debugger.LazDebugger;
|
||||
|
||||
try
|
||||
MainBrk := Debugger.SetBreakPoint(Src, 'BrkStart');
|
||||
Debugger.SetBreakPoint(Src, 'BrkThreadCreateInStep');
|
||||
Debugger.SetBreakPoint(Src, 'BrkInterfereByThread');
|
||||
Debugger.SetBreakPoint(Src, 'BrkNested');
|
||||
|
||||
BrkDis := Debugger.SetBreakPoint(Src, 'BrkDisabled');
|
||||
BrkHitCnt := Debugger.SetBreakPoint(Src, 'BrkHitCnt');
|
||||
BrkDis.Enabled := False;
|
||||
BrkHitCnt.BreakHitCount := 999;
|
||||
AssertDebuggerNotInErrorState;
|
||||
|
||||
Debugger.RunToNextPause(dcRun);
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('Init', 'BrkStart');
|
||||
ThreadIdMain := dbg.Threads.CurrentThreads.CurrentThreadId;
|
||||
|
||||
StepInstrToNextLine('Go to AfterStep');
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStep', 'AfterStep', -1);
|
||||
|
||||
StepInstrToNextLine('Go to AfterStepLongLine');
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStepLongLine', 'AfterStepLongLine', -1);
|
||||
|
||||
StepInstrToNextLine('Go to AfterStepProc');
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStepProc', 'AfterStepProc', -1);
|
||||
|
||||
StepInstrToNextLine('Go to AfterStepProcLong');
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStepProcLong', 'AfterStepProcLong', -1);
|
||||
|
||||
StepInstrToNextLine('Go to AfterStepSleepProc');
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStepSleepProc', 'AfterStepSleepProc', -1);
|
||||
|
||||
StepInstrToNextLine('Go to AfterStepSleep');
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStepSleep', 'AfterStepSleep', -1);
|
||||
|
||||
StepInstrToNextLine('Go to AfterStepBrkDis');
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStepBrkDis', 'AfterStepBrkDis', -1);
|
||||
|
||||
StepInstrToNextLine('Go to AfterStepBrkHitCnt');
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterStepBrkHitCnt', 'AfterStepBrkHitCnt', -1);
|
||||
|
||||
TestEquals('No Hit for disabled break', 0, BrkDis.HitCount);
|
||||
TestEquals('No Hit for skipped break', 1, BrkHitCnt.HitCount);
|
||||
|
||||
|
||||
Debugger.RunToNextPause(dcRun);
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At BrkNested', 'BrkNested', -1);
|
||||
|
||||
StepInstrToNextLine('Go to AfterNested 1');
|
||||
AssertDebuggerState(dsPause);
|
||||
StepInstrToNextLine('Go to AfterNested 2');
|
||||
AssertDebuggerState(dsPause);
|
||||
TestLocation('At AfterNested', 'AfterNested', -1);
|
||||
|
||||
|
||||
|
||||
dbg.Stop;
|
||||
finally
|
||||
Debugger.ClearDebuggerMonitors;
|
||||
@ -163,5 +295,6 @@ initialization
|
||||
RegisterDbgTest(TTestStepping);
|
||||
ControlTest := TestControlRegisterTest('TTestStepping');
|
||||
ControlTestStepOver := TestControlRegisterTest('TTestStepOver', ControlTest);
|
||||
ControlTestStepOverInstr := TestControlRegisterTest('TTestStepOverInstr', ControlTest);
|
||||
end.
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user