mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-10 20:37:43 +02:00
FpDebug: implement watching bitpacked array/record
git-svn-id: trunk@62012 -
This commit is contained in:
parent
f96c6b9f66
commit
cbe21ff4f3
File diff suppressed because it is too large
Load Diff
@ -191,6 +191,8 @@ const
|
|||||||
DW_AT_elemental = $66 ; // flag
|
DW_AT_elemental = $66 ; // flag
|
||||||
DW_AT_pure = $67 ; // flag
|
DW_AT_pure = $67 ; // flag
|
||||||
DW_AT_recursive = $68 ; // flag
|
DW_AT_recursive = $68 ; // flag
|
||||||
|
// -- DWARF 4 --
|
||||||
|
DW_AT_data_bit_offset = $6b ; // constant // block, constant, reference
|
||||||
// --- ---
|
// --- ---
|
||||||
DW_AT_lo_user = $2000; // ---
|
DW_AT_lo_user = $2000; // ---
|
||||||
DW_AT_hi_user = $3fff; // ---
|
DW_AT_hi_user = $3fff; // ---
|
||||||
|
@ -1788,6 +1788,7 @@ procedure TDwarfLocationStack.PushConst(const AVal: TDBGPtr);
|
|||||||
begin
|
begin
|
||||||
if Length(FList) <= FCount then
|
if Length(FList) <= FCount then
|
||||||
IncCapacity;
|
IncCapacity;
|
||||||
|
FList[FCount] := Default(TFpDbgMemLocation);
|
||||||
with FList[FCount] do begin
|
with FList[FCount] do begin
|
||||||
Address := AVal;
|
Address := AVal;
|
||||||
MType := mlfConstant;
|
MType := mlfConstant;
|
||||||
@ -1799,6 +1800,7 @@ procedure TDwarfLocationStack.PushTargetMem(const AVal: TDBGPtr);
|
|||||||
begin
|
begin
|
||||||
if Length(FList) <= FCount then
|
if Length(FList) <= FCount then
|
||||||
IncCapacity;
|
IncCapacity;
|
||||||
|
FList[FCount] := Default(TFpDbgMemLocation);
|
||||||
with FList[FCount] do begin
|
with FList[FCount] do begin
|
||||||
Address := AVal;
|
Address := AVal;
|
||||||
MType := mlfTargetMem;
|
MType := mlfTargetMem;
|
||||||
@ -1900,7 +1902,7 @@ var
|
|||||||
begin
|
begin
|
||||||
//TODO: zero fill / sign extend
|
//TODO: zero fill / sign extend
|
||||||
if (ASize > SizeOf(AValue)) or (ASize > AddrSize) then exit(False);
|
if (ASize > SizeOf(AValue)) or (ASize > AddrSize) then exit(False);
|
||||||
Result := FMemManager.ReadAddress(AnAddress, ASize, AValue, FContext);
|
Result := FMemManager.ReadAddress(AnAddress, SizeVal(ASize), AValue, FContext);
|
||||||
if not Result then
|
if not Result then
|
||||||
SetError;
|
SetError;
|
||||||
end;
|
end;
|
||||||
@ -1909,7 +1911,7 @@ var
|
|||||||
begin
|
begin
|
||||||
//TODO: zero fill / sign extend
|
//TODO: zero fill / sign extend
|
||||||
if (ASize > SizeOf(AValue)) or (ASize > AddrSize) then exit(False);
|
if (ASize > SizeOf(AValue)) or (ASize > AddrSize) then exit(False);
|
||||||
AValue := FMemManager.ReadAddressEx(AnAddress, AnAddrSpace, ASize, FContext);
|
AValue := FMemManager.ReadAddressEx(AnAddress, AnAddrSpace, SizeVal(ASize), FContext);
|
||||||
Result := IsValidLoc(AValue);
|
Result := IsValidLoc(AValue);
|
||||||
if not Result then
|
if not Result then
|
||||||
SetError;
|
SetError;
|
||||||
|
@ -118,7 +118,7 @@ type
|
|||||||
function GetDataAddressNext(AValueObj: TFpValueDwarf; var AnAddress: TFpDbgMemLocation;
|
function GetDataAddressNext(AValueObj: TFpValueDwarf; var AnAddress: TFpDbgMemLocation;
|
||||||
out ADoneWork: Boolean; ATargetType: TFpSymbolDwarfType): Boolean; override;
|
out ADoneWork: Boolean; ATargetType: TFpSymbolDwarfType): Boolean; override;
|
||||||
function GetTypedValueObject(ATypeCast: Boolean; AnOuterType: TFpSymbolDwarfType = nil): TFpValueDwarf; override;
|
function GetTypedValueObject(ATypeCast: Boolean; AnOuterType: TFpSymbolDwarfType = nil): TFpValueDwarf; override;
|
||||||
function DataSize: Integer; override;
|
function DataSize: TFpDbgValueSize; override;
|
||||||
public
|
public
|
||||||
property IsInternalPointer: Boolean read GetIsInternalPointer write FIsInternalPointer; // Class (also DynArray, but DynArray is handled without this)
|
property IsInternalPointer: Boolean read GetIsInternalPointer write FIsInternalPointer; // Class (also DynArray, but DynArray is handled without this)
|
||||||
end;
|
end;
|
||||||
@ -668,7 +668,7 @@ begin
|
|||||||
Result := AValueObj.MemManager <> nil;
|
Result := AValueObj.MemManager <> nil;
|
||||||
if not Result then
|
if not Result then
|
||||||
exit;
|
exit;
|
||||||
AnAddress := AValueObj.MemManager.ReadAddress(AnAddress, CompilationUnit.AddressSize);
|
AnAddress := AValueObj.MemManager.ReadAddress(AnAddress, SizeVal(CompilationUnit.AddressSize));
|
||||||
Result := IsValidLoc(AnAddress);
|
Result := IsValidLoc(AnAddress);
|
||||||
|
|
||||||
if (not Result) and
|
if (not Result) and
|
||||||
@ -689,14 +689,14 @@ begin
|
|||||||
Result := inherited GetTypedValueObject(ATypeCast, AnOuterType);
|
Result := inherited GetTypedValueObject(ATypeCast, AnOuterType);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpSymbolDwarfFreePascalTypePointer.DataSize: Integer;
|
function TFpSymbolDwarfFreePascalTypePointer.DataSize: TFpDbgValueSize;
|
||||||
var
|
var
|
||||||
Size: QWord;
|
Size: TFpDbgValueSize;
|
||||||
begin
|
begin
|
||||||
if Kind = skClass then begin
|
if Kind = skClass then begin
|
||||||
// TODO: get a value object // though fpc does not yet write variable sizes
|
// TODO: get a value object // though fpc does not yet write variable sizes
|
||||||
if not NestedTypeInfo.ReadSize(nil, Size) then begin
|
if not NestedTypeInfo.ReadSize(nil, Size) then begin
|
||||||
Result := 0;
|
Result := ZeroSize;
|
||||||
SetLastError(CreateError(fpErrAnyError, ['unknown size']));
|
SetLastError(CreateError(fpErrAnyError, ['unknown size']));
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@ -780,7 +780,8 @@ end;
|
|||||||
|
|
||||||
function TFpValueDwarfV2FreePascalShortString.GetAsString: AnsiString;
|
function TFpValueDwarfV2FreePascalShortString.GetAsString: AnsiString;
|
||||||
var
|
var
|
||||||
len, Size: QWord;
|
len: QWord;
|
||||||
|
Size: TFpDbgValueSize;
|
||||||
LenSym, StSym: TFpValueDwarf;
|
LenSym, StSym: TFpValueDwarf;
|
||||||
begin
|
begin
|
||||||
if FValueDone then
|
if FValueDone then
|
||||||
@ -795,7 +796,7 @@ begin
|
|||||||
SetLastError(CreateError(fpErrAnyError));
|
SetLastError(CreateError(fpErrAnyError));
|
||||||
exit('');
|
exit('');
|
||||||
end;
|
end;
|
||||||
if (Size < 0) or (len > Size) then begin
|
if (Size < len) then begin
|
||||||
SetLastError(CreateError(fpErrAnyError));
|
SetLastError(CreateError(fpErrAnyError));
|
||||||
exit('');
|
exit('');
|
||||||
end;
|
end;
|
||||||
@ -806,7 +807,7 @@ begin
|
|||||||
|
|
||||||
SetLength(Result, len);
|
SetLength(Result, len);
|
||||||
if len > 0 then
|
if len > 0 then
|
||||||
if not MemManager.ReadMemory(StSym.DataAddress, len, @Result[1]) then begin
|
if not MemManager.ReadMemory(StSym.DataAddress, SizeVal(len), @Result[1]) then begin
|
||||||
Result := ''; // TODO: error
|
Result := ''; // TODO: error
|
||||||
SetLastError(MemManager.LastError);
|
SetLastError(MemManager.LastError);
|
||||||
StSym.ReleaseReference;
|
StSym.ReleaseReference;
|
||||||
@ -907,7 +908,7 @@ begin
|
|||||||
exit(0); // dyn array, but bad data
|
exit(0); // dyn array, but bad data
|
||||||
Addr.Address := Addr.Address - AddressSize;
|
Addr.Address := Addr.Address - AddressSize;
|
||||||
//debugln(['TFpValueDwarfArray.GetMemberCount XXXXXXXXXXXXXXX dwarf 2 read len']);
|
//debugln(['TFpValueDwarfArray.GetMemberCount XXXXXXXXXXXXXXX dwarf 2 read len']);
|
||||||
if MemManager.ReadSignedInt(Addr, AddressSize, h) then begin
|
if MemManager.ReadSignedInt(Addr, SizeVal(AddressSize), h) then begin
|
||||||
Result := Integer(h)+1;
|
Result := Integer(h)+1;
|
||||||
exit;
|
exit;
|
||||||
end
|
end
|
||||||
@ -928,7 +929,7 @@ var
|
|||||||
Info: TDwarfInformationEntry;
|
Info: TDwarfInformationEntry;
|
||||||
t: Cardinal;
|
t: Cardinal;
|
||||||
t2: TFpSymbol;
|
t2: TFpSymbol;
|
||||||
CharSize: QWord;
|
CharSize: TFpDbgValueSize;
|
||||||
begin
|
begin
|
||||||
Result := FArrayOrStringType;
|
Result := FArrayOrStringType;
|
||||||
if Result <> iasUnknown then
|
if Result <> iasUnknown then
|
||||||
@ -959,8 +960,8 @@ begin
|
|||||||
// TODO: check the location parser, if it is a reference
|
// TODO: check the location parser, if it is a reference
|
||||||
//FIsShortString := iasShortString;
|
//FIsShortString := iasShortString;
|
||||||
if not t2.ReadSize(nil, CharSize) then
|
if not t2.ReadSize(nil, CharSize) then
|
||||||
CharSize := 0; // TODO: error
|
CharSize := ZeroSize; // TODO: error
|
||||||
if (CharSize = 2) then
|
if (CharSize.Size = 2) then
|
||||||
FArrayOrStringType := iasUnicodeString
|
FArrayOrStringType := iasUnicodeString
|
||||||
else
|
else
|
||||||
FArrayOrStringType := iasAnsiString;
|
FArrayOrStringType := iasAnsiString;
|
||||||
@ -1095,7 +1096,7 @@ begin
|
|||||||
// read data and check for DW_OP_shr ?
|
// read data and check for DW_OP_shr ?
|
||||||
Addr2 := Addr;
|
Addr2 := Addr;
|
||||||
Addr2.Address := Addr2.Address - AddressSize;
|
Addr2.Address := Addr2.Address - AddressSize;
|
||||||
if MemManager.ReadSignedInt(Addr2, AddressSize, i) then begin
|
if MemManager.ReadSignedInt(Addr2, SizeVal(AddressSize), i) then begin
|
||||||
if (i shr 1) = HighBound then
|
if (i shr 1) = HighBound then
|
||||||
HighBound := i;
|
HighBound := i;
|
||||||
end
|
end
|
||||||
@ -1116,7 +1117,7 @@ begin
|
|||||||
if t.Kind = skWideString then begin
|
if t.Kind = skWideString then begin
|
||||||
SetLength(WResult, HighBound-LowBound+1);
|
SetLength(WResult, HighBound-LowBound+1);
|
||||||
|
|
||||||
if not MemManager.ReadMemory(Addr, (HighBound-LowBound+1)*2, @WResult[1]) then begin
|
if not MemManager.ReadMemory(Addr, SizeVal((HighBound-LowBound+1)*2), @WResult[1]) then begin
|
||||||
WResult := '';
|
WResult := '';
|
||||||
SetLastError(MemManager.LastError);
|
SetLastError(MemManager.LastError);
|
||||||
end;
|
end;
|
||||||
@ -1124,7 +1125,7 @@ begin
|
|||||||
end else begin
|
end else begin
|
||||||
SetLength(Result, HighBound-LowBound+1);
|
SetLength(Result, HighBound-LowBound+1);
|
||||||
|
|
||||||
if not MemManager.ReadMemory(Addr, HighBound-LowBound+1, @Result[1]) then begin
|
if not MemManager.ReadMemory(Addr, SizeVal(HighBound-LowBound+1), @Result[1]) then begin
|
||||||
Result := '';
|
Result := '';
|
||||||
SetLastError(MemManager.LastError);
|
SetLastError(MemManager.LastError);
|
||||||
end;
|
end;
|
||||||
|
@ -96,7 +96,7 @@ type
|
|||||||
private
|
private
|
||||||
FEvalFlags: set of (efSizeDone, efSizeUnavail);
|
FEvalFlags: set of (efSizeDone, efSizeUnavail);
|
||||||
FLastError: TFpError;
|
FLastError: TFpError;
|
||||||
FSize: QWord;
|
FSize: TFpDbgValueSize;
|
||||||
protected
|
protected
|
||||||
procedure Reset; virtual; // keeps lastmember and structureninfo
|
procedure Reset; virtual; // keeps lastmember and structureninfo
|
||||||
procedure SetLastError(ALastError: TFpError);
|
procedure SetLastError(ALastError: TFpError);
|
||||||
@ -112,9 +112,9 @@ type
|
|||||||
function GetAsFloat: Extended; virtual;
|
function GetAsFloat: Extended; virtual;
|
||||||
|
|
||||||
function GetAddress: TFpDbgMemLocation; virtual;
|
function GetAddress: TFpDbgMemLocation; virtual;
|
||||||
function DoGetSize(out ASize: QWord): Boolean; virtual;
|
function DoGetSize(out ASize: TFpDbgValueSize): Boolean; virtual;
|
||||||
function GetDataAddress: TFpDbgMemLocation; virtual;
|
function GetDataAddress: TFpDbgMemLocation; virtual;
|
||||||
function GetDataSize: QWord; virtual;
|
function GetDataSize: TFpDbgValueSize; virtual;
|
||||||
|
|
||||||
function GetHasBounds: Boolean; virtual;
|
function GetHasBounds: Boolean; virtual;
|
||||||
function GetOrdHighBound: Int64; virtual;
|
function GetOrdHighBound: Int64; virtual;
|
||||||
@ -137,7 +137,7 @@ type
|
|||||||
constructor Create;
|
constructor Create;
|
||||||
property RefCount;
|
property RefCount;
|
||||||
|
|
||||||
function GetSize(out ASize: QWord): Boolean; inline;
|
function GetSize(out ASize: TFpDbgValueSize): Boolean; inline;
|
||||||
|
|
||||||
// Kind: determines which types of value are available
|
// Kind: determines which types of value are available
|
||||||
property Kind: TDbgSymbolKind read GetKind;
|
property Kind: TDbgSymbolKind read GetKind;
|
||||||
@ -159,7 +159,7 @@ type
|
|||||||
*)
|
*)
|
||||||
property Address: TFpDbgMemLocation read GetAddress;
|
property Address: TFpDbgMemLocation read GetAddress;
|
||||||
property DataAddress: TFpDbgMemLocation read GetDataAddress; //
|
property DataAddress: TFpDbgMemLocation read GetDataAddress; //
|
||||||
property DataSize: QWord read GetDataSize;
|
property DataSize: TFpDbgValueSize read GetDataSize;
|
||||||
|
|
||||||
property HasBounds: Boolean read GetHasBounds;
|
property HasBounds: Boolean read GetHasBounds;
|
||||||
property OrdLowBound: Int64 read GetOrdLowBound; // need typecast for QuadWord
|
property OrdLowBound: Int64 read GetOrdLowBound; // need typecast for QuadWord
|
||||||
@ -352,7 +352,7 @@ type
|
|||||||
procedure NameNeeded; virtual;
|
procedure NameNeeded; virtual;
|
||||||
procedure SymbolTypeNeeded; virtual;
|
procedure SymbolTypeNeeded; virtual;
|
||||||
procedure AddressNeeded; virtual;
|
procedure AddressNeeded; virtual;
|
||||||
function DoReadSize(const AValueObj: TFpValue; out ASize: QWord): Boolean; virtual;
|
function DoReadSize(const AValueObj: TFpValue; out ASize: TFpDbgValueSize): Boolean; virtual;
|
||||||
procedure TypeInfoNeeded; virtual;
|
procedure TypeInfoNeeded; virtual;
|
||||||
procedure MemberVisibilityNeeded; virtual;
|
procedure MemberVisibilityNeeded; virtual;
|
||||||
//procedure Needed; virtual;
|
//procedure Needed; virtual;
|
||||||
@ -367,7 +367,7 @@ type
|
|||||||
// Memory; Size is also part of type (byte vs word vs ...)
|
// Memory; Size is also part of type (byte vs word vs ...)
|
||||||
property Address: TFpDbgMemLocation read GetAddress; // used by Proc/func
|
property Address: TFpDbgMemLocation read GetAddress; // used by Proc/func
|
||||||
// ReadSize: Return False means no value available, and an error may or may not have occurred
|
// ReadSize: Return False means no value available, and an error may or may not have occurred
|
||||||
function ReadSize(const AValueObj: TFpValue; out ASize: QWord{TDbgPtr}): Boolean; inline;
|
function ReadSize(const AValueObj: TFpValue; out ASize: TFpDbgValueSize): Boolean; inline;
|
||||||
// TypeInfo used by
|
// TypeInfo used by
|
||||||
// stValue (Variable): Type
|
// stValue (Variable): Type
|
||||||
// stType: Pointer: type pointed to / Array: Element Type / Func: Result / Class: itheritance
|
// stType: Pointer: type pointed to / Array: Element Type / Func: Result / Class: itheritance
|
||||||
@ -431,7 +431,7 @@ type
|
|||||||
procedure KindNeeded; override;
|
procedure KindNeeded; override;
|
||||||
procedure NameNeeded; override;
|
procedure NameNeeded; override;
|
||||||
procedure SymbolTypeNeeded; override;
|
procedure SymbolTypeNeeded; override;
|
||||||
function DoReadSize(const AValueObj: TFpValue; out ASize: QWord): Boolean; override;
|
function DoReadSize(const AValueObj: TFpValue; out ASize: TFpDbgValueSize): Boolean; override;
|
||||||
procedure TypeInfoNeeded; override;
|
procedure TypeInfoNeeded; override;
|
||||||
procedure MemberVisibilityNeeded; override;
|
procedure MemberVisibilityNeeded; override;
|
||||||
|
|
||||||
@ -672,7 +672,7 @@ begin
|
|||||||
Result := InvalidLoc;
|
Result := InvalidLoc;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpValue.DoGetSize(out ASize: QWord): Boolean;
|
function TFpValue.DoGetSize(out ASize: TFpDbgValueSize): Boolean;
|
||||||
var
|
var
|
||||||
ti: TFpSymbol;
|
ti: TFpSymbol;
|
||||||
begin
|
begin
|
||||||
@ -691,12 +691,12 @@ begin
|
|||||||
Result := Address;
|
Result := Address;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpValue.GetDataSize: QWord;
|
function TFpValue.GetDataSize: TFpDbgValueSize;
|
||||||
begin
|
begin
|
||||||
GetSize(Result);
|
GetSize(Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpValue.GetSize(out ASize: QWord): Boolean;
|
function TFpValue.GetSize(out ASize: TFpDbgValueSize): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
if (efSizeUnavail in FEvalFlags) then // If there was an error, then LastError should still be set
|
if (efSizeUnavail in FEvalFlags) then // If there was an error, then LastError should still be set
|
||||||
@ -914,8 +914,8 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpSymbol.ReadSize(const AValueObj: TFpValue; out ASize: QWord
|
function TFpSymbol.ReadSize(const AValueObj: TFpValue; out
|
||||||
): Boolean;
|
ASize: TFpDbgValueSize): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := DoReadSize(AValueObj, ASize);
|
Result := DoReadSize(AValueObj, ASize);
|
||||||
end;
|
end;
|
||||||
@ -1120,10 +1120,10 @@ begin
|
|||||||
SetAddress(InvalidLoc);
|
SetAddress(InvalidLoc);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpSymbol.DoReadSize(const AValueObj: TFpValue; out ASize: QWord
|
function TFpSymbol.DoReadSize(const AValueObj: TFpValue; out
|
||||||
): Boolean;
|
ASize: TFpDbgValueSize): Boolean;
|
||||||
begin
|
begin
|
||||||
ASize := 0;
|
ASize := ZeroSize;
|
||||||
Result := False;
|
Result := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1206,7 +1206,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpSymbolForwarder.DoReadSize(const AValueObj: TFpValue; out
|
function TFpSymbolForwarder.DoReadSize(const AValueObj: TFpValue; out
|
||||||
ASize: QWord): Boolean;
|
ASize: TFpDbgValueSize): Boolean;
|
||||||
var
|
var
|
||||||
p: TFpSymbol;
|
p: TFpSymbol;
|
||||||
begin
|
begin
|
||||||
|
@ -92,6 +92,7 @@ begin
|
|||||||
i := FFpSymbolInfo.FSymbolList.IndexOf(AName);
|
i := FFpSymbolInfo.FSymbolList.IndexOf(AName);
|
||||||
if i > -1 then
|
if i > -1 then
|
||||||
begin
|
begin
|
||||||
|
val := Default(TFpDbgMemLocation);
|
||||||
val.Address:=FFpSymbolInfo.FSymbolList.Data[i];
|
val.Address:=FFpSymbolInfo.FSymbolList.Data[i];
|
||||||
val.MType:=mlfTargetMem;
|
val.MType:=mlfTargetMem;
|
||||||
result := TFpValueConstAddress.Create(val);
|
result := TFpValueConstAddress.Create(val);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -767,13 +767,13 @@ function TFpPascalPrettyPrinter.InternalPrintValue(out APrintedValue: String;
|
|||||||
procedure DoInt;
|
procedure DoInt;
|
||||||
var
|
var
|
||||||
n: Integer;
|
n: Integer;
|
||||||
ValSize: QWord;
|
ValSize: TFpDbgValueSize;
|
||||||
begin
|
begin
|
||||||
case ADisplayFormat of
|
case ADisplayFormat of
|
||||||
wdfUnsigned: APrintedValue := IntToStr(QWord(AValue.AsInteger));
|
wdfUnsigned: APrintedValue := IntToStr(QWord(AValue.AsInteger));
|
||||||
wdfHex: begin
|
wdfHex: begin
|
||||||
if (svfSize in AValue.FieldFlags) and AValue.GetSize(ValSize) then
|
if (svfSize in AValue.FieldFlags) and AValue.GetSize(ValSize) then
|
||||||
n := ValSize* 2
|
n := SizeToFullBytes(ValSize)* 2
|
||||||
else begin
|
else begin
|
||||||
n := 16;
|
n := 16;
|
||||||
if QWord(AValue.AsInteger) <= high(Cardinal) then n := 8;
|
if QWord(AValue.AsInteger) <= high(Cardinal) then n := 8;
|
||||||
@ -797,13 +797,13 @@ function TFpPascalPrettyPrinter.InternalPrintValue(out APrintedValue: String;
|
|||||||
procedure DoCardinal;
|
procedure DoCardinal;
|
||||||
var
|
var
|
||||||
n: Integer;
|
n: Integer;
|
||||||
ValSize: QWord;
|
ValSize: TFpDbgValueSize;
|
||||||
begin
|
begin
|
||||||
case ADisplayFormat of
|
case ADisplayFormat of
|
||||||
wdfDecimal: APrintedValue := IntToStr(Int64(AValue.AsCardinal));
|
wdfDecimal: APrintedValue := IntToStr(Int64(AValue.AsCardinal));
|
||||||
wdfHex: begin
|
wdfHex: begin
|
||||||
if (svfSize in AValue.FieldFlags) and AValue.GetSize(ValSize) then
|
if (svfSize in AValue.FieldFlags) and AValue.GetSize(ValSize) then
|
||||||
n := ValSize* 2
|
n := SizeToFullBytes(ValSize)* 2
|
||||||
else begin
|
else begin
|
||||||
n := 16;
|
n := 16;
|
||||||
if AValue.AsCardinal <= high(Cardinal) then n := 8;
|
if AValue.AsCardinal <= high(Cardinal) then n := 8;
|
||||||
@ -960,7 +960,7 @@ function TFpPascalPrettyPrinter.InternalPrintValue(out APrintedValue: String;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
if (MemManager <> nil) and (MemManager.CacheManager <> nil) then
|
if (MemManager <> nil) and (MemManager.CacheManager <> nil) then
|
||||||
Cache := MemManager.CacheManager.AddCache(AValue.DataAddress.Address, AValue.DataSize)
|
Cache := MemManager.CacheManager.AddCache(AValue.DataAddress.Address, SizeToFullBytes(AValue.DataSize))
|
||||||
else
|
else
|
||||||
Cache := nil;
|
Cache := nil;
|
||||||
try
|
try
|
||||||
@ -1114,7 +1114,7 @@ var
|
|||||||
MemSize: Integer;
|
MemSize: Integer;
|
||||||
MemDest: array of Byte;
|
MemDest: array of Byte;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
ValSize: QWord;
|
ValSize: TFpDbgValueSize;
|
||||||
begin
|
begin
|
||||||
if ADBGTypeInfo <> nil then ADBGTypeInfo^ := nil;
|
if ADBGTypeInfo <> nil then ADBGTypeInfo^ := nil;
|
||||||
if ANestLevel > 0 then begin
|
if ANestLevel > 0 then begin
|
||||||
@ -1126,21 +1126,21 @@ begin
|
|||||||
MemAddr := UnInitializedLoc;
|
MemAddr := UnInitializedLoc;
|
||||||
if svfDataAddress in AValue.FieldFlags then begin
|
if svfDataAddress in AValue.FieldFlags then begin
|
||||||
MemAddr := AValue.DataAddress;
|
MemAddr := AValue.DataAddress;
|
||||||
MemSize := AValue.DataSize;
|
MemSize := SizeToFullBytes(AValue.DataSize);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if svfAddress in AValue.FieldFlags then begin
|
if svfAddress in AValue.FieldFlags then begin
|
||||||
MemAddr := AValue.Address;
|
MemAddr := AValue.Address;
|
||||||
if not AValue.GetSize(ValSize) then
|
if not AValue.GetSize(ValSize) then
|
||||||
ValSize := 256;
|
ValSize := SizeVal(256);
|
||||||
MemSize := ValSize;
|
MemSize := SizeToFullBytes(ValSize);
|
||||||
end;
|
end;
|
||||||
if MemSize < ARepeatCount then MemSize := ARepeatCount;
|
if MemSize < ARepeatCount then MemSize := ARepeatCount;
|
||||||
if MemSize <= 0 then MemSize := 256;
|
if MemSize <= 0 then MemSize := 256;
|
||||||
|
|
||||||
if IsTargetAddr(MemAddr) then begin
|
if IsTargetAddr(MemAddr) then begin
|
||||||
SetLength(MemDest, MemSize);
|
SetLength(MemDest, MemSize);
|
||||||
if FMemManager.ReadMemory(MemAddr, MemSize, @MemDest[0]) then begin
|
if FMemManager.ReadMemory(MemAddr, SizeVal(MemSize), @MemDest[0]) then begin
|
||||||
APrintedValue := IntToHex(MemAddr.Address, AnAddressSize*2)+ ':' + LineEnding;
|
APrintedValue := IntToHex(MemAddr.Address, AnAddressSize*2)+ ':' + LineEnding;
|
||||||
for i := 0 to high(MemDest) do begin
|
for i := 0 to high(MemDest) do begin
|
||||||
if (i > 0) and (i mod 16 = 0) then
|
if (i > 0) and (i mod 16 = 0) then
|
||||||
|
@ -522,7 +522,7 @@ type
|
|||||||
protected
|
protected
|
||||||
function GetFieldFlags: TFpValueFieldFlags; override;
|
function GetFieldFlags: TFpValueFieldFlags; override;
|
||||||
function GetAddress: TFpDbgMemLocation; override;
|
function GetAddress: TFpDbgMemLocation; override;
|
||||||
function DoGetSize(out ASize: QWord): Boolean; override;
|
function DoGetSize(out ASize: TFpDbgValueSize): Boolean; override;
|
||||||
function GetAsCardinal: QWord; override; // reads men
|
function GetAsCardinal: QWord; override; // reads men
|
||||||
function GetTypeInfo: TFpSymbol; override; // TODO: Cardinal? Why? // TODO: does not handle AOffset
|
function GetTypeInfo: TFpSymbol; override; // TODO: Cardinal? Why? // TODO: does not handle AOffset
|
||||||
public
|
public
|
||||||
@ -621,7 +621,7 @@ begin
|
|||||||
Result := FValue.AsCardinal
|
Result := FValue.AsCardinal
|
||||||
else
|
else
|
||||||
if svfAddress in f then begin
|
if svfAddress in f then begin
|
||||||
if not FContext.MemManager.ReadUnsignedInt(FValue.Address, FContext.SizeOfAddress, Result) then
|
if not FContext.MemManager.ReadUnsignedInt(FValue.Address, SizeVal(FContext.SizeOfAddress), Result) then
|
||||||
Result := 0;
|
Result := 0;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -638,7 +638,7 @@ var
|
|||||||
ti: TFpSymbol;
|
ti: TFpSymbol;
|
||||||
addr: TFpDbgMemLocation;
|
addr: TFpDbgMemLocation;
|
||||||
Tmp: TFpValueConstAddress;
|
Tmp: TFpValueConstAddress;
|
||||||
Size: QWord;
|
Size: TFpDbgValueSize;
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
|
|
||||||
@ -656,7 +656,7 @@ begin
|
|||||||
SetLastError(CreateError(fpErrAnyError, ['Can index element of unknown size']));
|
SetLastError(CreateError(fpErrAnyError, ['Can index element of unknown size']));
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
AIndex := AIndex * Size;
|
AIndex := AIndex * SizeToFullBytes(Size);
|
||||||
end;
|
end;
|
||||||
addr.Address := addr.Address + AIndex;
|
addr.Address := addr.Address + AIndex;
|
||||||
{$POP}
|
{$POP}
|
||||||
@ -766,7 +766,7 @@ end;
|
|||||||
function TFpPasParserValueDerefPointer.GetAddress: TFpDbgMemLocation;
|
function TFpPasParserValueDerefPointer.GetAddress: TFpDbgMemLocation;
|
||||||
begin
|
begin
|
||||||
Result := FValue.DataAddress;
|
Result := FValue.DataAddress;
|
||||||
Result := Context.MemManager.ReadAddress(Result, Context.SizeOfAddress);
|
Result := Context.MemManager.ReadAddress(Result, SizeVal(Context.SizeOfAddress));
|
||||||
|
|
||||||
if FAddressOffset <> 0 then begin
|
if FAddressOffset <> 0 then begin
|
||||||
assert(IsTargetAddr(Result ), 'TFpPasParserValueDerefPointer.GetAddress: TargetLoc(Result)');
|
assert(IsTargetAddr(Result ), 'TFpPasParserValueDerefPointer.GetAddress: TargetLoc(Result)');
|
||||||
@ -777,7 +777,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpPasParserValueDerefPointer.DoGetSize(out ASize: QWord): Boolean;
|
function TFpPasParserValueDerefPointer.DoGetSize(out ASize: TFpDbgValueSize
|
||||||
|
): Boolean;
|
||||||
var
|
var
|
||||||
t: TFpSymbol;
|
t: TFpSymbol;
|
||||||
begin
|
begin
|
||||||
@ -810,7 +811,7 @@ begin
|
|||||||
FCardinalRead := True;
|
FCardinalRead := True;
|
||||||
Addr := GetAddress;
|
Addr := GetAddress;
|
||||||
if not IsReadableLoc(Addr) then exit;
|
if not IsReadableLoc(Addr) then exit;
|
||||||
FCardinal := LocToAddrOrNil(m.ReadAddress(Addr, Ctx.SizeOfAddress));
|
FCardinal := LocToAddrOrNil(m.ReadAddress(Addr, SizeVal(Ctx.SizeOfAddress)));
|
||||||
|
|
||||||
Result := FCardinal;
|
Result := FCardinal;
|
||||||
end;
|
end;
|
||||||
@ -905,7 +906,7 @@ var
|
|||||||
ti: TFpSymbol;
|
ti: TFpSymbol;
|
||||||
addr: TFpDbgMemLocation;
|
addr: TFpDbgMemLocation;
|
||||||
Tmp: TFpValueConstAddress;
|
Tmp: TFpValueConstAddress;
|
||||||
Size: QWord;
|
Size: TFpDbgValueSize;
|
||||||
begin
|
begin
|
||||||
if (AIndex = 0) or (FValue = nil) then begin
|
if (AIndex = 0) or (FValue = nil) then begin
|
||||||
Result := FValue;
|
Result := FValue;
|
||||||
@ -927,7 +928,7 @@ begin
|
|||||||
SetLastError(CreateError(fpErrAnyError, ['Can index element of unknown size']));
|
SetLastError(CreateError(fpErrAnyError, ['Can index element of unknown size']));
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
AIndex := AIndex * Size;
|
AIndex := AIndex * SizeToFullBytes(Size);
|
||||||
end;
|
end;
|
||||||
addr.Address := addr.Address + AIndex;
|
addr.Address := addr.Address + AIndex;
|
||||||
{$POP}
|
{$POP}
|
||||||
|
@ -871,7 +871,7 @@ var
|
|||||||
CurContext: TFpDbgInfoContext;
|
CurContext: TFpDbgInfoContext;
|
||||||
WatchPasExpr: TFpPascalExpression;
|
WatchPasExpr: TFpPascalExpression;
|
||||||
R: TFpValue;
|
R: TFpValue;
|
||||||
s: QWord;
|
s: TFpDbgValueSize;
|
||||||
begin
|
begin
|
||||||
assert(FInternalBreakpoint=nil);
|
assert(FInternalBreakpoint=nil);
|
||||||
debuglnEnter(DBG_BREAKPOINTS, ['>> TFPBreakpoint.SetBreak ADD ',FSource,':',FLine,'/',dbghex(Address),' ' ]);
|
debuglnEnter(DBG_BREAKPOINTS, ['>> TFPBreakpoint.SetBreak ADD ',FSource,':',FLine,'/',dbghex(Address),' ' ]);
|
||||||
@ -887,7 +887,7 @@ begin
|
|||||||
// TODO: Cache current value
|
// TODO: Cache current value
|
||||||
if WatchPasExpr.Valid and IsTargetNotNil(R.Address) and R.GetSize(s) then begin
|
if WatchPasExpr.Valid and IsTargetNotNil(R.Address) and R.GetSize(s) then begin
|
||||||
// pass context
|
// pass context
|
||||||
FInternalBreakpoint := TFpDebugDebugger(Debugger).AddWatch(R.Address.Address, s, WatchKind, WatchScope);
|
FInternalBreakpoint := TFpDebugDebugger(Debugger).AddWatch(R.Address.Address, SizeToFullBytes(s), WatchKind, WatchScope);
|
||||||
end;
|
end;
|
||||||
WatchPasExpr.Free;
|
WatchPasExpr.Free;
|
||||||
CurContext.ReleaseReference;
|
CurContext.ReleaseReference;
|
||||||
@ -1412,16 +1412,16 @@ begin
|
|||||||
if (ResValue.Kind = skClass) and (ResValue.AsCardinal <> 0) and (defClassAutoCast in EvalFlags)
|
if (ResValue.Kind = skClass) and (ResValue.AsCardinal <> 0) and (defClassAutoCast in EvalFlags)
|
||||||
then begin
|
then begin
|
||||||
CastName := '';
|
CastName := '';
|
||||||
if FMemManager.ReadAddress(ResValue.DataAddress, AContext.SizeOfAddress, ClassAddr) then begin
|
if FMemManager.ReadAddress(ResValue.DataAddress, SizeVal(AContext.SizeOfAddress), ClassAddr) then begin
|
||||||
{$PUSH}{$Q-}
|
{$PUSH}{$Q-}
|
||||||
ClassAddr.Address := ClassAddr.Address + TDBGPtr(3 * AContext.SizeOfAddress);
|
ClassAddr.Address := ClassAddr.Address + TDBGPtr(3 * AContext.SizeOfAddress);
|
||||||
{$POP}
|
{$POP}
|
||||||
if FMemManager.ReadAddress(ClassAddr, AContext.SizeOfAddress, CNameAddr) then begin
|
if FMemManager.ReadAddress(ClassAddr, SizeVal(AContext.SizeOfAddress), CNameAddr) then begin
|
||||||
if (FMemManager.ReadUnsignedInt(CNameAddr, 1, NameLen)) then
|
if (FMemManager.ReadUnsignedInt(CNameAddr, SizeVal(1), NameLen)) then
|
||||||
if NameLen > 0 then begin
|
if NameLen > 0 then begin
|
||||||
SetLength(CastName, NameLen);
|
SetLength(CastName, NameLen);
|
||||||
CNameAddr.Address := CNameAddr.Address + 1;
|
CNameAddr.Address := CNameAddr.Address + 1;
|
||||||
FMemManager.ReadMemory(CNameAddr, NameLen, @CastName[1]);
|
FMemManager.ReadMemory(CNameAddr, SizeVal(NameLen), @CastName[1]);
|
||||||
PasExpr2 := TFpPascalExpression.Create(CastName+'('+AExpression+')', AContext);
|
PasExpr2 := TFpPascalExpression.Create(CastName+'('+AExpression+')', AContext);
|
||||||
PasExpr2.ResultValue;
|
PasExpr2.ResultValue;
|
||||||
if PasExpr2.Valid then begin
|
if PasExpr2.Valid then begin
|
||||||
|
@ -1052,14 +1052,14 @@ DebugLn(DBG_VERBOSE, [ErrorHandler.ErrorAsString(PasExpr.Error)]);
|
|||||||
if (ResValue.Kind = skClass) and (ResValue.AsCardinal <> 0) and (defClassAutoCast in EvalFlags)
|
if (ResValue.Kind = skClass) and (ResValue.AsCardinal <> 0) and (defClassAutoCast in EvalFlags)
|
||||||
then begin
|
then begin
|
||||||
CastName := '';
|
CastName := '';
|
||||||
if FMemManager.ReadAddress(ResValue.DataAddress, Ctx.SizeOfAddress, ClassAddr) then begin
|
if FMemManager.ReadAddress(ResValue.DataAddress, SizeVal(Ctx.SizeOfAddress), ClassAddr) then begin
|
||||||
ClassAddr.Address := ClassAddr.Address + 3 * Ctx.SizeOfAddress;
|
ClassAddr.Address := ClassAddr.Address + 3 * Ctx.SizeOfAddress;
|
||||||
if FMemManager.ReadAddress(ClassAddr, Ctx.SizeOfAddress, CNameAddr) then begin
|
if FMemManager.ReadAddress(ClassAddr, SizeVal(Ctx.SizeOfAddress), CNameAddr) then begin
|
||||||
if (FMemManager.ReadUnsignedInt(CNameAddr, 1, NameLen)) then
|
if (FMemManager.ReadUnsignedInt(CNameAddr, SizeVal(1), NameLen)) then
|
||||||
if NameLen > 0 then begin
|
if NameLen > 0 then begin
|
||||||
SetLength(CastName, NameLen);
|
SetLength(CastName, NameLen);
|
||||||
CNameAddr.Address := CNameAddr.Address + 1;
|
CNameAddr.Address := CNameAddr.Address + 1;
|
||||||
FMemManager.ReadMemory(CNameAddr, NameLen, @CastName[1]);
|
FMemManager.ReadMemory(CNameAddr, SizeVal(NameLen), @CastName[1]);
|
||||||
PasExpr2 := TFpPascalExpression.Create(CastName+'('+AExpression+')', Ctx);
|
PasExpr2 := TFpPascalExpression.Create(CastName+'('+AExpression+')', Ctx);
|
||||||
PasExpr2.ResultValue;
|
PasExpr2.ResultValue;
|
||||||
if PasExpr2.Valid then begin
|
if PasExpr2.Valid then begin
|
||||||
|
@ -1494,14 +1494,14 @@ DebugLn(DBG_VERBOSE, [ErrorHandler.ErrorAsString(PasExpr.Error)]);
|
|||||||
if (ResValue.Kind = skClass) and (ResValue.AsCardinal <> 0) and (defClassAutoCast in EvalFlags)
|
if (ResValue.Kind = skClass) and (ResValue.AsCardinal <> 0) and (defClassAutoCast in EvalFlags)
|
||||||
then begin
|
then begin
|
||||||
CastName := '';
|
CastName := '';
|
||||||
if FMemManager.ReadAddress(ResValue.DataAddress, Ctx.SizeOfAddress, ClassAddr) then begin
|
if FMemManager.ReadAddress(ResValue.DataAddress, SizeVal(Ctx.SizeOfAddress), ClassAddr) then begin
|
||||||
ClassAddr.Address := ClassAddr.Address + 3 * Ctx.SizeOfAddress;
|
ClassAddr.Address := ClassAddr.Address + 3 * Ctx.SizeOfAddress;
|
||||||
if FMemManager.ReadAddress(ClassAddr, Ctx.SizeOfAddress, CNameAddr) then begin
|
if FMemManager.ReadAddress(ClassAddr, SizeVal(Ctx.SizeOfAddress), CNameAddr) then begin
|
||||||
if (FMemManager.ReadUnsignedInt(CNameAddr, 1, NameLen)) then
|
if (FMemManager.ReadUnsignedInt(CNameAddr, SizeVal(1), NameLen)) then
|
||||||
if NameLen > 0 then begin
|
if NameLen > 0 then begin
|
||||||
SetLength(CastName, NameLen);
|
SetLength(CastName, NameLen);
|
||||||
CNameAddr.Address := CNameAddr.Address + 1;
|
CNameAddr.Address := CNameAddr.Address + 1;
|
||||||
FMemManager.ReadMemory(CNameAddr, NameLen, @CastName[1]);
|
FMemManager.ReadMemory(CNameAddr, SizeVal(NameLen), @CastName[1]);
|
||||||
PasExpr2 := TFpPascalExpression.Create(CastName+'('+AExpression+')', Ctx);
|
PasExpr2 := TFpPascalExpression.Create(CastName+'('+AExpression+')', Ctx);
|
||||||
PasExpr2.ResultValue;
|
PasExpr2.ResultValue;
|
||||||
if PasExpr2.Valid then begin
|
if PasExpr2.Valid then begin
|
||||||
|
Loading…
Reference in New Issue
Block a user