mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-10 07:36:19 +02:00
FpGdbmiDebugger: fixes typecast to class of current method / improve nested procs / tests
git-svn-id: trunk@44711 -
This commit is contained in:
parent
50271115ae
commit
36cf5c18c1
@ -1197,11 +1197,25 @@ begin
|
|||||||
if InfoEntry.ReadName(InfoName) and not InfoEntry.IsArtificial
|
if InfoEntry.ReadName(InfoName) and not InfoEntry.IsArtificial
|
||||||
then begin
|
then begin
|
||||||
if (CompareUtf8BothCase(PNameUpper, PNameLower, InfoName)) then begin
|
if (CompareUtf8BothCase(PNameUpper, PNameLower, InfoName)) then begin
|
||||||
|
// TODO: this is a pascal sperific search order? Or not?
|
||||||
|
// If this is a type with a pointer or ref, need to find the pointer or ref.
|
||||||
|
InfoEntry.GoParent;
|
||||||
|
if InfoEntry.HasValidScope and
|
||||||
|
InfoEntry.GoNamedChildEx(PNameUpper, PNameLower)
|
||||||
|
then begin
|
||||||
|
if InfoEntry.IsAddressInStartScope(FAddress) and not InfoEntry.IsArtificial then begin
|
||||||
|
Result := SymbolToValue(TFpDwarfSymbol.CreateSubClass(AName, InfoEntry));
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
InfoEntry.ScopeIndex := StartScopeIdx;
|
||||||
Result := SymbolToValue(TFpDwarfSymbol.CreateSubClass(AName, InfoEntry));
|
Result := SymbolToValue(TFpDwarfSymbol.CreateSubClass(AName, InfoEntry));
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
tg := InfoEntry.AbbrevTag;
|
tg := InfoEntry.AbbrevTag;
|
||||||
if (tg = DW_TAG_class_type) or (tg = DW_TAG_structure_type) then begin
|
if (tg = DW_TAG_class_type) or (tg = DW_TAG_structure_type) then begin
|
||||||
if FindSymbolInStructure(AName,PNameUpper, PNameLower, InfoEntry, Result) then
|
if FindSymbolInStructure(AName,PNameUpper, PNameLower, InfoEntry, Result) then
|
||||||
|
@ -72,8 +72,8 @@ var
|
|||||||
StartScopeIdx: Integer;
|
StartScopeIdx: Integer;
|
||||||
ParentFpVal: TFpDbgValue;
|
ParentFpVal: TFpDbgValue;
|
||||||
SearchCtx: TFpDwarfFreePascalAddressContext;
|
SearchCtx: TFpDwarfFreePascalAddressContext;
|
||||||
pfp, fp, pc: TDbgPtr;
|
par_fp, cur_fp, prev_fp, pc: TDbgPtr;
|
||||||
i: Integer;
|
d, i: Integer;
|
||||||
ParentFpSym: TFpDwarfSymbol;
|
ParentFpSym: TFpDwarfSymbol;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
@ -104,7 +104,6 @@ begin
|
|||||||
|
|
||||||
|
|
||||||
InfoEntry.ScopeIndex := StartScopeIdx;
|
InfoEntry.ScopeIndex := StartScopeIdx;
|
||||||
// TODO: cache
|
|
||||||
if not InfoEntry.GoNamedChildEx(@parentfp[1], @parentfp[1]) then begin
|
if not InfoEntry.GoNamedChildEx(@parentfp[1], @parentfp[1]) then begin
|
||||||
FOuterNotFound := True;
|
FOuterNotFound := True;
|
||||||
exit;
|
exit;
|
||||||
@ -121,10 +120,10 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
pfp := ParentFpVal.AsCardinal;
|
par_fp := ParentFpVal.AsCardinal;
|
||||||
ParentFpSym.ReleaseReference;
|
ParentFpSym.ReleaseReference;
|
||||||
DebugLn(['pfp=',pfp]);
|
DebugLn(['par_fp=',par_fp]);
|
||||||
if pfp = 0 then begin
|
if par_fp = 0 then begin
|
||||||
DebugLn('no ordinal for parentfp');
|
DebugLn('no ordinal for parentfp');
|
||||||
FOuterNotFound := True;
|
FOuterNotFound := True;
|
||||||
exit;
|
exit;
|
||||||
@ -133,18 +132,27 @@ begin
|
|||||||
i := StackFrame + 1;
|
i := StackFrame + 1;
|
||||||
SearchCtx := TFpDwarfFreePascalAddressContext.Create(ThreadId, i, 0, Symbol, Dwarf);
|
SearchCtx := TFpDwarfFreePascalAddressContext.Create(ThreadId, i, 0, Symbol, Dwarf);
|
||||||
|
|
||||||
fp := 0;
|
cur_fp := 0;
|
||||||
while not (fp = pfp) do begin
|
if MemManager.ReadRegister(RegFp, cur_fp, Self) then begin
|
||||||
SearchCtx.StackFrame := i;
|
if cur_fp > par_fp then
|
||||||
// TODO: get reg num via memreader name-to-num
|
d := -1 // cur_fp must go down
|
||||||
if not MemManager.ReadRegister(RegFp, fp, SearchCtx) then
|
else
|
||||||
break;
|
d := 1; // cur_fp must go up
|
||||||
inc(i);
|
while not (cur_fp = par_fp) do begin
|
||||||
if i > StackFrame + 100 then break; // something wrong? // TODO better check
|
SearchCtx.StackFrame := i;
|
||||||
|
// TODO: get reg num via memreader name-to-num
|
||||||
|
prev_fp := cur_fp;
|
||||||
|
if not MemManager.ReadRegister(RegFp, cur_fp, SearchCtx) then
|
||||||
|
break;
|
||||||
|
inc(i);
|
||||||
|
if (cur_fp = prev_fp) or ((cur_fp < prev_fp) xor (d = -1)) then
|
||||||
|
break; // wrong direction
|
||||||
|
if i > StackFrame + 200 then break; // something wrong? // TODO better check
|
||||||
|
end;
|
||||||
|
dec(i);
|
||||||
end;
|
end;
|
||||||
dec(i);
|
|
||||||
|
|
||||||
if (pfp <> fp) or
|
if (par_fp <> cur_fp) or (cur_fp = 0) or
|
||||||
not MemManager.ReadRegister(RegPc, pc, SearchCtx)
|
not MemManager.ReadRegister(RegPc, pc, SearchCtx)
|
||||||
then begin
|
then begin
|
||||||
FOuterNotFound := True;
|
FOuterNotFound := True;
|
||||||
|
@ -456,16 +456,21 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{%region Fields / Glob / ... }
|
{%region Fields / Glob / ... }
|
||||||
for i := 0 to 5 do begin
|
for i := 0 to 7 do begin
|
||||||
case BrkIdx of
|
case BrkIdx of
|
||||||
// Simple_NoneNested
|
//Class1
|
||||||
4, 5: if not (i in [1]) then continue; // Only Global /// TODO: test for error
|
4, 5: // Simple_NoneNested
|
||||||
// Test2Method
|
if not (i in [1]) then continue;
|
||||||
8..13: if not (i in [0, 1, 5, 6]) then continue;
|
6..7: // Class1.Test0Method
|
||||||
// Class[12].Test0Method
|
if not (i in [1, 6]) then continue;
|
||||||
6..7, 14..15: if not (i in [1]) then continue; // Only Global /// TODO: test for error
|
//Class2
|
||||||
// Class0.Test0Method
|
8..13: // Class2.Test2Method
|
||||||
16..17: if not (i in [1]) then continue; // Only Global /// TODO: test for error
|
if not (i in [0..1, 5..8]) then continue;
|
||||||
|
14..15: // Class2.Test0Method
|
||||||
|
if not (i in [1, 6..7]) then continue;
|
||||||
|
//Class0
|
||||||
|
16..17: // Class0.Test0Method
|
||||||
|
if not (i in [1]) then continue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
case i of
|
case i of
|
||||||
@ -475,8 +480,8 @@ begin
|
|||||||
3: s := 'VArg_';
|
3: s := 'VArg_';
|
||||||
4: s := 'Local_';
|
4: s := 'Local_';
|
||||||
5: s := 'self.Field_';
|
5: s := 'self.Field_';
|
||||||
//6: s := 'TSimpleClass1(self).Field_';
|
6: s := 'TSimpleClass1(self).Field_';
|
||||||
//7: s := 'TSimpleClass2(self).Field_';
|
7: s := 'TSimpleClass2(self).Field_';
|
||||||
//8: s := 'TSimpleClass0(self).Field_';
|
//8: s := 'TSimpleClass0(self).Field_';
|
||||||
// 6: passed in object / var arg object
|
// 6: passed in object / var arg object
|
||||||
// unit.glob
|
// unit.glob
|
||||||
|
Loading…
Reference in New Issue
Block a user