FpDebug: TestCase, more refactor internal breakpoints.

git-svn-id: trunk@60161 -
This commit is contained in:
martin 2019-01-23 21:30:13 +00:00
parent 88aca89865
commit ceb99f5f2e
3 changed files with 128 additions and 11 deletions

View File

@ -1,6 +1,19 @@
program BreakPointPrg; program BreakPointPrg;
uses sysutils, Classes; uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
sysutils, Classes;
type
{ TTestThread }
TTestThread = class(TThread)
procedure Execute; override;
end;
var var
x, BreakDummy: Integer; x, BreakDummy: Integer;
@ -22,6 +35,23 @@ end;
label label
testasmlbl1, testasmlbl2; testasmlbl1, testasmlbl2;
{ TTestThread }
procedure TTestThread.Execute;
var
tt: Integer;
begin
tt := 1; // TEST_BREAKPOINT=Thread1
tt := 1; // TEST_BREAKPOINT=Thread2
tt := 1;
while true do begin
tt := 1;
tt := 1;
tt := 1;
tt := 1;
end;
end;
begin begin
x := 1; x := 1;
x := 1; BreakDummy:= 1; // TEST_BREAKPOINT=PrgStep1 x := 1; BreakDummy:= 1; // TEST_BREAKPOINT=PrgStep1
@ -59,11 +89,32 @@ testasmlbl2:
Foo2; Foo2;
BreakDummy:= 1; // TEST_BREAKPOINT=PrgAfterFoo2 BreakDummy:= 1; // TEST_BREAKPOINT=PrgAfterFoo2
Foo2; BreakDummy:= 1; // TEST_BREAKPOINT=New1
BreakDummy:= 1; // TEST_BREAKPOINT=PrgAfterFoo2B BreakDummy:= 1; // TEST_BREAKPOINT=New2
BreakDummy:= 1;
// TODO; stepping over ignored breakpoint / actually that is stepping test // TODO; stepping over ignored breakpoint / actually that is stepping test
// edit line / move breakpoint // edit line / move breakpoint
TTestThread.Create(False);
while true do begin
asm
nop
nop // TEST_BREAKPOINT=Main1
nop
nop
nop
nop
nop
nop // TEST_BREAKPOINT=Main2
nop
nop
nop
nop
nop
nop
end;
end;
end. end.

View File

@ -8,7 +8,7 @@ uses
Classes, SysUtils, fpcunit, testutils, testregistry, TestBase, TestDbgControl, Classes, SysUtils, fpcunit, testutils, testregistry, TestBase, TestDbgControl,
TestDbgTestSuites, TTestDebuggerClasses, TestOutputLogger, TestDbgTestSuites, TTestDebuggerClasses, TestOutputLogger,
TTestWatchUtilities, TestCommonSources, TestDbgConfig, DbgIntfDebuggerBase, TTestWatchUtilities, TestCommonSources, TestDbgConfig, DbgIntfDebuggerBase,
DbgIntfBaseTypes, Forms; DbgIntfBaseTypes, LazLoggerBase, Forms;
type type
@ -35,6 +35,9 @@ var
Src: TCommonSource; Src: TCommonSource;
dbg: TDebuggerIntf; dbg: TDebuggerIntf;
ExeName: String; ExeName: String;
loc: TDBGLocationRec;
b1, b2: TDBGBreakPoint;
i: Integer;
procedure TestLocation(ATestName, ABrkName: String; ABreakHitCount: Integer = 1); procedure TestLocation(ATestName, ABrkName: String; ABreakHitCount: Integer = 1);
var var
@ -43,12 +46,11 @@ var
AssertDebuggerState(dsPause); AssertDebuggerState(dsPause);
lc := dbg.GetLocation; lc := dbg.GetLocation;
TestEquals(ATestName+' '+ABrkName+' Loc', Src.BreakPoints[ABrkName], lc.SrcLine); TestEquals(ATestName+' '+ABrkName+' Loc', Src.BreakPoints[ABrkName], lc.SrcLine);
if ABreakHitCount >= 0 then
TestEquals(ATestName+' '+ABrkName+' HitCnt', Debugger.BreakPointByName(ABrkName).HitCount, ABreakHitCount); TestEquals(ATestName+' '+ABrkName+' HitCnt', Debugger.BreakPointByName(ABrkName).HitCount, ABreakHitCount);
end; end;
procedure TestHitCnt(ATestName, ABrkName: String; ABreakHitCount: Integer); procedure TestHitCnt(ATestName, ABrkName: String; ABreakHitCount: Integer);
var
lc: TDBGLocationRec;
begin begin
TestEquals(ATestName+' '+ABrkName+' HitCnt', Debugger.BreakPointByName(ABrkName).HitCount, ABreakHitCount); TestEquals(ATestName+' '+ABrkName+' HitCnt', Debugger.BreakPointByName(ABrkName).HitCount, ABreakHitCount);
end; end;
@ -84,7 +86,8 @@ begin
Debugger.SetBreakPoint(Src, 'Foo2'); Debugger.SetBreakPoint(Src, 'Foo2');
Debugger.SetBreakPoint(Src, 'PrgAfterFoo2'); Debugger.SetBreakPoint(Src, 'PrgAfterFoo2');
Debugger.SetBreakPoint(Src, 'PrgAfterFoo2B');
Debugger.SetBreakPoint(Src, 'Thread1');
AssertDebuggerNotInErrorState; AssertDebuggerNotInErrorState;
// Step to break next line // Step to break next line
@ -157,9 +160,69 @@ begin
TestLocation('Run Foo2 ended in prg', 'PrgAfterFoo2'); TestLocation('Run Foo2 ended in prg', 'PrgAfterFoo2');
TestHitCnt('Run Foo2', 'Foo2', 2); TestHitCnt('Run Foo2', 'Foo2', 2);
// Disable breakpoint // new breakpoint
Debugger.BreakPointByName('Foo2').Enabled := False; Debugger.RunToNextPause(dcStepOver);
TestLocation('Before insernt', 'New1', -1);
Debugger.SetBreakPoint(Src, 'New1');
Debugger.RunToNextPause(dcStepOver);
TestLocation('After insernt', 'New2', -1);
TestHitCnt('After insernt', 'New1', 0);
Debugger.SetBreakPoint(Src, 'New2');
Debugger.RunToNextPause(dcRun);
TestHitCnt('After insernt', 'New1', 0);
// in threads
(* In each thread set a breakpoint at the next instruction.
So when all threads are started, both should run/step OVER the breakpoint
without hitting it
*)
TestLocation('After insernt', 'Thread1');
Debugger.RunToNextPause(dcStepOver);
TestLocation('After insernt', 'Thread2', -1); // not set
loc := dbg.GetLocation;
TestEquals('loc in thread', loc.SrcLine, Src.BreakPoints['Thread2']);
b1 := dbg.BreakPoints.Add(loc.Address);
b1.InitialEnabled := True;
b1.Enabled := True;
for i := 0 to dbg.Threads.CurrentThreads.Count do
if dbg.Threads.CurrentThreads[i].ThreadId <> dbg.Threads.CurrentThreads.CurrentThreadId then begin
dbg.Threads.ChangeCurrentThread(dbg.Threads.CurrentThreads[i].ThreadId);
break;
end;
loc := dbg.GetLocation;
TestTrue('loc thread main', loc.SrcLine > Src.BreakPoints['New2']);
b2 := dbg.BreakPoints.Add(loc.Address);
b2.InitialEnabled := True;
b2.Enabled := True;
If loc.SrcLine >= Src.BreakPoints['Main2']-2 then
Debugger.SetBreakPoint(Src, 'Main1')
else
Debugger.SetBreakPoint(Src, 'Main2');
Debugger.RunToNextPause(dcRun);
If loc.SrcLine >= Src.BreakPoints['Main2']-2 then begin
TestLocation('main1', 'Main1');
Debugger.BreakPointByName('Main1').Enabled := False;
end else begin
TestLocation('main2', 'Main2');
Debugger.BreakPointByName('Main2').Enabled := False;
end;
TestEquals('b1 hits', 0, b1.HitCount);
TestEquals('b2 hits', 0, b2.HitCount);
Debugger.RunToNextPause(dcRun);
TestEquals('b1 hits after', 0, b1.HitCount);
TestEquals('b2 hits after', 0, b2.HitCount);
dbg.Stop;
finally finally
Debugger.ClearDebuggerMonitors; Debugger.ClearDebuggerMonitors;
Debugger.FreeDebugger; Debugger.FreeDebugger;

View File

@ -7,7 +7,7 @@ interface
uses uses
Classes, SysUtils, fgl, TestDbgConfig, TestDbgCompilerProcess, Classes, SysUtils, fgl, TestDbgConfig, TestDbgCompilerProcess,
TestOutputLogger, TTestDebuggerClasses, TestCommonSources, LazFileUtils, TestOutputLogger, TTestDebuggerClasses, TestCommonSources, LazFileUtils,
FileUtil, DbgIntfDebuggerBase, fpcunit; FileUtil, LazLoggerBase, DbgIntfDebuggerBase, fpcunit;
type type
@ -403,6 +403,7 @@ function TTestDbgDebugger.RunToNextPause(ACmd: TDBGCommand; ATimeOut: Integer;
AWaitForInternal: Boolean): Boolean; AWaitForInternal: Boolean): Boolean;
begin begin
Result := False; Result := False;
with LazDebugger.GetLocation do DebugLnEnter('>>> RunToNextPause Starting at %s %d @ %x', [SrcFile, SrcLine, Address]);
case ACmd of case ACmd of
dcRun: LazDebugger.Run; dcRun: LazDebugger.Run;
dcStepOver: LazDebugger.StepOver; dcStepOver: LazDebugger.StepOver;
@ -414,6 +415,7 @@ begin
exit; exit;
end; end;
Result := WaitForFinishRun(ATimeOut, AWaitForInternal); Result := WaitForFinishRun(ATimeOut, AWaitForInternal);
with LazDebugger.GetLocation do DebugLnExit('<<< RunToNextPause Ending at %s %d @ %x %s', [SrcFile, SrcLine, Address, dbgs(LazDebugger.State)]);
end; end;
function TTestDbgDebugger.WaitForFinishRun(ATimeOut: Integer; function TTestDbgDebugger.WaitForFinishRun(ATimeOut: Integer;
@ -445,6 +447,7 @@ begin
InitialEnabled := True; InitialEnabled := True;
Enabled := True; Enabled := True;
end; end;
DebugLn('Inserted breakpoint %s %d id: %d', [AFileName, ALine, Result.ID]);
end; end;
function TTestDbgDebugger.SetBreakPoint(ACommonSource: TCommonSource; function TTestDbgDebugger.SetBreakPoint(ACommonSource: TCommonSource;