mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 10:59:11 +02:00
FpDebug: pointer deref with index / tests
git-svn-id: trunk@44563 -
This commit is contained in:
parent
7473ac1d09
commit
8d1b5eeea4
@ -2242,10 +2242,10 @@ begin
|
|||||||
if (f * [svfAddress, svfSize, svfSizeOfPointer] = [svfAddress]) then
|
if (f * [svfAddress, svfSize, svfSizeOfPointer] = [svfAddress]) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
//if (f * [svfAddress, svfSize] = [svfAddress, svfSize]) and
|
if (f * [svfAddress, svfSize] = [svfAddress, svfSize]) and
|
||||||
// (FTypeCastSourceValue.Size = FTypeCastTargetType.Size)
|
(FTypeCastSourceValue.Size = FTypeCastTargetType.Size)
|
||||||
//then
|
then
|
||||||
// exit;
|
exit;
|
||||||
|
|
||||||
Result := False;
|
Result := False;
|
||||||
end;
|
end;
|
||||||
|
@ -487,12 +487,15 @@ type
|
|||||||
procedure IncRefLevel;
|
procedure IncRefLevel;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TFpPasParserValueDerefPointer }
|
{ TFpPasParserValueDerefPointer
|
||||||
|
Used as address source in typecast
|
||||||
|
}
|
||||||
|
|
||||||
TFpPasParserValueDerefPointer = class(TFpPasParserValue)
|
TFpPasParserValueDerefPointer = class(TFpPasParserValue)
|
||||||
private
|
private
|
||||||
FValue: TFpDbgValue;
|
FValue: TFpDbgValue;
|
||||||
FExpression: TFpPascalExpression; // MemReader / AddrSize
|
FExpression: TFpPascalExpression; // MemReader / AddrSize
|
||||||
|
FAddressOffset: Int64; // Add to address
|
||||||
FCardinal: QWord; // todo: TFpDbgMemLocation ?
|
FCardinal: QWord; // todo: TFpDbgMemLocation ?
|
||||||
FCardinalRead: Boolean;
|
FCardinalRead: Boolean;
|
||||||
protected
|
protected
|
||||||
@ -502,9 +505,10 @@ type
|
|||||||
function GetAddress: TFpDbgMemLocation; override;
|
function GetAddress: TFpDbgMemLocation; override;
|
||||||
function GetSize: Integer; override;
|
function GetSize: Integer; override;
|
||||||
function GetAsCardinal: QWord; override; // reads men
|
function GetAsCardinal: QWord; override; // reads men
|
||||||
function GetTypeInfo: TFpDbgSymbol; override;
|
function GetTypeInfo: TFpDbgSymbol; override; // TODO: Cardinal? Why? // TODO: does not handle AOffset
|
||||||
public
|
public
|
||||||
constructor Create(AValue: TFpDbgValue; AExpression: TFpPascalExpression);
|
constructor Create(AValue: TFpDbgValue; AExpression: TFpPascalExpression);
|
||||||
|
constructor Create(AValue: TFpDbgValue; AExpression: TFpPascalExpression; AOffset: Int64);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -679,6 +683,13 @@ end;
|
|||||||
function TFpPasParserValueDerefPointer.GetAddress: TFpDbgMemLocation;
|
function TFpPasParserValueDerefPointer.GetAddress: TFpDbgMemLocation;
|
||||||
begin
|
begin
|
||||||
Result := FValue.DataAddress;
|
Result := FValue.DataAddress;
|
||||||
|
if FAddressOffset <> 0 then begin
|
||||||
|
assert(IsTargetAddr(Result ), 'TFpPasParserValueDerefPointer.GetAddress: TargetLoc(Result)');
|
||||||
|
if IsTargetAddr(Result) then
|
||||||
|
Result.Address := Result.Address + FAddressOffset
|
||||||
|
else
|
||||||
|
Result := InvalidLoc;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpPasParserValueDerefPointer.GetSize: Integer;
|
function TFpPasParserValueDerefPointer.GetSize: Integer;
|
||||||
@ -733,11 +744,18 @@ end;
|
|||||||
|
|
||||||
constructor TFpPasParserValueDerefPointer.Create(AValue: TFpDbgValue;
|
constructor TFpPasParserValueDerefPointer.Create(AValue: TFpDbgValue;
|
||||||
AExpression: TFpPascalExpression);
|
AExpression: TFpPascalExpression);
|
||||||
|
begin
|
||||||
|
Create(AValue, AExpression, 0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TFpPasParserValueDerefPointer.Create(AValue: TFpDbgValue;
|
||||||
|
AExpression: TFpPascalExpression; AOffset: Int64);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
FValue := AValue;
|
FValue := AValue;
|
||||||
FValue.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FValue, 'TPasParserDerefPointerSymbolValue'){$ENDIF};
|
FValue.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FValue, 'TPasParserDerefPointerSymbolValue'){$ENDIF};
|
||||||
FExpression := AExpression;
|
FExpression := AExpression;
|
||||||
|
FAddressOffset := AOffset;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TFpPasParserValueDerefPointer.Destroy;
|
destructor TFpPasParserValueDerefPointer.Destroy;
|
||||||
@ -921,8 +939,10 @@ end;
|
|||||||
|
|
||||||
function TFpPascalExpressionPartBracketIndex.DoGetResultValue: TFpDbgValue;
|
function TFpPascalExpressionPartBracketIndex.DoGetResultValue: TFpDbgValue;
|
||||||
var
|
var
|
||||||
TmpVal, TmpVal2, TmpIndex: TFpDbgValue;
|
TmpVal, TmpVal2, TmpIndex, TmpDeref: TFpDbgValue;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
Offs: Int64;
|
||||||
|
ti: TFpDbgSymbol;
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
assert(Count >= 2, 'TFpPascalExpressionPartBracketIndex.DoGetResultValue: Count >= 2');
|
assert(Count >= 2, 'TFpPascalExpressionPartBracketIndex.DoGetResultValue: Count >= 2');
|
||||||
@ -945,7 +965,7 @@ begin
|
|||||||
TmpVal2 := TmpVal.Member[TmpIndex.AsInteger]
|
TmpVal2 := TmpVal.Member[TmpIndex.AsInteger]
|
||||||
else
|
else
|
||||||
if (svfOrdinal in TmpIndex.FieldFlags) and
|
if (svfOrdinal in TmpIndex.FieldFlags) and
|
||||||
(TmpIndex.AsCardinal <= high(Integer))
|
(TmpIndex.AsCardinal <= high(Int64))
|
||||||
then
|
then
|
||||||
TmpVal2 := TmpVal.Member[TmpIndex.AsCardinal]
|
TmpVal2 := TmpVal.Member[TmpIndex.AsCardinal]
|
||||||
else
|
else
|
||||||
@ -954,13 +974,37 @@ begin
|
|||||||
TmpVal.ReleaseReference;
|
TmpVal.ReleaseReference;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
if TmpVal2 <> nil then TmpVal2.AddReference;
|
||||||
end // Kind = skArray
|
end // Kind = skArray
|
||||||
else
|
else
|
||||||
if (TmpVal.Kind = skPointer) then begin
|
if (TmpVal.Kind = skPointer) then begin
|
||||||
//Result := TmpVal.TypeInfo;
|
if (TmpVal.TypeInfo = nil) or (TmpVal.TypeInfo.TypeInfo = nil) or
|
||||||
SetError('Not implemented');
|
(TmpVal.TypeInfo.TypeInfo.Size <= 0)
|
||||||
TmpVal.ReleaseReference;
|
then begin
|
||||||
exit;
|
SetError('Can not dereference an untyped pointer');
|
||||||
|
TmpVal.ReleaseReference;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
// TODO: check svfDataAddress / readable ? (see normal pointer deref);
|
||||||
|
ti := TmpVal.TypeInfo.TypeInfo;
|
||||||
|
if (svfInteger in TmpIndex.FieldFlags) then
|
||||||
|
Offs := TmpIndex.AsInteger
|
||||||
|
else
|
||||||
|
if (svfOrdinal in TmpIndex.FieldFlags) and (TmpIndex.AsCardinal <= high(Int64))
|
||||||
|
then
|
||||||
|
Offs := Int64(TmpIndex.AsCardinal)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
SetError('Can not calculate Index');
|
||||||
|
TmpVal.ReleaseReference;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
{$PUSH}{$R-}{$Q-} // TODO: check overflow
|
||||||
|
Offs := Offs * ti.Size;
|
||||||
|
{$POP}
|
||||||
|
TmpDeref := TFpPasParserValueDerefPointer.Create(TmpVal, Expression, Offs);
|
||||||
|
TmpVal2 := ti.TypeCastValue(TmpDeref);
|
||||||
|
TmpDeref.ReleaseReference;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if (TmpVal.Kind = skString) then begin
|
if (TmpVal.Kind = skString) then begin
|
||||||
@ -981,7 +1025,6 @@ begin
|
|||||||
TmpVal.ReleaseReference;
|
TmpVal.ReleaseReference;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
TmpVal2.AddReference;
|
|
||||||
TmpVal.ReleaseReference;
|
TmpVal.ReleaseReference;
|
||||||
TmpVal := TmpVal2;
|
TmpVal := TmpVal2;
|
||||||
end;
|
end;
|
||||||
|
@ -355,6 +355,8 @@ var
|
|||||||
|
|
||||||
// dummy, ensure "pointer" is in debug info
|
// dummy, ensure "pointer" is in debug info
|
||||||
ArrayGlob_DummyPointer: Pointer;
|
ArrayGlob_DummyPointer: Pointer;
|
||||||
|
ArrayGlob_DummyPInteger: PInteger;
|
||||||
|
|
||||||
procedure Test1;
|
procedure Test1;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
@ -14,7 +14,7 @@ const
|
|||||||
BREAK_LINE_TestWatchesUnitSimple_2 = 570;
|
BREAK_LINE_TestWatchesUnitSimple_2 = 570;
|
||||||
BREAK_LINE_TestWatchesUnitSimple_3 = 578;
|
BREAK_LINE_TestWatchesUnitSimple_3 = 578;
|
||||||
|
|
||||||
BREAK_LINE_TestWatchesUnitArray = 840;
|
BREAK_LINE_TestWatchesUnitArray = 842;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -662,6 +662,16 @@ if not (i in [2,3]) then // open array / TODO
|
|||||||
|
|
||||||
end; // i
|
end; // i
|
||||||
{%endregion Fields }
|
{%endregion Fields }
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
AddSimpleInt('PInteger(Field_DynInt1)[0]', 5511, M_Int);
|
||||||
|
AddSimpleInt('PInteger(Field_DynInt1)[1]', 5512, M_Int);
|
||||||
|
AddSimpleInt('PInteger(Field_DynInt1)[2]', 5513, M_Int);
|
||||||
|
|
||||||
|
AddSimpleInt('^LongInt(Field_DynInt1)[0]', 5511, M_Int);
|
||||||
|
AddSimpleInt('^LongInt(Field_DynInt1)[1]', 5512, M_Int);
|
||||||
|
AddSimpleInt('^LongInt(Field_DynInt1)[2]', 5513, M_Int);
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestWatches.RunTestWatches(NamePreFix: String; TestExeName, ExtraOpts: String;
|
procedure TTestWatches.RunTestWatches(NamePreFix: String; TestExeName, ExtraOpts: String;
|
||||||
|
Loading…
Reference in New Issue
Block a user