Debugger (GDB): deal with regression in gdb 7.7 when accessing members of current object (self). Issue #0027136

git-svn-id: trunk@47371 -
This commit is contained in:
martin 2015-01-13 00:16:44 +00:00
parent ebcecf6b36
commit 53c99ecb3c
4 changed files with 90 additions and 3 deletions

View File

@ -2156,7 +2156,11 @@ begin
Create(skSimple, ''); // initialize
FInternalTypeName := '';
FEvalError := False;
FExpression := AnExpression;
(* uppercase due to https://sourceware.org/bugzilla/show_bug.cgi?id=17835
gdb 7.7 and 7.8 fail to find members, if lowercased
Alternative prefix with "self." if gdb returns &"Type TCLASSXXXX has no component named EXPRESSION.\n"
*)
FExpression := UpperCase(AnExpression);
FOrigExpression := FExpression;
FCreationFlags := AFlags;
FExprEvaluateFormat := AFormat;

View File

@ -319,6 +319,26 @@ begin
);
{$UNDEF Global_Call_FooFunc}
{$DEFINE Global_Body_Extra}
{ class/record/object }
{$I WatchesPrgStruct.inc}
{ strings }
{$I WatchesPrgString.inc}
{ simple }
{$I WatchesPrgSimple.inc}
{ enum/set }
{$I WatchesPrgEnum.inc}
{ Array }
{$I WatchesPrgArray.inc}
{ variants }
{$I WatchesPrgVariant.inc}
{ procedure/function/method }
{$I WatchesPrgProc.inc}
{$UNDEF Global_Body_Extra}
// same with nil
{$DEFINE Global_Body_NIL}

View File

@ -317,7 +317,16 @@
TClassTCastUW1Component = class(TClassUW1BaseComponent) public b: Integer; end;
{$ENDIF}
TClassTCast2 = class(TClassTCast) public c: Integer; end;
TClassTCast2 = class(TClassTCast)
private
privMember1: Integer;
protected
protMember1: Integer;
public
publMember1: Integer;
c: Integer;
procedure ClassTCast2Method1; //procedure TClassTCast2.ClassTCast2Method1;
end;
TClassTCast3 = type TClassTCast;
{$ENDIF}
@ -481,6 +490,12 @@
begin
PropInt := AValue;
end;
procedure TClassTCast2.ClassTCast2Method1;
begin
// break on next line
writeln(1);
end;
{$ENDIF}
{$IFDEF FooFunc_LocalType}
@ -692,6 +707,8 @@
GlobPNewFooClass: PNewFooClass;
PGlobTFooClass: ^TFooClass;
GlobClassTCast2: TClassTCast2;
{$ENDIF}
{$IFDEF Global_Body}
@ -706,6 +723,15 @@
PGlobTFooClass := @GlobTNewFooClass;
{$ENDIF}
{$IFDEF Global_Body_Extra}
//begin
GlobClassTCast2 := TClassTCast2.Create;
GlobClassTCast2.privMember1 := 411;
GlobClassTCast2.protMember1 := 412;
GlobClassTCast2.publMember1 := 413;
GlobClassTCast2.ClassTCast2Method1;
{$ENDIF}
{$IFDEF Global_Body_NIL}
//begin
{ ClassesTyps }

View File

@ -12,6 +12,7 @@ const
BREAK_LINE_FOOFUNC_NEST = 206;
BREAK_LINE_FOOFUNC = 230;
BREAK_LINE_FOOFUNC_ARRAY = 254;
BREAK_LINE_Class_Meth1 = 497; // WatchesPrgStruct.inc
RUN_GDB_TEST_ONLY = -1; // -1 run all
RUN_TEST_ONLY = -1; // -1 run all
@ -40,6 +41,7 @@ type
ExpectBreakSubFoo: TWatchExpectationArray; // Watches, evaluated in SubFoo (nested)
ExpectBreakFoo: TWatchExpectationArray; // Watches, evaluated in Foo
ExpectBreakFooArray: TWatchExpectationArray; // Watches, evaluated in Foo_Array
ExpectBreakClassMeth1: TWatchExpectationArray; // Watches, evaluated TClassTCast2.ClassTCast2Method1;
FCurrentExpArray: ^TWatchExpectationArray; // currently added to
@ -70,6 +72,7 @@ type
procedure AddExpectBreakFooAll;
procedure AddExpectBreakFooArray;
procedure AddExpectBreakFooMixInfo;
procedure AddExpectBreakClassMeth1;
//procedure AddExpectBreakSubFoo;
procedure AddExpectBreakFooAndSubFoo; // check for caching issues
procedure RunTestWatches(NamePreFix: String;
@ -132,6 +135,7 @@ begin
SetLength(ExpectBreakSubFoo, 0);
SetLength(ExpectBreakFoo, 0);
SetLength(ExpectBreakFooArray, 0);
SetLength(ExpectBreakClassMeth1, 0);
end;
function TTestWatches.HasTestArraysData: Boolean;
@ -139,7 +143,8 @@ begin
Result := (Length(ExpectBreakFooGdb) > 0) or
(Length(ExpectBreakSubFoo) > 0) or
(Length(ExpectBreakFoo) > 0) or
(Length(ExpectBreakFooArray) >0 );
(Length(ExpectBreakFooArray) >0 ) or
(Length(ExpectBreakClassMeth1) >0 );
end;
@ -1617,6 +1622,21 @@ begin
[]);
end;
procedure TTestWatches.AddExpectBreakClassMeth1;
begin
if not TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf(' TTestWatch.All')] then exit;
FCurrentExpArray := @ExpectBreakClassMeth1;
AddFmtDef('publMember1', '^413$', skSimple, 'Integer|LongInt', [fTpMtch]);
AddFmtDef('protMember1', '^412$', skSimple, 'Integer|LongInt', [fTpMtch]);
AddFmtDef('privMember1', '^411$', skSimple, 'Integer|LongInt', [fTpMtch]);
AddFmtDef('self.publMember1', '^413$', skSimple, 'Integer|LongInt', [fTpMtch]);
AddFmtDef('self.protMember1', '^412$', skSimple, 'Integer|LongInt', [fTpMtch]);
AddFmtDef('self.privMember1', '^411$', skSimple, 'Integer|LongInt', [fTpMtch]);
end;
procedure TTestWatches.AddExpectBreakFooAndSubFoo;
procedure AddF(AnExpr: string; AFmt: TWatchDisplayFormat;
AMtch: string; AKind: TDBGSymbolKind; ATpNm: string; AFlgs: TWatchExpectationFlags;
@ -1729,6 +1749,11 @@ begin
InitialEnabled := True;
Enabled := True;
end;
with dbg.BreakPoints.Add('WatchesPrgStruct.inc', BREAK_LINE_Class_Meth1) do begin
InitialEnabled := True;
Enabled := True;
end;
if dbg.State = dsError then
Fail(' Failed Init');
@ -1737,6 +1762,7 @@ begin
AddWatches(ExpectBreakFoo, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakSubFoo, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakFooArray, FWatches, Only, OnlyName, OnlyNamePart);
AddWatches(ExpectBreakClassMeth1, FWatches, Only, OnlyName, OnlyNamePart);
(* Start debugging *)
dbg.ShowConsole := True;
@ -1788,6 +1814,16 @@ begin
else TestTrue('Hit BREAK_LINE_FOOFUNC_ARRAY', False);
if TestTrue('State=Pause', dbg.State = dsPause)
then begin
(* Hit 2nd breakpoint: BREAK_LINE_Class_Meth1 *)
TestWatchList('Brk3', ExpectBreakClassMeth1, dbg, Only, OnlyName, OnlyNamePart);
dbg.Run;
end
else TestTrue('Hit BREAK_LINE_Class_Meth1', False);
// TODO: 2nd round, with NIL data
//DebugInteract(dbg);
@ -1824,6 +1860,7 @@ begin
AddExpectBreakFooArray;
//AddExpectBreakFooMixInfo;
AddExpectBreakFooAndSubFoo;
AddExpectBreakClassMeth1;
RunTestWatches('', TestExeName, '', []);
if TestControlForm.CheckListBox1.Checked[TestControlForm.CheckListBox1.Items.IndexOf(' TTestWatch.Mix')]