From 53c99ecb3ca0a46d13313fe8aa998d0c9c623adb Mon Sep 17 00:00:00 2001 From: martin Date: Tue, 13 Jan 2015 00:16:44 +0000 Subject: [PATCH] Debugger (GDB): deal with regression in gdb 7.7 when accessing members of current object (self). Issue #0027136 git-svn-id: trunk@47371 - --- components/lazdebuggergdbmi/gdbtypeinfo.pp | 6 ++- .../test/TestApps/WatchesPrg.pas | 20 ++++++++++ .../test/TestApps/WatchesPrgStruct.inc | 28 ++++++++++++- .../lazdebuggergdbmi/test/testwatches.pas | 39 ++++++++++++++++++- 4 files changed, 90 insertions(+), 3 deletions(-) diff --git a/components/lazdebuggergdbmi/gdbtypeinfo.pp b/components/lazdebuggergdbmi/gdbtypeinfo.pp index 5250507bff..bff8f65298 100644 --- a/components/lazdebuggergdbmi/gdbtypeinfo.pp +++ b/components/lazdebuggergdbmi/gdbtypeinfo.pp @@ -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; diff --git a/components/lazdebuggergdbmi/test/TestApps/WatchesPrg.pas b/components/lazdebuggergdbmi/test/TestApps/WatchesPrg.pas index 4621f6393e..03b909c5b1 100644 --- a/components/lazdebuggergdbmi/test/TestApps/WatchesPrg.pas +++ b/components/lazdebuggergdbmi/test/TestApps/WatchesPrg.pas @@ -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} diff --git a/components/lazdebuggergdbmi/test/TestApps/WatchesPrgStruct.inc b/components/lazdebuggergdbmi/test/TestApps/WatchesPrgStruct.inc index 45a08c9263..e78082e53a 100644 --- a/components/lazdebuggergdbmi/test/TestApps/WatchesPrgStruct.inc +++ b/components/lazdebuggergdbmi/test/TestApps/WatchesPrgStruct.inc @@ -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 } diff --git a/components/lazdebuggergdbmi/test/testwatches.pas b/components/lazdebuggergdbmi/test/testwatches.pas index 1d0dd80ded..d63bdd0896 100644 --- a/components/lazdebuggergdbmi/test/testwatches.pas +++ b/components/lazdebuggergdbmi/test/testwatches.pas @@ -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')]