GDBMI debugger: more tests for LineInfo with exceptions, run error, assert

git-svn-id: trunk@56243 -
This commit is contained in:
martin 2017-10-30 00:25:45 +00:00
parent efb8df15a1
commit a43dd15a73
5 changed files with 220 additions and 26 deletions

View File

@ -1,4 +1,4 @@
program ExceptPrg; program ExceptPrg; {$INLINE OFF}
{$IFDEF TEST_WITH_HPLUS} {$IFDEF TEST_WITH_HPLUS}
{$H+} {$H+}
{$ELSE} {$ELSE}
@ -35,12 +35,78 @@ var
end; end;
{$ENDIF} {$ENDIF}
{$IFDEF TEST_EXCEPTION_AT}
procedure Bar;
begin
raise Exception.create('at1') at
get_caller_addr(get_caller_frame(get_frame)),
get_caller_frame(get_caller_frame(get_frame));
end;
procedure Bar1;
begin
Bar();
end;
procedure Bar2;
begin
Bar1();
end;
procedure BarBar;
begin
raise Exception.create('at2') at
get_caller_addr(get_frame),
get_caller_frame(get_frame);
end;
procedure BarBar1;
begin
BarBar();
end;
procedure BarBar2;
begin
BarBar1();
end;
{$ENDIF}
{$IFDEF TEST_RUNERR}
{$R+}
procedure Run;
var a: array of integer;
begin
SetLength(a, 2);
a[0] := -2;
a[1] := a[length(a)-a[0]];
end;
procedure Run1;
begin
Run();
end;
{$ENDIF}
{$IFDEF TEST_ASSERT}
{$C+}
procedure check;
begin
Assert(false, 'denied');
end;
procedure check1;
begin
check();
end;
{$ENDIF}
begin begin
{$IFnDEF TEST_NO_POINTER_VAR} {$IFnDEF TEST_NO_POINTER_VAR}
p := nil; p := nil;
{$ENDIF} {$ENDIF}
//foo; //foo;
{$IFnDEF TEST_SKIP_EXCEPTION_1}
try try
{$IFnDEF TEST_NO_EXCEPTION_VAR} {$IFnDEF TEST_NO_EXCEPTION_VAR}
x := Exception.Create('foo'); x := Exception.Create('foo');
@ -59,8 +125,28 @@ begin
end; end;
end; end;
writeln(1); writeln(1);
{$ENDIF}
{$IFDEF TEST_EXCEPTION_AT}
try
Bar2();
except end;
try
BarBar2();
except end;
{$ENDIF}
{$IFDEF TEST_RUNERR}
Run1();
{$ENDIF}
{$IFDEF TEST_ASSERT}
check1();
{$ENDIF}
{$IFnDEF TEST_NO_EXCEPTION_TYPE} {$IFnDEF TEST_NO_EXCEPTION_TYPE}
foo; foo;
{$ENDIF} {$ENDIF}
writeln(2); writeln(2);
end. end.

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<CONFIG> <CONFIG>
<ProjectOptions> <ProjectOptions>
<Version Value="9"/> <Version Value="10"/>
<PathDelim Value="\"/> <PathDelim Value="\"/>
<General> <General>
<SessionStorage Value="InProjectDir"/> <SessionStorage Value="InProjectDir"/>
@ -12,9 +12,6 @@
<i18n> <i18n>
<EnableI18N LFM="False"/> <EnableI18N LFM="False"/>
</i18n> </i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1"> <BuildModes Count="1">
<Item1 Name="Default" Default="True"/> <Item1 Name="Default" Default="True"/>
</BuildModes> </BuildModes>
@ -53,7 +50,6 @@
<Unit0> <Unit0>
<Filename Value="TestGdbmi.lpr"/> <Filename Value="TestGdbmi.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="TestGdbmi"/>
</Unit0> </Unit0>
<Unit1> <Unit1>
<Filename Value="testexception.pas"/> <Filename Value="testexception.pas"/>
@ -124,6 +120,9 @@
<OverflowChecks Value="True"/> <OverflowChecks Value="True"/>
<StackChecks Value="True"/> <StackChecks Value="True"/>
</Checks> </Checks>
<Optimizations>
<OptimizationLevel Value="0"/>
</Optimizations>
</CodeGeneration> </CodeGeneration>
<Linking> <Linking>
<Debugging> <Debugging>
@ -132,11 +131,7 @@
</Debugging> </Debugging>
</Linking> </Linking>
<Other> <Other>
<CompilerMessages>
<UseMsgFile Value="True"/>
</CompilerMessages>
<CustomOptions Value="-gt"/> <CustomOptions Value="-gt"/>
<CompilerPath Value="$(CompPath)"/>
</Other> </Other>
</CompilerOptions> </CompilerOptions>
<Debugging> <Debugging>

View File

@ -3,6 +3,7 @@
<Package Version="4"> <Package Version="4">
<PathDelim Value="\"/> <PathDelim Value="\"/>
<Name Value="GdbmiTestUtils"/> <Name Value="GdbmiTestUtils"/>
<Type Value="RunAndDesignTime"/>
<Author Value="M Friebe"/> <Author Value="M Friebe"/>
<CompilerOptions> <CompilerOptions>
<Version Value="11"/> <Version Value="11"/>
@ -10,12 +11,11 @@
<SearchPaths> <SearchPaths>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths> </SearchPaths>
<Other> <Linking>
<CompilerMessages> <Debugging>
<MsgFileName Value=""/> <DebugInfoType Value="dsDwarf2Set"/>
</CompilerMessages> </Debugging>
<CompilerPath Value="$(CompPath)"/> </Linking>
</Other>
</CompilerOptions> </CompilerOptions>
<Description Value="Test helper units for LazDebuggerGDBMI"/> <Description Value="Test helper units for LazDebuggerGDBMI"/>
<License Value="GPL2"/> <License Value="GPL2"/>
@ -39,10 +39,9 @@
</Item4> </Item4>
<Item5> <Item5>
<Filename Value="testwatchutils.pas"/> <Filename Value="testwatchutils.pas"/>
<UnitName Value="testwatchutils"/> <UnitName Value="TestWatchUtils"/>
</Item5> </Item5>
</Files> </Files>
<Type Value="RunAndDesignTime"/>
<RequiredPkgs Count="3"> <RequiredPkgs Count="3">
<Item1> <Item1>
<PackageName Value="FPCUnitTestRunner"/> <PackageName Value="FPCUnitTestRunner"/>

View File

@ -6,7 +6,8 @@ interface
uses uses
Classes, SysUtils, FileUtil, fpcunit, testutils, testregistry, LCLProc, LazLogger, Classes, SysUtils, FileUtil, fpcunit, testutils, testregistry, LCLProc, LazLogger,
LazFileUtils, DbgIntfDebuggerBase, CompileHelpers, Dialogs, TestGDBMIControl, GDBMIDebugger; // , FpGdbmiDebugger; LazFileUtils, DbgIntfDebuggerBase, CompileHelpers, Dialogs, TestGDBMIControl,
RegExpr, GDBMIDebugger; // , FpGdbmiDebugger;
// EnvironmentOpts, ExtToolDialog, TransferMacros, // EnvironmentOpts, ExtToolDialog, TransferMacros,
(* (*
@ -375,6 +376,10 @@ type
procedure AddTestSuccess(s: string; MinGdbVers: Integer = 0; AIgnoreReason: String = ''); procedure AddTestSuccess(s: string; MinGdbVers: Integer = 0; AIgnoreReason: String = '');
procedure AddTestSuccess(s: string; MinGdbVers: Integer; MinFpcVers: Integer;AIgnoreReason: String = ''); procedure AddTestSuccess(s: string; MinGdbVers: Integer; MinFpcVers: Integer;AIgnoreReason: String = '');
function TestMatches(Expected, Got: string): Boolean;
function TestMatches(Name: string; Expected, Got: string; MinGdbVers: Integer = 0; AIgnoreReason: String = ''): Boolean;
function TestMatches(Name: string; Expected, Got: string; MinGdbVers: Integer; MinFpcVers: Integer; AIgnoreReason: String = ''): Boolean;
function TestEquals(Expected, Got: string): Boolean; function TestEquals(Expected, Got: string): Boolean;
function TestEquals(Name: string; Expected, Got: string; MinGdbVers: Integer = 0; AIgnoreReason: String = ''): Boolean; function TestEquals(Name: string; Expected, Got: string; MinGdbVers: Integer = 0; AIgnoreReason: String = ''): Boolean;
function TestEquals(Name: string; Expected, Got: string; MinGdbVers: Integer; MinFpcVers: Integer; AIgnoreReason: String = ''): Boolean; function TestEquals(Name: string; Expected, Got: string; MinGdbVers: Integer; MinFpcVers: Integer; AIgnoreReason: String = ''): Boolean;
@ -1066,6 +1071,32 @@ begin
inc(FSucessCnt); inc(FSucessCnt);
end; end;
function TGDBTestCase.TestMatches(Expected, Got: string): Boolean;
begin
Result := TestMatches('', Expected, Got);
end;
function TGDBTestCase.TestMatches(Name: string; Expected, Got: string;
MinGdbVers: Integer; AIgnoreReason: String): Boolean;
begin
Result := TestMatches(Name, Expected, Got, MinGdbVers, 0, AIgnoreReason);
end;
function TGDBTestCase.TestMatches(Name: string; Expected, Got: string;
MinGdbVers: Integer; MinFpcVers: Integer; AIgnoreReason: String): Boolean;
var
rx: TRegExpr;
begin
rx := TRegExpr.Create;
rx.ModifierI := true;
rx.Expression := Expected;
Result := rx.Exec(Got);
FreeAndNil(rx);
if Result
then AddTestSuccess(Name + ': Expected to fail with, but succeded, Got "'+Got+'"', MinGdbVers, MinFpcVers, AIgnoreReason)
else AddTestError(Name + ': Expected "'+Expected+'", Got "'+Got+'"', MinGdbVers, MinFpcVers, AIgnoreReason);
end;
function TGDBTestCase.TestEquals(Expected, Got: string): Boolean; function TGDBTestCase.TestEquals(Expected, Got: string): Boolean;
begin begin
Result := TestEquals('', Expected, Got); Result := TestEquals('', Expected, Got);

View File

@ -21,6 +21,7 @@ type
FGotExceptClass: String; FGotExceptClass: String;
FGotExceptMsg: String; FGotExceptMsg: String;
FGotExceptType: TDBGExceptionType; FGotExceptType: TDBGExceptionType;
FGotExceptionLocation: TDBGLocationRec;
procedure DoDebuggerException(Sender: TObject; procedure DoDebuggerException(Sender: TObject;
const AExceptionType: TDBGExceptionType; const AExceptionType: TDBGExceptionType;
@ -61,6 +62,7 @@ begin
FGotExceptClass := AExceptionClass; FGotExceptClass := AExceptionClass;
FGotExceptMsg := AExceptionText; FGotExceptMsg := AExceptionText;
FGotExceptType := AExceptionType; FGotExceptType := AExceptionType;
FGotExceptionLocation := AExceptionLocation;
AContinue := False; AContinue := False;
end; end;
@ -77,26 +79,106 @@ var
begin begin
if SkipTest then exit; if SkipTest then exit;
if not TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf('TTestExceptionOne')] then exit; if not TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf('TTestExceptionOne')] then exit;
if not TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf(' TTestException')] then exit;
ClearTestErrors; ClearTestErrors;
TestCompile(AppDir + 'ExceptPrg.pas', TestExeName, '', '-gt -gh'); TstName := 'All';
TestCompile(AppDir + 'ExceptPrg.pas', TestExeName, '_raise_at', '-gt -gh -dTEST_EXCEPTION_AT');
try try
FGotExceptCount := 0; TstName := 'all'; FGotExceptCount := 0;
dbg := StartGDB(AppDir, TestExeName); dbg := StartGDB(AppDir, TestExeName);
dbg.OnException := @DoDebuggerException; dbg.OnException := @DoDebuggerException;
dbg.Run; dbg.Run;
TstName := 'All - raise';
TestEquals(TstName+' Got 1 exception', 1, FGotExceptCount); TestEquals(TstName+' Got 1 exception', 1, FGotExceptCount);
TestEquals(TstName+' Got class', 'Exception', FGotExceptClass); TestEquals(TstName+' Got class', 'Exception', FGotExceptClass);
TestEquals(TstName+' Got msg', 'foo', FGotExceptMsg, 060000); TestEquals(TstName+' Got msg', 'foo', FGotExceptMsg, 060000);
TestEquals(TstName+' Got location Line', 113, FGotExceptionLocation.SrcLine);
TestMatches(TstName+' Got location File', 'ExceptPrg\.pas$', FGotExceptionLocation.SrcFile);
TestMatches(TstName+' Got location Proc', '^main$', FGotExceptionLocation.FuncName);
TestTrue(TstName+' Got type', FGotExceptType = deInternal);
dbg.Run; dbg.Run;
TestEquals(TstName+' Got 2nd exception', 2, FGotExceptCount); TstName := 'All - raise at 2 down';
TestEquals(TstName+' Got exception 2', 2, FGotExceptCount);
TestEquals(TstName+' Got class', 'Exception', FGotExceptClass);
TestEquals(TstName+' Got msg', 'at1', FGotExceptMsg, 060000);
TestEquals(TstName+' Got location Line', 53, FGotExceptionLocation.SrcLine);
TestMatches(TstName+' Got location File', 'ExceptPrg\.pas$', FGotExceptionLocation.SrcFile);
TestMatches(TstName+' Got location Proc', '^Bar2$', FGotExceptionLocation.FuncName);
TestTrue(TstName+' Got type', FGotExceptType = deInternal);
dbg.Run; dbg.Run;
TestEquals(TstName+' Got no more exception', 2, FGotExceptCount); TstName := 'All - raise at 1 down';
TestEquals(TstName+' Got exception 3', 3, FGotExceptCount);
TestEquals(TstName+' Got class', 'Exception', FGotExceptClass);
TestEquals(TstName+' Got msg', 'at2', FGotExceptMsg, 060000);
TestEquals(TstName+' Got location Line', 65, FGotExceptionLocation.SrcLine);
TestMatches(TstName+' Got location File', 'ExceptPrg\.pas$', FGotExceptionLocation.SrcFile);
TestMatches(TstName+' Got location Proc', '^BarBar1$', FGotExceptionLocation.FuncName);
TestTrue(TstName+' Got type', FGotExceptType = deInternal);
dbg.Run;
TstName := 'All - raise subclass';
TestEquals(TstName+'Got exception 4', 4, FGotExceptCount);
TestEquals(TstName+' Got class', 'MyESome', FGotExceptClass); TestEquals(TstName+' Got class', 'MyESome', FGotExceptClass);
// not yet MakePrintable // not yet MakePrintable
//TestEquals(TstName+' Got msg', 'abc üü {[''''[{ \n\t''#13#9''#', FGotExceptMsg, 050300); //TestEquals(TstName+' Got msg', 'abc üü {[''''[{ \n\t''#13#9''#', FGotExceptMsg, 050300);
TestEquals(TstName+' Got msg', 'abc üü {[''[{ \n\t'#13#9'#', FGotExceptMsg, 050300); TestEquals(TstName+' Got msg', 'abc üü {[''[{ \n\t'#13#9'#', FGotExceptMsg, 050300);
TestEquals(TstName+' Got location Line', 34, FGotExceptionLocation.SrcLine);
TestMatches(TstName+' Got location File', 'ExceptPrg\.pas$', FGotExceptionLocation.SrcFile);
TestMatches(TstName+' Got location Proc', '^foo$', FGotExceptionLocation.FuncName);
TestTrue(TstName+' Got type', FGotExceptType = deInternal);
dbg.Run;
TestEquals(TstName+' Got no more exception', 4, FGotExceptCount);
dbg.Stop;
finally
dbg.Done;
CleanGdb;
dbg.Free;
end;
TstName := 'RunError';
TestCompile(AppDir + 'ExceptPrg.pas', TestExeName, '_runerr', '-gt -gh -dTEST_SKIP_EXCEPTION_1 -dTEST_RUNERR');
try
FGotExceptCount := 0;
dbg := StartGDB(AppDir, TestExeName);
dbg.OnException := @DoDebuggerException;
dbg.Run;
TestEquals(TstName+' Got run err', 1, FGotExceptCount);
TestMatches(TstName+' Got class', 'RunError', FGotExceptClass);
//TestEquals(TstName+' Got msg', 'at2', FGotExceptMsg, 060000);
TestEquals(TstName+' Got location Line', 81, FGotExceptionLocation.SrcLine);
TestMatches(TstName+' Got location File', 'ExceptPrg\.pas$', FGotExceptionLocation.SrcFile);
TestMatches(TstName+' Got location Proc', '^Run$', FGotExceptionLocation.FuncName);
TestTrue(TstName+' Got type', FGotExceptType = deRunError);
dbg.Stop;
finally
dbg.Done;
CleanGdb;
dbg.Free;
end;
TstName := 'Assert';
TestCompile(AppDir + 'ExceptPrg.pas', TestExeName, '_assert', '-gt -gh -dTEST_SKIP_EXCEPTION_1 -dTEST_ASSERT');
try
FGotExceptCount := 0;
dbg := StartGDB(AppDir, TestExeName);
dbg.OnException := @DoDebuggerException;
dbg.Run;
TestEquals(TstName+' Got Assert', 1, FGotExceptCount);
TestMatches(TstName+' Got class', 'EAssertionFailed', FGotExceptClass);
TestMatches(TstName+' Got msg', 'denied', FGotExceptMsg, 060000);
// TestEquals(TstName+' Got location Line', 94, FGotExceptionLocation.SrcLine);
TestMatches(TstName+' Got location File', 'ExceptPrg\.pas$', FGotExceptionLocation.SrcFile);
// TestMatches(TstName+' Got location Proc', '^check$', FGotExceptionLocation.FuncName);
TestTrue(TstName+' Got type', FGotExceptType = deInternal);
dbg.Stop; dbg.Stop;
finally finally
dbg.Done; dbg.Done;
@ -243,6 +325,7 @@ var
begin begin
if SkipTest then exit; if SkipTest then exit;
if not TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf('TTestExceptionOne')] then exit; if not TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf('TTestExceptionOne')] then exit;
if not TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf(' TTestExceptionStepOut')] then exit;
ClearTestErrors; ClearTestErrors;
TestCompile(AppDir + 'ExceptPrgStep.pas', TestExeName, '', ''); TestCompile(AppDir + 'ExceptPrgStep.pas', TestExeName, '', '');
@ -289,7 +372,7 @@ end;
initialization initialization
RegisterDbgTest(TTestExceptionOne); RegisterDbgTest(TTestExceptionOne);
RegisterTestSelectors(['TTestExceptionOne' RegisterTestSelectors(['TTestExceptionOne', ' TTestException', ' TTestExceptionStepOut'
]); ]);
end. end.