FpDebug: fix nil array / tests

git-svn-id: trunk@44527 -
This commit is contained in:
martin 2014-03-26 23:31:59 +00:00
parent 2ad2c287e1
commit 0f0ea7602d
7 changed files with 589 additions and 77 deletions

View File

@ -614,20 +614,24 @@ type
procedure DoReferenceReleased; override;
procedure CircleBackRefActiveChanged(NewActive: Boolean); override;
procedure SetLastMember(ALastMember: TFpDbgDwarfValue);
function GetLastError: TFpError; override;
// Address of the symbol (not followed any type deref, or location)
function GetAddress: TFpDbgMemLocation; override;
function OrdOrAddress: TFpDbgMemLocation;
// Address of the data (followed type deref, location, ...)
function DataAddr: TFpDbgMemLocation;
function OrdOrDataAddr: TFpDbgMemLocation;
function GetDwarfDataAddress(out AnAddress: TFpDbgMemLocation; ATargetType: TDbgDwarfTypeIdentifier = nil): Boolean;
function GetStructureDwarfDataAddress(out AnAddress: TFpDbgMemLocation;
ATargetType: TDbgDwarfTypeIdentifier = nil): Boolean;
function HasDwarfDataAddress: Boolean;
function HasDwarfDataAddress: Boolean; // TODO: is this just HasAddress?
procedure Reset; virtual; // keeps lastmember and structureninfo
function GetFieldFlags: TFpDbgValueFieldFlags; override;
function HasTypeCastInfo: Boolean;
function IsValidTypeCast: Boolean; virtual;
function GetKind: TDbgSymbolKind; override;
function GetAddress: TFpDbgMemLocation; override;
function GetMemberCount: Integer; override;
function GetMemberByName(AIndex: String): TFpDbgValue; override;
function GetMember(AIndex: Int64): TFpDbgValue; override;
@ -1419,7 +1423,7 @@ implementation
var
FPDBG_DWARF_ERRORS, FPDBG_DWARF_WARNINGS, FPDBG_DWARF_SEARCH, FPDBG_DWARF_VERBOSE,
FPDBG_DWARF_DATA_WARNINGS: PLazLoggerLogGroup;
FPDBG_DWARF_VERBOSE_LOAD, FPDBG_DWARF_DATA_WARNINGS: PLazLoggerLogGroup;
const
SCOPE_ALLOC_BLOCK_SIZE = 4096; // Increase scopelist in steps of
@ -1925,10 +1929,11 @@ end;
function TFpDbgDwarfValueArray.GetDataAddress: TFpDbgMemLocation;
begin
//Result := GetDwarfDataAddress;
Result := MemManager.ReadAddress(OrdOrDataAddr, AddressSize); // TODO: cache
if not IsValidLoc(Result) then
FLastError := MemManager.LastError;
// TODO:
Result := OrdOrDataAddr;
//Result := MemManager.ReadAddress(OrdOrAddress, AddressSize); // TODO: cache
//if not IsValidLoc(Result) then
// FLastError := MemManager.LastError;
end;
function TFpDbgDwarfValueArray.GetMember(AIndex: Int64): TFpDbgValue;
@ -3058,6 +3063,14 @@ begin
Result := inherited GetAddress;
end;
function TFpDbgDwarfValue.OrdOrAddress: TFpDbgMemLocation;
begin
if HasTypeCastInfo and (svfOrdinal in FTypeCastSourceValue.FieldFlags) then
Result := ConstLoc(FTypeCastSourceValue.AsCardinal)
else
Result := Address;
end;
function TFpDbgDwarfValue.GetMemberCount: Integer;
begin
if FValueSymbol <> nil then
@ -3721,7 +3734,7 @@ var
begin
abbrev := 0;
CurAbbrevIndex := 0;
DbgVerbose := (FPDBG_DWARF_VERBOSE <> nil) and (FPDBG_DWARF_VERBOSE^.Enabled);
DbgVerbose := (FPDBG_DWARF_VERBOSE_LOAD <> nil) and (FPDBG_DWARF_VERBOSE_LOAD^.Enabled);
while (pbyte(AnAbbrevDataPtr) < FAbbrDataEnd) and (pbyte(AnAbbrevDataPtr)^ <> 0) do
begin
@ -3743,9 +3756,9 @@ begin
if DbgVerbose
then begin
DebugLn(FPDBG_DWARF_VERBOSE, [' abbrev: ', abbrev]);
DebugLn(FPDBG_DWARF_VERBOSE, [' tag: ', Def.tag, '=', DwarfTagToString(Def.tag)]);
DebugLn(FPDBG_DWARF_VERBOSE, [' children:', pbyte(AnAbbrevDataPtr)^, '=', DwarfChildrenToString(pbyte(AnAbbrevDataPtr)^)]);
DebugLn(FPDBG_DWARF_VERBOSE_LOAD, [' abbrev: ', abbrev]);
DebugLn(FPDBG_DWARF_VERBOSE_LOAD, [' tag: ', Def.tag, '=', DwarfTagToString(Def.tag)]);
DebugLn(FPDBG_DWARF_VERBOSE_LOAD, [' children:', pbyte(AnAbbrevDataPtr)^, '=', DwarfChildrenToString(pbyte(AnAbbrevDataPtr)^)]);
end;
if pbyte(AnAbbrevDataPtr)^ = DW_CHILDREN_yes then
f := [dafHasChildren]
@ -3779,7 +3792,7 @@ begin
Inc(CurAbbrevIndex);
if DbgVerbose
then DebugLn(FPDBG_DWARF_VERBOSE, [' [', n, '] attrib: ', attrib, '=', DwarfAttributeToString(attrib), ', form: ', form, '=', DwarfAttributeFormToString(form)]);
then DebugLn(FPDBG_DWARF_VERBOSE_LOAD, [' [', n, '] attrib: ', attrib, '=', DwarfAttributeToString(attrib), ', form: ', form, '=', DwarfAttributeFormToString(form)]);
Inc(n);
end;
Def.Count := n;
@ -9733,10 +9746,11 @@ begin
end;
initialization
FPDBG_DWARF_ERRORS := DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_ERRORS' {$IFDEF FPDBG_DWARF_ERRORS} , True {$ENDIF} );
FPDBG_DWARF_WARNINGS := DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_WARNINGS' {$IFDEF FPDBG_DWARF_WARNINGS} , True {$ENDIF} );
FPDBG_DWARF_VERBOSE := DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_VERBOSE' {$IFDEF FPDBG_DWARF_VERBOSE} , True {$ENDIF} );
FPDBG_DWARF_SEARCH := DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_SEARCH' {$IFDEF FPDBG_DWARF_SEARCH} , True {$ENDIF} );
FPDBG_DWARF_ERRORS := DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_ERRORS' {$IFDEF FPDBG_DWARF_ERRORS} , True {$ENDIF} );
FPDBG_DWARF_WARNINGS := DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_WARNINGS' {$IFDEF FPDBG_DWARF_WARNINGS} , True {$ENDIF} );
FPDBG_DWARF_VERBOSE := DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_VERBOSE' {$IFDEF FPDBG_DWARF_VERBOSE} , True {$ENDIF} );
FPDBG_DWARF_VERBOSE_LOAD := DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_VERBOSE_LOAD' {$IFDEF FPDBG_DWARF_VERBOSE_LOAD} , True {$ENDIF} );
FPDBG_DWARF_SEARCH := DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_SEARCH' {$IFDEF FPDBG_DWARF_SEARCH} , True {$ENDIF} );
// Target data anormalities
FPDBG_DWARF_DATA_WARNINGS := DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_DATA_WARNINGS' {$IFDEF FPDBG_DWARF_DATA_WARNINGS} , True {$ENDIF} );

View File

@ -565,6 +565,11 @@ function PrintPasValue(out APrintedValue: String; AResValue: TFpDbgValue;
begin
APrintedValue := '';
c := AResValue.MemberCount;
if (c = 0) and (svfOrdinal in AResValue.FieldFlags) then begin // dyn array
APrintedValue := 'nil';
Result := True;
exit;
end;
if c > 500 then c := 500;
d := 0;
// TODO: use valueobject for bounds

View File

@ -8,12 +8,14 @@ procedure Test1;
implementation
var
ArrayGlob_DynInt1: array of Integer;
ArrayGlob_DynInt1, ArrayGlob_DynInt2: array of Integer;
ArrayGlob_StatInt1: array [4..9] of Integer;
ArrayGlob_StatInt2: array [-4..9] of Integer;
procedure Test1;
begin
ArrayGlob_DynInt2 := nil;
SetLength(ArrayGlob_DynInt1,20);
ArrayGlob_DynInt1[0] := 5511;
ArrayGlob_DynInt1[1] := 5512;

View File

@ -10,32 +10,63 @@ procedure Test1;
implementation
type
{ TSimpleClass1 }
TSimpleClass1 = class
public
SimpleField_Short1: ShortInt;
SimpleField_Small1: Smallint;
SimpleField_Int1: LongInt;
SimpleField_QInt1: Int64;
SimpleField_Byte1: Byte;
SimpleField_Word1: Word;
SimpleField_DWord1: LongWord;
SimpleField_QWord1: QWord;
SimpleField_Single1: Single;
SimpleField_Double1: Double;
SimpleField_Ext1: Extended;
procedure Test1Method;
end;
{ TSimpleClass2 }
TSimpleClass2 = class(TSimpleClass1)
procedure Test2Method; // read inherited fields
end;
var
SimpleGlob_Short1, SimpleGlob_Short2, SimpleGlob_Short3, SimpleGlob_Short4, SimpleGlob_Short5: ShortInt;
SimpleGlob_Small1, SimpleGlob_Small2, SimpleGlob_Small3, SimpleGlob_Small4, SimpleGlob_Small5: Smallint;
SimpleGlob_Int1, SimpleGlob_Int2, SimpleGlob_Int3, SimpleGlob_Int4, SimpleGlob_Int5: Integer;
SimpleGlob_Int1, SimpleGlob_Int2, SimpleGlob_Int3, SimpleGlob_Int4, SimpleGlob_Int5: LongInt;
SimpleGlob_QInt1, SimpleGlob_QInt2, SimpleGlob_QInt3, SimpleGlob_QInt4, SimpleGlob_QInt5: Int64;
SimpleGlob_Byte1, SimpleGlob_Byte2, SimpleGlob_Byte3, SimpleGlob_Byte4, SimpleGlob_Byte5: Byte;
SimpleGlob_Word1, SimpleGlob_Word2, SimpleGlob_Word3, SimpleGlob_Word4, SimpleGlob_Word5: Word;
SimpleGlob_DWord1, SimpleGlob_DWord2, SimpleGlob_DWord3, SimpleGlob_DWord4, SimpleGlob_DWord5: DWord;
SimpleGlob_DWord1, SimpleGlob_DWord2, SimpleGlob_DWord3, SimpleGlob_DWord4, SimpleGlob_DWord5: LongWord;
SimpleGlob_QWord1, SimpleGlob_QWord2, SimpleGlob_QWord3, SimpleGlob_QWord4, SimpleGlob_QWord5: QWord;
SimpleGlob_Single1, SimpleGlob_Single2, SimpleGlob_Single3, SimpleGlob_Single4, SimpleGlob_Single5: Single;
SimpleGlob_Double1, SimpleGlob_Double2, SimpleGlob_Double3, SimpleGlob_Double4, SimpleGlob_Double5: Double;
SimpleGlob_Ext1, SimpleGlob_Ext2, SimpleGlob_Ext3, SimpleGlob_Ext4, SimpleGlob_Ext5: Extended;
SimpleGlob_Comp1, SimpleGlob_Comp2, SimpleGlob_Comp3: Comp;
SimpleGlob_Class1: TSimpleClass1;
SimpleGlob_Class2: TSimpleClass2;
procedure Test1Sub(
SimpleArg_Short1: ShortInt;
SimpleArg_Small1: Smallint;
SimpleArg_Int1: Integer;
SimpleArg_Int1: LongInt;
SimpleArg_QInt1: Int64;
SimpleArg_Byte1: Byte;
SimpleArg_Word1: Word;
SimpleArg_DWord1: DWord;
SimpleArg_DWord1: LongWord;
SimpleArg_QWord1: QWord;
SimpleArg_Single1: Single;
@ -44,54 +75,132 @@ procedure Test1Sub(
var SimpleVArg_Short1: ShortInt;
var SimpleVArg_Small1: Smallint;
var SimpleVArg_Int1 : Integer;
var SimpleVArg_Int1 : LongInt;
var SimpleVArg_QInt1: Int64;
var SimpleVArg_Byte1: Byte;
var SimpleVArg_Word1: Word;
var SimpleVArg_DWord1: DWord;
var SimpleVArg_DWord1: LongWord;
var SimpleVArg_QWord1: QWord;
var SimpleVArg_Single1: Single;
var SimpleVArg_Double1: Double;
var SimpleVArg_Ext1: Extended
var SimpleVArg_Ext1: Extended;
SimpleArg_Class1: TSimpleClass1;
SimpleArg_Class2: TSimpleClass2;
var SimpleVArg_Class1: TSimpleClass1;
var SimpleVArg_Class2: TSimpleClass2
);
var
SimpleLocal_Short1: ShortInt;
SimpleLocal_Small1: Smallint;
SimpleLocal_Int1 : Integer;
SimpleLocal_Int1 : LongInt;
SimpleLocal_QInt1: Int64;
SimpleLocal_Byte1: Byte;
SimpleLocal_Word1: Word;
SimpleLocal_DWord1: DWord;
SimpleLocal_DWord1: LongWord;
SimpleLocal_QWord1: QWord;
SimpleLocal_Single1: Single;
SimpleLocal_Double1: Double;
SimpleLocal_Ext1: Extended;
SimplePArg_Int1, SimplePVArg_Int1, SimplePLocal_Int1, SimplePGlob_Int1: PLongInt;
begin
SimpleLocal_Short1 := 39;
SimpleGlob_Short1 := 29;
SimpleGlob_Short2 := 0;
SimpleGlob_Short3 := -1;
SimpleGlob_Short4 := high(ShortInt);
SimpleGlob_Short5 := low(ShortInt);
SimpleLocal_Small1 := 391;
SimpleGlob_Small1 := 291;
SimpleGlob_Small2 := 0;
SimpleGlob_Small3 := -1;
SimpleGlob_Small4 := high(SmallInt);
SimpleGlob_Small5 := low(SmallInt);
SimpleLocal_Int1 := 3901;
SimpleGlob_Int1 := 2901;
SimpleGlob_Int2 := 0;
SimpleGlob_Int3 := -1;
SimpleGlob_Int4 := high(Integer);
SimpleGlob_Int5 := low(Integer);
SimpleGlob_Int4 := high(LongInt);
SimpleGlob_Int5 := low(LongInt);
SimpleLocal_QInt1 := 39001;
SimpleGlob_QInt1 := 29001;
SimpleGlob_QInt2 := 0;
SimpleGlob_QInt3 := -1;
SimpleGlob_QInt4 := high(Int64);
SimpleGlob_QInt5 := low(Int64);
SimpleLocal_Byte1 := 59;
SimpleGlob_Byte1 := 49;
SimpleGlob_Byte2 := $7f;
SimpleGlob_Byte3 := $80;
SimpleGlob_Byte4 := high(Byte);
SimpleGlob_Byte5 := low(Byte);
SimpleLocal_Word1 := 591;
SimpleGlob_Word1 := 491;
SimpleGlob_Word2 := $7fff;
SimpleGlob_Word3 := $8000;
SimpleGlob_Word4 := high(Word);
SimpleGlob_Word5 := low(Word);
SimpleLocal_DWord1 := 5901;
SimpleGlob_DWord1 := 4901;
SimpleGlob_DWord2 := $7fffffff;
SimpleGlob_DWord3 := $80000000;
SimpleGlob_DWord4 := high(LongWORD);
SimpleGlob_DWord5 := low(LongWORD);
SimpleLocal_QWord1 := 59001;
SimpleGlob_QWord1 := 49001;
SimpleGlob_QWord2 := $7fffffffffffffff;
SimpleGlob_QWord3 := qword($8000000000000000);
SimpleGlob_QWord4 := high(QWord);
SimpleGlob_QWord5 := low(QWord);
SimplePArg_Int1 := @SimpleArg_Int1;
SimplePVArg_Int1 := @SimpleVArg_Int1;
SimplePLocal_Int1 := @SimpleLocal_Int1;
SimplePGlob_Int1 := @SimpleGlob_Int1;
inc(SimpleVArg_Int1); // BREAK Single 1
end;
{ TSimpleClass1 }
procedure TSimpleClass1.Test1Method;
begin
inc(SimpleGlob_Byte1); // BREAK Single 2
end;
{ TSimpleClass2 }
procedure TSimpleClass2.Test2Method;
begin
inc(SimpleGlob_Byte1); // BREAK Single 3
end;
procedure Test1;
var
i1: shortint;
i2: smallint;
i3: Integer;
i3: LongInt;
i4: Int64;
u1: byte;
u2: word;
u3: dword;
u3: Longword;
u4: qword;
d1: Single;
d2: double;
@ -108,11 +217,54 @@ begin
d1 := -1234;
d2 := -2345;
d3 := -3456;
SimpleGlob_Class1 := TSimpleClass1.Create;
SimpleGlob_Class2 := TSimpleClass2.Create;
with SimpleGlob_Class1 do begin
SimpleField_Short1 := 11;
SimpleField_Small1 := 12;
SimpleField_Int1 := 13;
SimpleField_QInt1 := 14;
SimpleField_Byte1 := 15;
SimpleField_Word1 := 16;
SimpleField_DWord1 := 17;
SimpleField_QWord1 := 18;
SimpleField_Single1 := 21;
SimpleField_Double1 := 21;
SimpleField_Ext1 := 21;
end;
with SimpleGlob_Class2 do begin
SimpleField_Short1 := 111;
SimpleField_Small1 := 112;
SimpleField_Int1 := 113;
SimpleField_QInt1 := 114;
SimpleField_Byte1 := 115;
SimpleField_Word1 := 116;
SimpleField_DWord1 := 117;
SimpleField_QWord1 := 118;
SimpleField_Single1 := 121.3;
SimpleField_Double1 := 121.4;
SimpleField_Ext1 := 121.5;
end;
SimpleGlob_Comp1 := 0;
SimpleGlob_Comp1 := 1;
SimpleGlob_Comp1 := -1;
Test1Sub(
-92, -192, -1902, -190000000000002, 92, 192, 1902, 190000000000002,
1234, 2345, 3456,
i1, i2, i3, i4, u1, u2, u3, u4, d1, d2, d3
i1, i2, i3, i4, u1, u2, u3, u4, d1, d2, d3,
SimpleGlob_Class1, SimpleGlob_Class2, SimpleGlob_Class1, SimpleGlob_Class2
);
SimpleGlob_Class1.Test1Method;
SimpleGlob_Class2.Test2Method;
end;
end.

View File

@ -10,7 +10,10 @@ uses
GDBMIDebugger;
const
BREAK_LINE_TestWatchesUnitSimple = 82;
BREAK_LINE_TestWatchesUnitSimple_1 = 178;
BREAK_LINE_TestWatchesUnitSimple_2 = 185;
BREAK_LINE_TestWatchesUnitSimple_3 = 192;
BREAK_LINE_TestWatchesUnitArray = 38;
type
@ -21,9 +24,18 @@ type
private
FWatches: TWatches;
ExpectBreakSimple1: TWatchExpectationArray;
ExpectBreakArray1: TWatchExpectationArray;
FCurrentExpArray: ^TWatchExpectationArray; // currently added to
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;
ExpectBreakArray_1: TWatchExpectationArray;
FCurrentExpect: ^TWatchExpectationArray; // currently added to
FDbgOutPut: String;
FDbgOutPutEnable: Boolean;
@ -39,10 +51,13 @@ type
function AddFmtDef (AnExpr, AMtch: string; AKind: TDBGSymbolKind; ATpNm: string; AFlgs: TWatchExpectationFlags=[]): PWatchExpectation;
function AddFmtDef (AnExpr: String; AEvalFlags: TDBGEvaluateFlags; AMtch: string; AKind: TDBGSymbolKind; ATpNm: string; AFlgs: TWatchExpectationFlags=[]): PWatchExpectation;
function AddSimpleInt(AnExpr, AMtch: string; ATpNm: string): PWatchExpectation;
function AddSimpleInt(AnExpr: string; AMtch: Int64; ATpNm: string): PWatchExpectation;
function AddSimpleUInt(AnExpr: string; AMtch: QWord; ATpNm: string): PWatchExpectation;
procedure AddExpectSimple;
procedure AddExpectArray;
procedure AddExpectSimple_1;
procedure AddExpectSimple_2;
procedure AddExpectSimple_3;
procedure AddExpectArray_1;
procedure RunTestWatches(NamePreFix: String;
TestExeName, ExtraOpts: String;
UsedUnits: array of TUsesDir
@ -124,14 +139,14 @@ end;
function TTestWatches.Add(AnExpr: string; AFmt: TWatchDisplayFormat; AMtch: string;
AKind: TDBGSymbolKind; ATpNm: string; AFlgs: TWatchExpectationFlags): PWatchExpectation;
begin
Result := AddWatchExp(FCurrentExpArray^, AnExpr, AFmt, AMtch, AKind, ATpNm, AFlgs );
Result := AddWatchExp(FCurrentExpect^, AnExpr, AFmt, AMtch, AKind, ATpNm, AFlgs );
end;
function TTestWatches.Add(AnExpr: string; AFmt: TWatchDisplayFormat;
AEvalFlags: TDBGEvaluateFlags; AMtch: string; AKind: TDBGSymbolKind; ATpNm: string;
AFlgs: TWatchExpectationFlags): PWatchExpectation;
begin
Result := AddWatchExp(FCurrentExpArray^, AnExpr, AFmt, AEvalFlags, AMtch, AKind, ATpNm, AFlgs );
Result := AddWatchExp(FCurrentExpect^, AnExpr, AFmt, AEvalFlags, AMtch, AKind, ATpNm, AFlgs );
end;
function TTestWatches.AddFmtDef(AnExpr, AMtch: string; AKind: TDBGSymbolKind; ATpNm: string;
@ -146,44 +161,297 @@ begin
Result := Add(AnExpr, wdfDefault, AEvalFlags, AMtch, AKind, ATpNm, AFlgs );
end;
function TTestWatches.AddSimpleInt(AnExpr, AMtch: string; ATpNm: string): PWatchExpectation;
function TTestWatches.AddSimpleInt(AnExpr: string; AMtch: Int64;
ATpNm: string): PWatchExpectation;
begin
AddFmtDef(AnExpr, AMtch, skSimple, ATpNm, [fTpMtch]);
AddFmtDef(AnExpr, '^'+IntToStr(AMtch), skSimple, ATpNm, [fTpMtch]);
end;
procedure TTestWatches.AddExpectSimple;
function TTestWatches.AddSimpleUInt(AnExpr: string; AMtch: QWord;
ATpNm: string): PWatchExpectation;
begin
FCurrentExpArray := @ExpectBreakSimple1;
//
AddSimpleInt('SimpleArg_Int1', '^-1902', M_Int);
AddSimpleInt('SimpleVArg_Int1', '^-1901', M_Int);
AddSimpleInt('SimpleLocal_Int1', '^3901', M_Int);
AddSimpleInt('SimpleGlob_Int1', '^2901', M_Int);
AddSimpleInt('SimpleGlob_Int2', '^0', M_Int);
AddSimpleInt('SimpleGlob_Int3', '^-1', M_Int);
AddSimpleInt('SimpleGlob_Int4', '^2147483647', M_Int);
AddSimpleInt('SimpleGlob_Int5', '^-2147483648', M_Int);
AddFmtDef(AnExpr, '^'+IntToStr(AMtch), skSimple, ATpNm, [fTpMtch]);
end;
procedure TTestWatches.AddExpectArray;
procedure TTestWatches.AddExpectSimple_1;
var
i: Integer;
s, s2, s2def: String;
j: Integer;
begin
FCurrentExpArray := @ExpectBreakArray1;
FCurrentExpect := @ExpectBreakSimple_1;
for i := 0 to 3 do begin
s2def := '';
case i of
0: s := '%s';
1: s := '(@%s)^';
2: s := 'Int64(%s)';
3: s := 'QWord(%s)';
end;
case i of
2: s2def := 'Int64';
3: s2def := 'QWord';
end;
s2 := s2def;
if s2 = '' then s2 := 'ShortInt';
if not(i in [3]) then begin
AddSimpleInt(Format(s, ['SimpleArg_Short1']), -92, s2);
AddSimpleInt(Format(s, ['SimpleVArg_Short1']), -91, s2);
end else begin
AddSimpleUInt(Format(s, ['SimpleArg_Short1']), QWord(-92), s2);
AddSimpleUInt(Format(s, ['SimpleVArg_Short1']), QWord(-91), s2);
end;
AddSimpleInt(Format(s, ['SimpleLocal_Short1']), 39, s2);
AddSimpleInt(Format(s, ['SimpleGlob_Short1 ']), 29, s2);
AddSimpleInt(Format(s, ['SimpleGlob_Short2']), 0, s2);
if not(i in [3]) then begin
AddSimpleInt(Format(s, ['SimpleGlob_Short3']), -1, s2);
end;
AddSimpleInt(Format(s, ['SimpleGlob_Short4']), high(ShortInt), s2);
if not(i in [3]) then begin
AddSimpleInt(Format(s, ['SimpleGlob_Short5']), low(ShortInt), s2);
end;
s2 := s2def;
if s2 = '' then s2 := 'SmallInt';
if not(i in [3]) then begin
AddSimpleInt(Format(s, ['SimpleArg_Small1']), -192, s2);
AddSimpleInt(Format(s, ['SimpleVArg_Small1']), -191, s2);
end;
AddSimpleInt(Format(s, ['SimpleLocal_Small1']), 391, s2);
AddSimpleInt(Format(s, ['SimpleGlob_Small1 ']), 291, s2);
AddSimpleInt(Format(s, ['SimpleGlob_Small2']), 0, s2);
if not(i in [3]) then begin
AddSimpleInt(Format(s, ['SimpleGlob_Small3']), -1, s2);
end;
AddSimpleInt(Format(s, ['SimpleGlob_Small4']), high(SmallInt), s2);
if not(i in [3]) then begin
AddSimpleInt(Format(s, ['SimpleGlob_Small5']), low(SmallInt), s2);
end;
s2 := s2def;
if s2 = '' then s2 := M_Int;
if not(i in [3]) then begin
AddSimpleInt(Format(s, ['SimpleArg_Int1']), -1902, s2);
AddSimpleInt(Format(s, ['SimpleVArg_Int1']), -1901, s2);
end;
AddSimpleInt(Format(s, ['SimpleLocal_Int1']), 3901, s2);
AddSimpleInt(Format(s, ['SimpleGlob_Int1']), 2901, s2);
AddSimpleInt(Format(s, ['SimpleGlob_Int2']), 0, s2);
if not(i in [3]) then begin
AddSimpleInt(Format(s, ['SimpleGlob_Int3']), -1, s2);
end;
AddSimpleInt(Format(s, ['SimpleGlob_Int4']), 2147483647, s2);
if not(i in [3]) then begin
AddSimpleInt(Format(s, ['SimpleGlob_Int5']), -2147483648, s2);
end;
s2 := s2def;
if s2 = '' then s2 := 'Int64';
if not(i in [3]) then begin
AddSimpleInt(Format(s, ['SimpleArg_QInt1']), -190000000000002, s2);
AddSimpleInt(Format(s, ['SimpleVArg_QInt1']), -190000000000001, s2);
end;
AddSimpleInt(Format(s, ['SimpleLocal_QInt1']), 39001, s2);
AddSimpleInt(Format(s, ['SimpleGlob_QInt1 ']), 29001, s2);
AddSimpleInt(Format(s, ['SimpleGlob_QInt2']), 0, s2);
if not(i in [3]) then begin
AddSimpleInt(Format(s, ['SimpleGlob_QInt3']), -1, s2);
end;
AddSimpleInt(Format(s, ['SimpleGlob_QInt4']), high(Int64), s2);
if not(i in [3]) then begin
AddSimpleInt(Format(s, ['SimpleGlob_QInt5']), low(Int64), s2);
end;
s2 := s2def;
if s2 = '' then s2 := 'Byte';
AddSimpleUInt(Format(s, ['SimpleLocal_Byte1']), 59, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_Byte1 ']), 49, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_Byte2']), $7f, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_Byte3']), $80, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_Byte4']), high(Byte), s2);
AddSimpleUInt(Format(s, ['SimpleGlob_Byte5']), low(Byte), s2);
s2 := s2def;
if s2 = '' then s2 := 'Word';
AddSimpleUInt(Format(s, ['SimpleLocal_Word1']), 591, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_Word1 ']), 491, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_Word2']), $7fff, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_Word3']), $8000, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_Word4']), high(Word), s2);
AddSimpleUInt(Format(s, ['SimpleGlob_Word5']), low(Word), s2);
s2 := s2def;
if s2 = '' then s2 := 'LongWord';
AddSimpleUInt(Format(s, ['SimpleLocal_DWord1']), 5901, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_DWord1 ']), 4901, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_DWord2']), $7fffffff, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_DWord3']), $80000000, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_DWord4']), high(LongWord), s2);
AddSimpleUInt(Format(s, ['SimpleGlob_DWord5']), low(LongWord), s2);
s2 := s2def;
if s2 = '' then s2 := 'QWord';
if not(i in [2]) then begin
AddSimpleUInt(Format(s, ['SimpleLocal_QWord1']), 59001, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_QWord1 ']), 49001, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_QWord2']), $7fffffffffffffff, s2);
AddSimpleUInt(Format(s, ['SimpleGlob_QWord3']), qword($8000000000000000), s2);
AddSimpleUInt(Format(s, ['SimpleGlob_QWord4']), high(QWord), s2);
AddSimpleUInt(Format(s, ['SimpleGlob_QWord5']), low(QWord), s2);
end;
end;
s2 := 'Byte';
s := 'Byte(%s)';
AddSimpleInt(Format(s, ['SimpleArg_Int1']), Byte(-1902), s2);
AddSimpleInt(Format(s, ['SimpleVArg_Int1']), Byte(-1901), s2);
AddSimpleInt(Format(s, ['SimpleLocal_Int1']), Byte(3901), s2);
AddSimpleInt(Format(s, ['SimpleGlob_Int1']), Byte(2901), s2);
AddSimpleInt(Format(s, ['SimpleGlob_Int2']), Byte(0), s2);
AddSimpleInt(Format(s, ['SimpleGlob_Int3']), Byte(-1), s2);
AddSimpleInt(Format(s, ['SimpleGlob_Int4']), Byte(2147483647), s2);
AddSimpleInt(Format(s, ['SimpleGlob_Int5']), Byte(-2147483648), s2);
for i := 0 to 3 do begin
case i of
0: s := 'SimpleArg_Class1.%s';
1: s := 'SimpleVArg_Class1.%s';
2: s := 'SimpleArg_Class2.%s';
3: s := 'SimpleVArg_Class2.%s';
end;
j := 0;
if i in [2,3] then j := 100;
AddSimpleInt(Format(s, ['SimpleField_Short1']), j+11, 'ShortInt');
AddSimpleInt(Format(s, ['SimpleField_Small1']), j+12, 'SmallInt');
AddSimpleInt(Format(s, ['SimpleField_Int1']), j+13, 'LongInt');
AddSimpleInt(Format(s, ['SimpleField_QInt1']), j+14, 'Int64');
AddSimpleInt(Format(s, ['SimpleField_Byte1']), j+15, 'Byte');
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 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, '');
FSimplePVArg_Int1 := AddFmtDef('SimplePVArg_Int1', '\$[0-9A-F]', skPointer, '');
FAddrSimpleVArg_Int1 := AddFmtDef('@SimpleVArg_Int1', 'replaceme', skPointer, '');
UpdResMinFpc(FAddrSimpleVArg_Int1, stSymAll, 020600);
FSimplePLocal_Int1 := AddFmtDef('SimplePLocal_Int1', '\$[0-9A-F]', skPointer, '');
FAddrSimpleLocal_Int1 := AddFmtDef('@SimpleLocal_Int1', 'replaceme', skPointer, '');
FSimplePGlob_Int1 := AddFmtDef('SimplePGlob_Int1', '\$[0-9A-F]', skPointer, '');
FAddrSimpleGlob_Int1 := AddFmtDef('@SimpleGlob_Int1', 'replaceme', skPointer, '');
{%region}
end;
procedure TTestWatches.AddExpectSimple_2;
var
s: String;
begin
FCurrentExpect := @ExpectBreakSimple_2;
s := '%s';
AddSimpleInt(Format(s, ['SimpleField_Short1']), 11, 'ShortInt');
AddSimpleInt(Format(s, ['SimpleField_Small1']), 12, 'SmallInt');
AddSimpleInt(Format(s, ['SimpleField_Int1']), 13, 'LongInt');
AddSimpleInt(Format(s, ['SimpleField_QInt1']), 14, 'Int64');
AddSimpleInt(Format(s, ['SimpleField_Byte1']), 15, 'Byte');
AddSimpleInt(Format(s, ['SimpleField_Word1']), 16, 'Word');
AddSimpleInt(Format(s, ['SimpleField_DWord1']), 17, 'LongWord');
AddSimpleInt(Format(s, ['SimpleField_QWord1']), 18, 'QWord');
s := 'self.%s';
AddSimpleInt(Format(s, ['SimpleField_Short1']), 11, 'ShortInt');
AddSimpleInt(Format(s, ['SimpleField_Small1']), 12, 'SmallInt');
AddSimpleInt(Format(s, ['SimpleField_Int1']), 13, 'LongInt');
AddSimpleInt(Format(s, ['SimpleField_QInt1']), 14, 'Int64');
AddSimpleInt(Format(s, ['SimpleField_Byte1']), 15, 'Byte');
AddSimpleInt(Format(s, ['SimpleField_Word1']), 16, 'Word');
AddSimpleInt(Format(s, ['SimpleField_DWord1']), 17, 'LongWord');
AddSimpleInt(Format(s, ['SimpleField_QWord1']), 18, 'QWord');
end;
procedure TTestWatches.AddExpectSimple_3;
var
s: String;
begin
FCurrentExpect := @ExpectBreakSimple_3;
s := '%s';
AddSimpleInt(Format(s, ['SimpleField_Short1']), 111, 'ShortInt');
AddSimpleInt(Format(s, ['SimpleField_Small1']), 112, 'SmallInt');
AddSimpleInt(Format(s, ['SimpleField_Int1']), 113, 'LongInt');
AddSimpleInt(Format(s, ['SimpleField_QInt1']), 114, 'Int64');
AddSimpleInt(Format(s, ['SimpleField_Byte1']), 115, 'Byte');
AddSimpleInt(Format(s, ['SimpleField_Word1']), 116, 'Word');
AddSimpleInt(Format(s, ['SimpleField_DWord1']), 117, 'LongWord');
AddSimpleInt(Format(s, ['SimpleField_QWord1']), 118, 'QWord');
s := 'self.%s';
AddSimpleInt(Format(s, ['SimpleField_Short1']), 111, 'ShortInt');
AddSimpleInt(Format(s, ['SimpleField_Small1']), 112, 'SmallInt');
AddSimpleInt(Format(s, ['SimpleField_Int1']), 113, 'LongInt');
AddSimpleInt(Format(s, ['SimpleField_QInt1']), 114, 'Int64');
AddSimpleInt(Format(s, ['SimpleField_Byte1']), 115, 'Byte');
AddSimpleInt(Format(s, ['SimpleField_Word1']), 116, 'Word');
AddSimpleInt(Format(s, ['SimpleField_DWord1']), 117, 'LongWord');
AddSimpleInt(Format(s, ['SimpleField_QWord1']), 118, 'QWord');
end;
procedure TTestWatches.AddExpectArray_1;
begin
FCurrentExpect := @ExpectBreakArray_1;
AddFmtDef('ArrayGlob_DynInt2', '^nil', skArray, '', [fTpMtch]);
AddSimpleInt('QWord(ArrayGlob_DynInt2)', 0, 'QWord');
// TODO var param
//UpdResMinFpc(r, stSymAll, 020600);
AddFmtDef('ArrayGlob_DynInt1', '^[\(L].*5511, 5512, 5513, 5514, -5511',
skArray, '', [fTpMtch]);
AddSimpleInt('ArrayGlob_DynInt1[0]', '^5511', M_Int);
AddSimpleInt('ArrayGlob_DynInt1[19]', '^5500', M_Int);
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);
AddSimpleInt('ArrayGlob_StatInt1[9]', '^6699', M_Int);
AddSimpleInt('ArrayGlob_StatInt1[-1]', '', M_Int); // Just do not crash
AddSimpleInt('ArrayGlob_StatInt1[4]', 6600, M_Int);
AddSimpleInt('ArrayGlob_StatInt1[9]', 6699, M_Int);
AddFmtDef('ArrayGlob_StatInt1[3]', '', skSimple, M_Int, [fTpMtch]); // Just do not crash
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);
AddSimpleInt('ArrayGlob_StatInt2[-4]', 3300, M_Int);
AddSimpleInt('ArrayGlob_StatInt2[0]', 3304, M_Int);
// EMPTY dyn array = nil
end;
procedure TTestWatches.RunTestWatches(NamePreFix: String; TestExeName, ExtraOpts: String;
@ -196,7 +464,10 @@ var
var
i: Integer;
WListSimple1, WListArray1: TTestWatchArray;
WListSimple1, WListSimple2, WListSimple3,
WListArray1: TTestWatchArray;
st: TSymbolType;
s: String;
begin
TestBaseName := NamePreFix;
@ -226,7 +497,15 @@ begin
dbg := StartGDB(AppDir, TestExeName);
FWatches := Watches.Watches;
with dbg.BreakPoints.Add('TestWatchesUnitSimple.pas', BREAK_LINE_TestWatchesUnitSimple) do begin
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;
@ -238,32 +517,72 @@ begin
if dbg.State = dsError then
Fail(' Failed Init');
AddWatches(ExpectBreakSimple1, WListSimple1, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakArray1, WListArray1, FWatches, Only, OnlyName, OnlyNamePart);
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);
(* Start debugging *)
dbg.ShowConsole := True;
dbg.Run;
if not TestTrue('State=Pause', dbg.State = dsPause) then begin
TestTrue('Hit BREAK_LINE_TestWatchesUnitSimple', False);
TestTrue('Hit BREAK_LINE_TestWatchesUnitSimple_1', False);
exit;
end;
(* Hit first breakpoint: *)
TestWatchList('Simple1',ExpectBreakSimple1, WListSimple1, dbg, Only, OnlyName, OnlyNamePart);
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);
dbg.Run;
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);
dbg.Run;
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);
// array
dbg.Run;
if not TestTrue('State=Pause', dbg.State = dsPause) then begin
TestTrue('Hit BREAK_LINE_TestWatchesUnitArray', False);
exit;
end;
(* Hit 2nd breakpoint: *)
TestWatchList('Array1',ExpectBreakArray1, WListArray1, dbg, Only, OnlyName, OnlyNamePart);
(* Hit 11st Array breakpoint: *)
TestWatchList('Array1',ExpectBreakArray_1, WListArray1, dbg, Only, OnlyName, OnlyNamePart);
dbg.Run;
@ -293,8 +612,10 @@ begin
ClearTestErrors;
ClearAllTestArrays;
AddExpectSimple;
AddExpectArray;
AddExpectSimple_1;
AddExpectSimple_2;
AddExpectSimple_3;
AddExpectArray_1;
RunTestWatches('', TestExeName, '', []);

View File

@ -185,6 +185,8 @@ type
protected
function CreateRegistersList: TRegistersList; override;
procedure RequestData(ARegisters: TRegisters);
procedure DoStateEnterPause; override;
procedure DoStateLeavePause; override;
end;
{ TBaseList }
@ -564,6 +566,18 @@ begin
else ARegisters.DataValidity := ddsInvalid;
end;
procedure TTestRegistersMonitor.DoStateEnterPause;
begin
inherited DoStateEnterPause;
RegistersList.Clear;
end;
procedure TTestRegistersMonitor.DoStateLeavePause;
begin
inherited DoStateLeavePause;
RegistersList.Clear;
end;
{ TTEstRegistersList }
function TTestRegistersList.CreateEntry(AThreadId, AStackFrame: Integer): TRegisters;
@ -1646,9 +1660,11 @@ initialization
DebugLogger.FindOrRegisterLogGroup('DBGMI_TYPE_INFO', True )^.Enabled := True;
DebugLogger.FindOrRegisterLogGroup('DBGMI_TIMEOUT_DEBUG', True )^.Enabled := True;
DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_ERRORS', True);
DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_SEARCH', True)^.Enabled := True;
DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_WARNINGS', True)^.Enabled := True;
//FPDBG_DWARF_VERBOSE
DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_VERBOSE', True);
DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_DATA_WARNINGS', True);
AppDir := AppendPathDelim(ExtractFilePath(Paramstr(0)));

View File

@ -111,6 +111,7 @@ type
EvaluateFlags: TDBGEvaluateFlags;
StackFrame: Integer;
Result: Array [TSymbolType] of TWatchExpectationResult;
TheWatch: TTestWatch;
end;
TWatchExpectationArray = array of TWatchExpectation;
@ -543,6 +544,7 @@ begin
WatchList[i].DisplayFormat := ExpectList[i].DspFormat;
WatchList[i].EvaluateFlags:= ExpectList[i].EvaluateFlags;
WatchList[i].enabled := True;
ExpectList[i].TheWatch := WatchList[i];
end;
end;
end;