mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-15 22:03:11 +02:00
FPDebug: starting arrays
git-svn-id: trunk@44187 -
This commit is contained in:
parent
d2a52610bd
commit
499e59ec52
@ -600,6 +600,8 @@ type
|
|||||||
function MemManager: TFpDbgMemManager; inline;
|
function MemManager: TFpDbgMemManager; inline;
|
||||||
function AddressSize: Byte; inline;
|
function AddressSize: Byte; inline;
|
||||||
protected
|
protected
|
||||||
|
function DataAddr: TFpDbgMemLocation;
|
||||||
|
function OrdOrDataAddr: TFpDbgMemLocation;
|
||||||
function GetDwarfDataAddress(out AnAddress: TFpDbgMemLocation; ATargetType: TDbgDwarfTypeIdentifier = nil): Boolean;
|
function GetDwarfDataAddress(out AnAddress: TFpDbgMemLocation; ATargetType: TDbgDwarfTypeIdentifier = nil): Boolean;
|
||||||
procedure Reset; virtual;
|
procedure Reset; virtual;
|
||||||
function GetFieldFlags: TDbgSymbolValueFieldFlags; override;
|
function GetFieldFlags: TDbgSymbolValueFieldFlags; override;
|
||||||
@ -630,8 +632,6 @@ type
|
|||||||
private
|
private
|
||||||
FSize: Integer;
|
FSize: Integer;
|
||||||
protected
|
protected
|
||||||
function OrdOrDataAddr: TFpDbgMemLocation;
|
|
||||||
function DataAddr: TFpDbgMemLocation;
|
|
||||||
function CanUseTypeCastAddress: Boolean;
|
function CanUseTypeCastAddress: Boolean;
|
||||||
function GetFieldFlags: TDbgSymbolValueFieldFlags; override;
|
function GetFieldFlags: TDbgSymbolValueFieldFlags; override;
|
||||||
function GetSize: Integer; override;
|
function GetSize: Integer; override;
|
||||||
@ -825,6 +825,8 @@ type
|
|||||||
protected
|
protected
|
||||||
function GetFieldFlags: TDbgSymbolValueFieldFlags; override;
|
function GetFieldFlags: TDbgSymbolValueFieldFlags; override;
|
||||||
function GetKind: TDbgSymbolKind; override;
|
function GetKind: TDbgSymbolKind; override;
|
||||||
|
function GetAsCardinal: QWord; override;
|
||||||
|
function GetDataAddress: TFpDbgMemLocation; override;
|
||||||
function GetMember(AIndex: Integer): TDbgSymbolValue; override;
|
function GetMember(AIndex: Integer): TDbgSymbolValue; override;
|
||||||
function GetMemberEx(AIndex: array of Int64): TDbgSymbolValue; override;
|
function GetMemberEx(AIndex: array of Int64): TDbgSymbolValue; override;
|
||||||
function GetMemberCount: Integer; override;
|
function GetMemberCount: Integer; override;
|
||||||
@ -1868,6 +1870,8 @@ function TDbgDwarfArraySymbolValue.GetFieldFlags: TDbgSymbolValueFieldFlags;
|
|||||||
begin
|
begin
|
||||||
Result := inherited GetFieldFlags;
|
Result := inherited GetFieldFlags;
|
||||||
Result := Result + [svfMembers];
|
Result := Result + [svfMembers];
|
||||||
|
if (TypeInfo <> nil) and (sfDynArray in TypeInfo.Flags) then
|
||||||
|
Result := Result + [svfOrdinal, svfDataAddress];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgDwarfArraySymbolValue.GetKind: TDbgSymbolKind;
|
function TDbgDwarfArraySymbolValue.GetKind: TDbgSymbolKind;
|
||||||
@ -1875,6 +1879,17 @@ begin
|
|||||||
Result := skArray;
|
Result := skArray;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TDbgDwarfArraySymbolValue.GetAsCardinal: QWord;
|
||||||
|
begin
|
||||||
|
Result := QWord(LocToAddrOrNil(DataAddress));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TDbgDwarfArraySymbolValue.GetDataAddress: TFpDbgMemLocation;
|
||||||
|
begin
|
||||||
|
//Result := GetDwarfDataAddress;
|
||||||
|
Result := MemManager.ReadAddress(OrdOrDataAddr, AddressSize); // TODO: cache
|
||||||
|
end;
|
||||||
|
|
||||||
function TDbgDwarfArraySymbolValue.GetMember(AIndex: Integer): TDbgSymbolValue;
|
function TDbgDwarfArraySymbolValue.GetMember(AIndex: Integer): TDbgSymbolValue;
|
||||||
begin
|
begin
|
||||||
Result := GetMemberEx([AIndex]);
|
Result := GetMemberEx([AIndex]);
|
||||||
@ -1890,12 +1905,12 @@ begin
|
|||||||
if not IsReadableLoc(Addr) then exit;
|
if not IsReadableLoc(Addr) then exit;
|
||||||
|
|
||||||
if (FAddrObj = nil) or (FAddrObj.RefCount > 1) then begin
|
if (FAddrObj = nil) or (FAddrObj.RefCount > 1) then begin
|
||||||
FAddrObj.ReleaseReference;
|
FAddrObj.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FAddrObj, 'TDbgDwarfArraySymbolValue'){$ENDIF};
|
||||||
FAddrObj := TDbgDwarfSymbolValueConstAddress.Create(Addr);
|
FAddrObj := TDbgDwarfSymbolValueConstAddress.Create(Addr);
|
||||||
|
{$IFDEF WITH_REFCOUNT_DEBUG}FAddrObj.DbgRenameReference(@FAddrObj, 'TDbgDwarfArraySymbolValue');{$ENDIF}
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
FAddrObj.Update(Addr);
|
FAddrObj.Update(Addr);
|
||||||
FAddrObj.AddReference;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if (FResVal = nil) or (FResVal.RefCount > 1) then begin
|
if (FResVal = nil) or (FResVal.RefCount > 1) then begin
|
||||||
@ -1903,25 +1918,36 @@ begin
|
|||||||
FResVal := FOwner.TypeInfo.TypeCastValue(FAddrObj);
|
FResVal := FOwner.TypeInfo.TypeCastValue(FAddrObj);
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
TDbgDwarfSymbolValue(FResVal).SetTypeCastInfo(TDbgDwarfTypeIdentifier(FOwner), FAddrObj);
|
TDbgDwarfSymbolValue(FResVal).SetTypeCastInfo(TDbgDwarfTypeIdentifier(FOwner.TypeInfo), FAddrObj);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
FAddrObj.ReleaseReference;
|
|
||||||
Result := FResVal;
|
Result := FResVal;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgDwarfArraySymbolValue.GetMemberCount: Integer;
|
function TDbgDwarfArraySymbolValue.GetMemberCount: Integer;
|
||||||
var
|
var
|
||||||
t: TDbgSymbol;
|
t, t2: TDbgSymbol;
|
||||||
|
Addr: TFpDbgMemLocation;
|
||||||
|
i: Int64;
|
||||||
begin
|
begin
|
||||||
Result := 0;
|
Result := 0;
|
||||||
t := TypeInfo;
|
t := TypeInfo;
|
||||||
if t.MemberCount < 1 then
|
if t.MemberCount < 1 then
|
||||||
exit;
|
exit;
|
||||||
t := t.Member[0];
|
t2 := t.Member[0];
|
||||||
if not t.HasBounds then
|
if not t2.HasBounds then begin
|
||||||
|
if (sfDynArray in t.Flags) and (AsCardinal <> 0) and
|
||||||
|
GetDwarfDataAddress(Addr, TDbgDwarfTypeIdentifier(FOwner))
|
||||||
|
then begin
|
||||||
|
Addr.Address := Addr.Address - 4;
|
||||||
|
if MemManager.ReadSignedInt(Addr, 4, i) then begin
|
||||||
|
Result := Integer(i);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
exit;
|
exit;
|
||||||
Result := t.OrdHighBound - t.OrdLowBound + 1;
|
end;
|
||||||
|
Result := t2.OrdHighBound - t2.OrdLowBound + 1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgDwarfArraySymbolValue.GetMemberCountEx(AIndex: array of Int64): Integer;
|
function TDbgDwarfArraySymbolValue.GetMemberCountEx(AIndex: array of Int64): Integer;
|
||||||
@ -1972,6 +1998,7 @@ end;
|
|||||||
|
|
||||||
destructor TDbgDwarfArraySymbolValue.Destroy;
|
destructor TDbgDwarfArraySymbolValue.Destroy;
|
||||||
begin
|
begin
|
||||||
|
FAddrObj.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FAddrObj, 'TDbgDwarfArraySymbolValue'){$ENDIF};
|
||||||
FResVal.ReleaseReference;
|
FResVal.ReleaseReference;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
@ -2135,25 +2162,6 @@ end;
|
|||||||
|
|
||||||
{ TDbgDwarfSizedSymbolValue }
|
{ TDbgDwarfSizedSymbolValue }
|
||||||
|
|
||||||
function TDbgDwarfSizedSymbolValue.OrdOrDataAddr: TFpDbgMemLocation;
|
|
||||||
begin
|
|
||||||
if HasTypeCastInfo and (svfOrdinal in FTypeCastSourceValue.FieldFlags) then
|
|
||||||
Result := ConstLoc(FTypeCastSourceValue.AsCardinal)
|
|
||||||
else
|
|
||||||
Result := DataAddr;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TDbgDwarfSizedSymbolValue.DataAddr: TFpDbgMemLocation;
|
|
||||||
begin
|
|
||||||
if FValueSymbol <> nil then
|
|
||||||
Result := FValueSymbol.Address
|
|
||||||
else
|
|
||||||
if HasTypeCastInfo then
|
|
||||||
Result := FTypeCastSourceValue.Address
|
|
||||||
else
|
|
||||||
Result := InvalidLoc;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TDbgDwarfSizedSymbolValue.CanUseTypeCastAddress: Boolean;
|
function TDbgDwarfSizedSymbolValue.CanUseTypeCastAddress: Boolean;
|
||||||
begin
|
begin
|
||||||
Result := True;
|
Result := True;
|
||||||
@ -2750,6 +2758,25 @@ begin
|
|||||||
Result := FOwner.FCU.FAddressSize;
|
Result := FOwner.FCU.FAddressSize;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TDbgDwarfSymbolValue.DataAddr: TFpDbgMemLocation;
|
||||||
|
begin
|
||||||
|
if FValueSymbol <> nil then
|
||||||
|
Result := FValueSymbol.Address
|
||||||
|
else
|
||||||
|
if HasTypeCastInfo then
|
||||||
|
Result := FTypeCastSourceValue.Address
|
||||||
|
else
|
||||||
|
Result := InvalidLoc;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TDbgDwarfSymbolValue.OrdOrDataAddr: TFpDbgMemLocation;
|
||||||
|
begin
|
||||||
|
if HasTypeCastInfo and (svfOrdinal in FTypeCastSourceValue.FieldFlags) then
|
||||||
|
Result := ConstLoc(FTypeCastSourceValue.AsCardinal)
|
||||||
|
else
|
||||||
|
Result := DataAddr;
|
||||||
|
end;
|
||||||
|
|
||||||
function TDbgDwarfSymbolValue.GetDwarfDataAddress(out AnAddress: TFpDbgMemLocation;
|
function TDbgDwarfSymbolValue.GetDwarfDataAddress(out AnAddress: TFpDbgMemLocation;
|
||||||
ATargetType: TDbgDwarfTypeIdentifier): Boolean;
|
ATargetType: TDbgDwarfTypeIdentifier): Boolean;
|
||||||
var
|
var
|
||||||
|
@ -403,7 +403,7 @@ end;
|
|||||||
|
|
||||||
function TDbgSymbolValueConstAddress.GetFieldFlags: TDbgSymbolValueFieldFlags;
|
function TDbgSymbolValueConstAddress.GetFieldFlags: TDbgSymbolValueFieldFlags;
|
||||||
begin
|
begin
|
||||||
Result := [svfAddress, svfSizeOfPointer]
|
Result := [svfAddress]
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgSymbolValueConstAddress.GetAddress: TFpDbgMemLocation;
|
function TDbgSymbolValueConstAddress.GetAddress: TFpDbgMemLocation;
|
||||||
|
@ -552,6 +552,33 @@ function PrintPasValue(out APrintedValue: String; AResValue: TDbgSymbolValue;
|
|||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure DoArray;
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
i: Integer;
|
||||||
|
m: TDbgSymbolValue;
|
||||||
|
c: Integer;
|
||||||
|
begin
|
||||||
|
APrintedValue := '';
|
||||||
|
c := AResValue.MemberCount;
|
||||||
|
if c > 500 then c := 500;
|
||||||
|
// TODO: low-ord to high ord
|
||||||
|
for i := 0 to c - 1 do begin
|
||||||
|
m := AResValue.Member[i];
|
||||||
|
if m <> nil then
|
||||||
|
PrintPasValue(s, m, AnAddrSize, AFlags)
|
||||||
|
else
|
||||||
|
s := '{error}';
|
||||||
|
if APrintedValue = ''
|
||||||
|
then APrintedValue := s
|
||||||
|
else APrintedValue := APrintedValue + ', ' + s;
|
||||||
|
end;
|
||||||
|
if c < AResValue.MemberCount then
|
||||||
|
APrintedValue := APrintedValue + ', ...';
|
||||||
|
APrintedValue := '(' + APrintedValue + ')';
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
case AResValue.Kind of
|
case AResValue.Kind of
|
||||||
@ -576,7 +603,7 @@ begin
|
|||||||
skObject: DoStructure;
|
skObject: DoStructure;
|
||||||
skClass: DoStructure;
|
skClass: DoStructure;
|
||||||
skInterface: ;
|
skInterface: ;
|
||||||
skArray: ;
|
skArray: DoArray;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
@ -1290,8 +1290,8 @@ var
|
|||||||
if not PrintPasValue(AResText, ResValue, ctx.SizeOfAddress, []) then
|
if not PrintPasValue(AResText, ResValue, ctx.SizeOfAddress, []) then
|
||||||
exit;
|
exit;
|
||||||
ATypeInfo := TDBGType.Create(skPointer, ResTypeName);
|
ATypeInfo := TDBGType.Create(skPointer, ResTypeName);
|
||||||
|
ATypeInfo.Value.AsPointer := Pointer(ResValue.AsCardinal); // TODO: no cut off
|
||||||
ATypeInfo.Value.AsString := AResText;
|
ATypeInfo.Value.AsString := AResText;
|
||||||
//ATypeInfo.Value.AsPointer := ; // ???
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure DoSimple;
|
procedure DoSimple;
|
||||||
@ -1427,6 +1427,17 @@ var
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure DoArray;
|
||||||
|
begin
|
||||||
|
if not PrintPasValue(AResText, ResValue, ctx.SizeOfAddress, []) then
|
||||||
|
exit;
|
||||||
|
ATypeInfo := TDBGType.Create(skArray, ResTypeName);
|
||||||
|
ATypeInfo.Value.AsString := AResText;
|
||||||
|
//ATypeInfo.Len;
|
||||||
|
//ATypeInfo.BoundLow;
|
||||||
|
//ATypeInfo.BoundHigh;
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
ATypeInfo := nil;
|
ATypeInfo := nil;
|
||||||
@ -1472,7 +1483,7 @@ begin
|
|||||||
skObject: DoClass;
|
skObject: DoClass;
|
||||||
skClass: DoClass;
|
skClass: DoClass;
|
||||||
skInterface: ;
|
skInterface: ;
|
||||||
skArray: ;
|
skArray: DoArray;
|
||||||
end;
|
end;
|
||||||
if not IsWatchValueAlive then exit;
|
if not IsWatchValueAlive then exit;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user