FpDebug: fix array with struct / tests

git-svn-id: trunk@44531 -
This commit is contained in:
martin 2014-03-28 00:21:26 +00:00
parent fc89c8dc99
commit b9283584dc
8 changed files with 270 additions and 107 deletions

View File

@ -823,6 +823,7 @@ type
FDataAddressDone: Boolean;
protected
procedure Reset; override;
procedure ClearMembers;
function GetFieldFlags: TFpDbgValueFieldFlags; override;
function GetKind: TDbgSymbolKind; override;
function GetAsCardinal: QWord; override;
@ -2565,6 +2566,16 @@ procedure TFpDbgDwarfValueStructTypeCast.Reset;
begin
inherited Reset;
FDataAddressDone := False;
ClearMembers;
end;
procedure TFpDbgDwarfValueStructTypeCast.ClearMembers;
var
i: Integer;
begin
if FMembers <> nil then
for i := 0 to FMembers.Count - 1 do
TDbgDwarfValueIdentifier(FMembers[i]).StructureValueInfo := nil;
end;
function TFpDbgDwarfValueStructTypeCast.GetFieldFlags: TFpDbgValueFieldFlags;
@ -2679,12 +2690,8 @@ begin
end;
destructor TFpDbgDwarfValueStructTypeCast.Destroy;
var
i: Integer;
begin
if FMembers <> nil then
for i := 0 to FMembers.Count - 1 do
TDbgDwarfValueIdentifier(FMembers[i]).StructureValueInfo := nil;
ClearMembers;
FreeAndNil(FMembers);
inherited Destroy;
end;
@ -2717,6 +2724,7 @@ begin
if not HasTypeCastInfo then
exit;
// TODO: Why store them all in list? They are hold by the type
tmp := FTypeCastTargetType.Member[AIndex];
if (tmp <> nil) then begin
assert((tmp is TDbgDwarfValueIdentifier), 'TDbgDwarfStructTypeCastSymbolValue.GetMemberByName'+DbgSName(tmp));
@ -2857,6 +2865,9 @@ end;
procedure TFpDbgDwarfValue.SetStructureValue(AValue: TFpDbgDwarfValue);
begin
if FStructureValue <> nil then
Reset;
if FStructureValue = AValue then
exit;

View File

@ -1,11 +1,78 @@
unit TestWatchesUnitArray;
{$mode objfpc}{$H+}{$NOTES off}
interface
uses sysutils, types;
procedure Test1;
type
TArrayClass1 = class;
TArrayRec = packed record
FieldInt1, FieldInt2: Integer;
FieldDynInt1: array of Integer;
FieldStatInt1: array [4..9] of Integer;
FieldByte1: Byte;
end;
implementation
TArrayDynInt = array of Integer;
TArrayDynClass = array of TArrayClass1;
TArrayDynRec = array of TArrayRec;
TArrayDynDynInt = array of array of Integer;
TArrayDynDynClass = array of array of TArrayClass1;
TArrayDynDynRec = array of array of TArrayRec;
TArrayDynStatInt = array of array [1..5] of Integer;
TArrayDynStatClass = array of array [1..5] of TArrayClass1;
TArrayDynStatRec = array of array [1..5] of TArrayRec;
TArrayStatInt = array [-2..5] of Integer;
TArrayStatClass = array [-2..5] of TArrayClass1;
TArrayStatRec = array [-2..5] of TArrayRec;
TArrayStatStatInt = array [-9..-5] of array [1..5] of Integer;
TArrayStatStatClass = array [-9..-5] of array [1..5] of TArrayClass1;
TArrayStatStatRec = array [-9..-5] of array [1..5] of TArrayRec;
TArrayStatDynInt = array [-9..-5] of array of Integer;
TArrayStatDynClass = array [-9..-5] of array of TArrayClass1;
TArrayStatDynRec = array [-9..-5] of array of TArrayRec;
{ TArrayClass1 }
TArrayClass1 = class
public
FieldInt1, FieldInt2: Integer;
FieldDynAInt1: array of Integer;
FieldStatAInt1: array [4..9] of Integer;
FieldDynInt1: TArrayDynInt;
FieldDynClass1: TArrayDynClass;
FieldDynRec1: TArrayDynRec;
FieldDynDynInt1: TArrayDynDynInt;
FieldDynDynClass1: TArrayDynDynClass;
FieldDynDynRec1: TArrayDynDynRec;
FieldDynStatInt1: TArrayDynStatInt;
FieldDynStatClass1: TArrayDynStatClass;
FieldDynStatRec1: TArrayDynStatRec;
FieldStatInt1: TArrayStatInt;
FieldStatClass1: TArrayStatClass;
FieldStatRec1: TArrayStatRec;
FieldStatStatInt1: TArrayStatStatInt;
FieldStatStatClass1: TArrayStatStatClass;
FieldStatStatRec1: TArrayStatStatRec;
FieldStatDynInt1: TArrayStatDynInt;
FieldStatDynClass1: TArrayStatDynClass;
FieldStatDynRec1: TArrayStatDynRec;
procedure Test1Method;
end;
var
ArrayGlob_DynInt1, ArrayGlob_DynInt2: array of Integer;
@ -13,6 +80,12 @@ var
ArrayGlob_StatInt2: array [-4..9] of Integer;
procedure Test1;
implementation
{ TArrayClass1 }
procedure TArrayClass1.Test1Method;
begin
ArrayGlob_DynInt2 := nil;
@ -37,8 +110,78 @@ begin
ArrayGlob_StatInt2[1] := 3305;
ArrayGlob_DynInt1[9] := -5511; // BREAK
SetLength(FieldDynInt1, 5);
FieldDynInt1[0] := 100;
FieldDynInt1[1] := 101;
FieldDynInt1[2] := 102;
SetLength(FieldDynClass1, 6);
FieldDynClass1[0] := TArrayClass1.Create;
FieldDynClass1[0].FieldInt1 := 98700;
FieldDynClass1[0].FieldInt2 := 98701;
SetLength(FieldDynClass1[0].FieldDynAInt1, 2);
FieldDynClass1[0].FieldDynAInt1[0] := 9900;
FieldDynClass1[0].FieldDynAInt1[1] := 9901;
FieldDynClass1[1] := TArrayClass1.Create;
FieldDynClass1[1].FieldInt1 := 88700;
FieldDynClass1[1].FieldInt2 := 88701;
SetLength(FieldDynClass1[1].FieldDynAInt1, 2);
FieldDynClass1[1].FieldDynAInt1[0] := 8900;
FieldDynClass1[1].FieldDynAInt1[1] := 8901;
FieldDynClass1[2] := TArrayClass1.Create;
FieldDynClass1[2].FieldInt1 := 78700;
FieldDynClass1[2].FieldInt2 := 78701;
SetLength(FieldDynClass1[2].FieldDynAInt1, 3);
FieldDynClass1[2].FieldDynAInt1[0] := 7900;
FieldDynClass1[2].FieldDynAInt1[1] := 7901;
FieldDynClass1[2].FieldDynAInt1[2] := 7902;
SetLength(FieldDynRec1, 7);
FieldDynRec1[0].FieldInt1 := 200;
FieldDynRec1[0].FieldInt2 := 201;
FieldDynRec1[1].FieldInt1 := 210;
FieldDynRec1[1].FieldInt2 := 211;
FieldDynRec1[2].FieldInt1 := 220;
FieldDynRec1[2].FieldInt2 := 221;
SetLength(FieldDynDynInt1, 5,3);
FieldDynDynInt1[0][0] := 1000;
FieldDynDynInt1[0][1] := 1001;
FieldDynDynInt1[0][2] := 1002;
FieldDynDynInt1[0][3] := 1003;
FieldDynDynInt1[1][0] := 1010;
FieldDynDynInt1[1][1] := 1011;
SetLength(FieldDynDynClass1, 5,4);
SetLength(FieldDynDynRec1, 5,6);
SetLength(FieldDynStatInt1, 3);
SetLength(FieldDynStatClass1, 4);
SetLength(FieldDynStatRec1, 5);
//SetLength(FieldStatInt1, );
//SetLength(FieldStatClass1, );
//SetLength(FieldStatRec1, );
//SetLength(FieldStatStatInt1, );
//SetLength(FieldStatStatClass1, );
//SetLength(FieldStatStatRec1, );
SetLength(FieldStatDynInt1[-9], 3);
SetLength(FieldStatDynClass1[-9], 3);
SetLength(FieldStatDynRec1[-9], 3);
ArrayGlob_DynInt1[9] := -5511; // BREAK
end;
procedure Test1;
var
ArrayClass1: TArrayClass1;
begin
ArrayClass1 := TArrayClass1.Create;
ArrayClass1.Test1Method;
end;
end.

View File

@ -1,4 +1,5 @@
unit TestWatchesUnitSimple;
{$mode objfpc}{$H+}{$NOTES off}
interface
uses sysutils, types;
@ -167,7 +168,10 @@ begin
SimpleGlob_QWord4 := high(QWord);
SimpleGlob_QWord5 := low(QWord);
SimpleGlob_Single1 := 99.2;
SimpleGlob_Double1 := 199.3;
SimpleGlob_Ext1 := 299.4;
SimpleGlob_Comp1 := -2;
SimplePArg_Int1 := @SimpleArg_Int1;

View File

@ -1,4 +1,5 @@
unit TestWatchesUnitStruct;
{$mode objfpc}{$H+}{$NOTES off}
interface
uses sysutils, types;

View File

@ -10,11 +10,11 @@ uses
GDBMIDebugger;
const
BREAK_LINE_TestWatchesUnitSimple_1 = 178;
BREAK_LINE_TestWatchesUnitSimple_2 = 185;
BREAK_LINE_TestWatchesUnitSimple_3 = 192;
BREAK_LINE_TestWatchesUnitSimple_1 = 182;
BREAK_LINE_TestWatchesUnitSimple_2 = 189;
BREAK_LINE_TestWatchesUnitSimple_3 = 196;
BREAK_LINE_TestWatchesUnitArray = 38;
BREAK_LINE_TestWatchesUnitArray = 176;
type
@ -25,11 +25,6 @@ type
FWatches: TWatches;
ExpectBreakSimple_1: TWatchExpectationArray;
FSimplePArg_Int1, FAddrSimpleArg_Int1,
FSimplePVArg_Int1, FAddrSimpleVArg_Int1,
FSimplePLocal_Int1, FAddrSimpleLocal_Int1,
FSimplePGlob_Int1, FAddrSimpleGlob_Int1: PWatchExpectation;
ExpectBreakSimple_2: TWatchExpectationArray;
ExpectBreakSimple_3: TWatchExpectationArray;
@ -54,6 +49,8 @@ type
function AddSimpleInt(AnExpr: string; AMtch: Int64; ATpNm: string): PWatchExpectation;
function AddSimpleUInt(AnExpr: string; AMtch: QWord; ATpNm: string): PWatchExpectation;
procedure AdjustExpectToAddress(AWatchExp: PWatchExpectation);
procedure AddExpectSimple_1;
procedure AddExpectSimple_2;
procedure AddExpectSimple_3;
@ -109,10 +106,22 @@ begin
end;
{ TTestWatches }
procedure TTestWatches.AdjustExpectToAddress(AWatchExp: PWatchExpectation);
var
OtherWatchExp: PWatchExpectation;
s: String;
st: TSymbolType;
begin
OtherWatchExp := PWatchExpectation(AWatchExp^.UserData);
if OtherWatchExp = nil then exit;;
s := OtherWatchExp^.TheWatch.Values[1,0].Value;
delete(s, 1, pos('$', s) - 1); delete(s, pos(')', s), 99);
for st := low(TSymbolType) to high(TSymbolType) do
AWatchExp^.Result[st].ExpMatch := '\'+s;
end;
procedure TTestWatches.DoDbgOutput(Sender: TObject; const AText: String);
begin
inherited DoDbgOutput(Sender, AText);
@ -178,9 +187,11 @@ var
i: Integer;
s, s2, s2def: String;
j: Integer;
r: PWatchExpectation;
begin
FCurrentExpect := @ExpectBreakSimple_1;
{%region Int?Cardinal types}
for i := 0 to 3 do begin
s2def := '';
case i of
@ -338,26 +349,34 @@ begin
AddSimpleInt(Format(s, ['SimpleField_Word1']), j+16, 'Word');
AddSimpleInt(Format(s, ['SimpleField_DWord1']), j+17, 'LongWord');
AddSimpleInt(Format(s, ['SimpleField_QWord1']), j+18, 'QWord');
//AddSimpleInt(Format(s, ['SimpleField_Single1']), 15, 'Byte');
//AddSimpleInt(Format(s, ['SimpleField_Double1']), 15, 'Byte');
//AddSimpleInt(Format(s, ['SimpleField_Ext1']), 15, 'Byte');
end;
{%region}
s := '%s';
AddFmtDef(Format(s, ['SimpleGlob_Single1']), '^99\.(2|19)', skSimple, '', [fTpMtch]);
AddFmtDef(Format(s, ['SimpleGlob_Double1']), '^199\.(3|29)', skSimple, '', [fTpMtch]);
AddFmtDef(Format(s, ['SimpleGlob_Ext1']), '^299\.(4|39)', skSimple, '', [fTpMtch]);
AddSimpleInt(Format(s, ['SimpleGlob_Comp1']), -2, '');
{%region AddressOf / Var param, hidden pointer}
//SimplePArg_Int1, SimplePVArg_Int1, SimplePLocal_Int1, SimplePGlob_Int1: PLongInt;
FSimplePArg_Int1 := AddFmtDef('SimplePArg_Int1', '\$[0-9A-F]', skPointer, '');
FAddrSimpleArg_Int1 := AddFmtDef('@SimpleArg_Int1', 'replaceme', skPointer, '');
r := AddFmtDef('@SimpleArg_Int1', 'replaceme', skPointer, '');
r^.OnBeforeTest := @AdjustExpectToAddress;
r^.UserData := AddFmtDef('SimplePArg_Int1', '\$[0-9A-F]', skPointer, '');
FSimplePVArg_Int1 := AddFmtDef('SimplePVArg_Int1', '\$[0-9A-F]', skPointer, '');
FAddrSimpleVArg_Int1 := AddFmtDef('@SimpleVArg_Int1', 'replaceme', skPointer, '');
UpdResMinFpc(FAddrSimpleVArg_Int1, stSymAll, 020600);
r := AddFmtDef('@SimpleVArg_Int1', 'replaceme', skPointer, '');
r^.OnBeforeTest := @AdjustExpectToAddress;
r^.UserData := AddFmtDef('SimplePVArg_Int1', '\$[0-9A-F]', skPointer, '');
UpdResMinFpc(r, stSymAll, 020600);
FSimplePLocal_Int1 := AddFmtDef('SimplePLocal_Int1', '\$[0-9A-F]', skPointer, '');
FAddrSimpleLocal_Int1 := AddFmtDef('@SimpleLocal_Int1', 'replaceme', skPointer, '');
r := AddFmtDef('@SimpleLocal_Int1', 'replaceme', skPointer, '');
r^.OnBeforeTest := @AdjustExpectToAddress;
r^.UserData := AddFmtDef('SimplePLocal_Int1', '\$[0-9A-F]', skPointer, '');
r := AddFmtDef('@SimpleGlob_Int1', 'replaceme', skPointer, '');
r^.OnBeforeTest := @AdjustExpectToAddress;
r^.UserData := AddFmtDef('SimplePGlob_Int1', '\$[0-9A-F]', skPointer, '');
FSimplePGlob_Int1 := AddFmtDef('SimplePGlob_Int1', '\$[0-9A-F]', skPointer, '');
FAddrSimpleGlob_Int1 := AddFmtDef('@SimpleGlob_Int1', 'replaceme', skPointer, '');
{%region}
end;
@ -437,6 +456,7 @@ begin
AddSimpleInt('ArrayGlob_DynInt1[0]', 5511, M_Int);
AddSimpleInt('ArrayGlob_DynInt1[19]', 5500, M_Int);
AddFmtDef('ArrayGlob_StatInt1', '^[\(L].*6600, 6601, 6602',
skArray, '', [fTpMtch]);
AddSimpleInt('ArrayGlob_StatInt1[4]', 6600, M_Int);
@ -445,27 +465,43 @@ begin
AddFmtDef('ArrayGlob_StatInt1[10]', '', skSimple, M_Int, [fTpMtch]); // Just do not crash
AddFmtDef('ArrayGlob_StatInt1[-1]', '', skSimple, M_Int, [fTpMtch]); // Just do not crash
AddFmtDef('ArrayGlob_StatInt2', '^[\(L].*3300, 3301, 3302',
skArray, '', [fTpMtch]);
AddSimpleInt('ArrayGlob_StatInt2[-4]', 3300, M_Int);
AddSimpleInt('ArrayGlob_StatInt2[0]', 3304, M_Int);
// EMPTY dyn array = nil
AddFmtDef('FieldDynInt1', '^[\(L].*100, 101, 102', skArray, '', [fTpMtch]);
AddFmtDef('FieldDynClass1', '^[\(L].*?'+
'\(.*FIELDINT1 = 98700;.*FIELDINT2 = 98701;.*FIELDDYNAINT1 = \(9900, 9901\);.*\), ' +
'\(.*FIELDINT1 = 88700;.*FIELDINT2 = 88701;.*FIELDDYNAINT1 = \(8900, 8901\);.*\), ' +
'\(.*FIELDINT1 = 78700;.*FIELDINT2 = 78701;.*FIELDDYNAINT1 = \(7900, 7901, 7902\);.*\)',
skArray, '', [fTpMtch]);
end;
procedure TTestWatches.RunTestWatches(NamePreFix: String; TestExeName, ExtraOpts: String;
UsedUnits: array of TUsesDir);
var
dbg: TGDBMIDebugger;
Only: Integer;
OnlyName, OnlyNamePart: String;
procedure SetBreak(AFileName: String; ALineNum: Integer);
begin
with dbg.BreakPoints.Add(AFileName, ALineNum) do begin
InitialEnabled := True;
Enabled := True;
end;
end;
var
i: Integer;
WListSimple1, WListSimple2, WListSimple3,
WListArray1: TTestWatchArray;
st: TSymbolType;
s: String;
@ -497,30 +533,18 @@ begin
dbg := StartGDB(AppDir, TestExeName);
FWatches := Watches.Watches;
with dbg.BreakPoints.Add('TestWatchesUnitSimple.pas', BREAK_LINE_TestWatchesUnitSimple_1) do begin
InitialEnabled := True;
Enabled := True;
end;
with dbg.BreakPoints.Add('TestWatchesUnitSimple.pas', BREAK_LINE_TestWatchesUnitSimple_2) do begin
InitialEnabled := True;
Enabled := True;
end;
with dbg.BreakPoints.Add('TestWatchesUnitSimple.pas', BREAK_LINE_TestWatchesUnitSimple_3) do begin
InitialEnabled := True;
Enabled := True;
end;
with dbg.BreakPoints.Add('TestWatchesUnitArray.pas', BREAK_LINE_TestWatchesUnitArray) do begin
InitialEnabled := True;
Enabled := True;
end;
SetBreak('TestWatchesUnitSimple.pas', BREAK_LINE_TestWatchesUnitSimple_1);
SetBreak('TestWatchesUnitSimple.pas', BREAK_LINE_TestWatchesUnitSimple_2);
SetBreak('TestWatchesUnitSimple.pas', BREAK_LINE_TestWatchesUnitSimple_3);
SetBreak('TestWatchesUnitArray.pas', BREAK_LINE_TestWatchesUnitArray);
if dbg.State = dsError then
Fail(' Failed Init');
AddWatches(ExpectBreakSimple_1, WListSimple1, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakSimple_2, WListSimple2, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakSimple_3, WListSimple3, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakArray_1, WListArray1, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakSimple_1, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakSimple_2, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakSimple_3, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakArray_1, FWatches, Only, OnlyName, OnlyNamePart);
(* Start debugging *)
dbg.ShowConsole := True;
@ -531,45 +555,25 @@ begin
TestTrue('Hit BREAK_LINE_TestWatchesUnitSimple_1', False);
exit;
end;
(* Hit first breakpoint: *)
for st := low(TSymbolType) to high(TSymbolType) do begin
s := FSimplePArg_Int1^.TheWatch.Values[1,0].Value;
delete(s, 1, pos('$', s) - 1); delete(s, pos(')', s), 99);
FAddrSimpleArg_Int1^.Result[st].ExpMatch := '\'+s;
s := FSimplePVArg_Int1^.TheWatch.Values[1,0].Value;
delete(s, 1, pos('$', s) - 1); delete(s, pos(')', s), 99);
FAddrSimpleVArg_Int1^.Result[st].ExpMatch := '\'+s;
s := FSimplePGlob_Int1^.TheWatch.Values[1,0].Value;
delete(s, 1, pos('$', s) - 1); delete(s, pos(')', s), 99);
FAddrSimpleGlob_Int1^.Result[st].ExpMatch := '\'+s;
s := FSimplePLocal_Int1^.TheWatch.Values[1,0].Value;
delete(s, 1, pos('$', s) - 1); delete(s, pos(')', s), 99);
FAddrSimpleLocal_Int1^.Result[st].ExpMatch := '\'+s;
end;
TestWatchList('Simple1',ExpectBreakSimple_1, WListSimple1, dbg, Only, OnlyName, OnlyNamePart);
TestWatchList('Simple1',ExpectBreakSimple_1, dbg, Only, OnlyName, OnlyNamePart);
dbg.Run;
if not TestTrue('State=Pause', dbg.State = dsPause) then begin
if not TestTrue('State=Pause', dbg.State = dsPause) then begin
TestTrue('Hit BREAK_LINE_TestWatchesUnitSimple', False);
exit;
end;
(* Hit 2nd Simple breakpoint: *)
TestWatchList('Simple2',ExpectBreakSimple_2, WListSimple2, dbg, Only, OnlyName, OnlyNamePart);
TestWatchList('Simple2',ExpectBreakSimple_2, dbg, Only, OnlyName, OnlyNamePart);
dbg.Run;
if not TestTrue('State=Pause', dbg.State = dsPause) then begin
if not TestTrue('State=Pause', dbg.State = dsPause) then begin
TestTrue('Hit BREAK_LINE_TestWatchesUnitSimple', False);
exit;
end;
(* Hit 3rd Simlpe breakpoint: *)
TestWatchList('Simple3',ExpectBreakSimple_3, WListSimple3, dbg, Only, OnlyName, OnlyNamePart);
TestWatchList('Simple3',ExpectBreakSimple_3, dbg, Only, OnlyName, OnlyNamePart);
// array
@ -582,7 +586,7 @@ begin
end;
(* Hit 11st Array breakpoint: *)
TestWatchList('Array1',ExpectBreakArray_1, WListArray1, dbg, Only, OnlyName, OnlyNamePart);
TestWatchList('Array1',ExpectBreakArray_1, dbg, Only, OnlyName, OnlyNamePart);
dbg.Run;

View File

@ -94,7 +94,7 @@ begin
{$ENDIF}
FpcBuild.ShowWindow := swoHIDE;
CmdLine := FpcExe + ' -MObjFPC -FUlib -o'+ ExeName + ' ' + FpcOpts + ' ' + PrgName;
CmdLine := FpcExe + ' -B -MObjFPC -FUlib -o'+ ExeName + ' ' + FpcOpts + ' ' + PrgName;
debugln(['**** running compiler: ', CmdLine]);
FpcBuild.CommandLine := CmdLine;
FCommandLine := CmdLine;

View File

@ -85,6 +85,8 @@ const
WatchExpFlagSIgnTpName = [IgnStabs, IgnDwrf, IgnDwrf2, IgnDwrf2IfNoSet, IgnDwrf3, IgnTpName, IgnTpNameDw, IgnTpNameDw2, IgnTpNameDw3, IgnTpNameSt];
type
PWatchExpectation= ^TWatchExpectation;
TWatchExpectOnBeforeTest = procedure(AWatchExp: PWatchExpectation) of object;
TFullTypeMemberExpectationResult = record
Name: string;
@ -94,7 +96,6 @@ type
end;
TFullTypeMemberExpectationResultArray = array of TFullTypeMemberExpectationResult;
PWatchExpectation= ^TWatchExpectation;
TWatchExpectationResult = record
ExpMatch: string;
ExpKind: TDBGSymbolKind;
@ -111,22 +112,23 @@ type
EvaluateFlags: TDBGEvaluateFlags;
StackFrame: Integer;
Result: Array [TSymbolType] of TWatchExpectationResult;
TheWatch: TTestWatch;
UserData: Pointer;
OnBeforeTest: TWatchExpectOnBeforeTest;
end;
TWatchExpectationArray = array of TWatchExpectation;
TTestWatchArray = Array of TTestWatch;
{ TTestWatchesBase }
TTestWatchesBase = class(TGDBTestCase)
protected
procedure TestWatch(Name: String; ADbg: TDebuggerIntf;
AWatch: TTestWatch; Data: TWatchExpectation; WatchValue: String = '');
procedure AddWatches(ExpectList: TWatchExpectationArray; var WatchList: TTestWatchArray;
procedure AddWatches(ExpectList: TWatchExpectationArray;
AWatches: TWatches;
Only: Integer; OnlyName, OnlyNamePart: String);
procedure TestWatchList(AName: String; ExpectList: TWatchExpectationArray; WatchList: TTestWatchArray;
procedure TestWatchList(AName: String; ExpectList: TWatchExpectationArray;
ADbg: TDebuggerIntf;
Only: Integer; OnlyName, OnlyNamePart: String);
end;
@ -398,6 +400,8 @@ var
begin
if not TestTrue('Dbg did NOT enter dsError', ADbg.State <> dsError) then exit;
if Data.OnBeforeTest <> nil then Data.OnBeforeTest(@Data);
rx := nil;
Stack := Data.StackFrame;
DataRes := Data.Result[SymbolType];
@ -513,9 +517,8 @@ begin
end;
procedure TTestWatchesBase.AddWatches(ExpectList: TWatchExpectationArray;
var WatchList: TTestWatchArray; AWatches: TWatches; Only: Integer; OnlyName,
OnlyNamePart: String);
procedure TTestWatchesBase.AddWatches(ExpectList: TWatchExpectationArray; AWatches: TWatches;
Only: Integer; OnlyName, OnlyNamePart: String);
function SkipTest(const Data: TWatchExpectation): Boolean;
begin
@ -535,22 +538,20 @@ procedure TTestWatchesBase.AddWatches(ExpectList: TWatchExpectationArray;
var
i: Integer;
begin
SetLength(WatchList, length(ExpectList));
for i := low(ExpectList) to high(ExpectList) do begin
if not MatchOnly(ExpectList[i], i) then continue;
if not SkipTest(ExpectList[i]) then begin
WatchList[i] := TTestWatch.Create(AWatches);
WatchList[i].Expression := ExpectList[i].Expression;
WatchList[i].DisplayFormat := ExpectList[i].DspFormat;
WatchList[i].EvaluateFlags:= ExpectList[i].EvaluateFlags;
WatchList[i].enabled := True;
ExpectList[i].TheWatch := WatchList[i];
ExpectList[i].TheWatch := TTestWatch.Create(AWatches);
ExpectList[i].TheWatch.Expression := ExpectList[i].Expression;
ExpectList[i].TheWatch.DisplayFormat := ExpectList[i].DspFormat;
ExpectList[i].TheWatch.EvaluateFlags:= ExpectList[i].EvaluateFlags;
ExpectList[i].TheWatch.enabled := True;
end;
end;
end;
procedure TTestWatchesBase.TestWatchList(AName: String; ExpectList: TWatchExpectationArray;
WatchList: TTestWatchArray; ADbg: TDebuggerIntf; Only: Integer; OnlyName,
ADbg: TDebuggerIntf; Only: Integer; OnlyName,
OnlyNamePart: String);
function SkipTest(const Data: TWatchExpectation): Boolean;
@ -574,7 +575,7 @@ begin
for i := low(ExpectList) to high(ExpectList) do begin
if not MatchOnly(ExpectList[i], i) then continue;
if not SkipTest(ExpectList[i]) then
TestWatch(AName + ' '+IntToStr(i)+' ', ADbg, WatchList[i], ExpectList[i]);
TestWatch(AName + ' '+IntToStr(i)+' ', ADbg, ExpectList[i].TheWatch, ExpectList[i]);
end;
end;

View File

@ -1688,7 +1688,6 @@ var
var
i: Integer;
WList, WListSub, WListArray: Array of TTestWatch;
begin
TestBaseName := NamePreFix;
@ -1735,9 +1734,9 @@ begin
Fail(' Failed Init');
(* Create all watches *)
AddWatches(ExpectBreakFoo, WList, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakSubFoo, WListSub, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakFooArray, WListArray, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakFoo, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakSubFoo, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakFooArray, FWatches, Only, OnlyName, OnlyNamePart);
(* Start debugging *)
dbg.ShowConsole := True;
@ -1747,7 +1746,7 @@ begin
then begin
(* Hit first breakpoint: BREAK_LINE_FOOFUNC_NEST SubFoo -- (1st loop) Called with none nil data *)
TestWatchList('Brk1', ExpectBreakSubFoo, WListSub, dbg, Only, OnlyName, OnlyNamePart);
TestWatchList('Brk1', ExpectBreakSubFoo, dbg, Only, OnlyName, OnlyNamePart);
dbg.Run;
end
@ -1771,7 +1770,7 @@ begin
for i := low(ExpectBreakFoo) to high(ExpectBreakFoo) do begin
if not MatchOnly(ExpectBreakFoo[i], i) then continue;
if not SkipTest(ExpectBreakFoo[i]) then
TestWatch('Brk2 '+IntToStr(i)+' ', dbg, WList[i], ExpectBreakFoo[i]);
TestWatch('Brk2 '+IntToStr(i)+' ', dbg, ExpectBreakFoo[i].TheWatch, ExpectBreakFoo[i]);
end;
dbg.Run;
@ -1782,7 +1781,7 @@ begin
then begin
(* Hit 2nd breakpoint: BREAK_LINE_FOOFUNC_ARRAY SubFoo_Watches -- (1st loop) Called with none nil data *)
TestWatchList('Brk3', ExpectBreakFooArray, WListArray, dbg, Only, OnlyName, OnlyNamePart);
TestWatchList('Brk3', ExpectBreakFooArray, dbg, Only, OnlyName, OnlyNamePart);
dbg.Run;
end