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