mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-25 03:52:29 +01:00
FpDebug: started DisplayFormat
git-svn-id: trunk@44896 -
This commit is contained in:
parent
31b29671af
commit
6281c4adcf
@ -5,8 +5,8 @@ unit FpPascalBuilder;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, DbgIntfBaseTypes, FpDbgInfo, FpdMemoryTools, FpErrorMessages,
|
Classes, SysUtils, DbgIntfBaseTypes, DbgIntfDebuggerBase, FpDbgInfo, FpdMemoryTools,
|
||||||
LazLoggerBase;
|
FpErrorMessages, LazLoggerBase;
|
||||||
|
|
||||||
type
|
type
|
||||||
TTypeNameFlag = (
|
TTypeNameFlag = (
|
||||||
@ -39,18 +39,24 @@ type
|
|||||||
TFpPascalPrettyPrinter = class
|
TFpPascalPrettyPrinter = class
|
||||||
private
|
private
|
||||||
FAddressSize: Integer;
|
FAddressSize: Integer;
|
||||||
|
FMemManager: TFpDbgMemManager;
|
||||||
function InternalPrintValue(out APrintedValue: String;
|
function InternalPrintValue(out APrintedValue: String;
|
||||||
AValue: TFpDbgValue;
|
AValue: TFpDbgValue;
|
||||||
AnAddressSize: Integer;
|
AnAddressSize: Integer;
|
||||||
AFlags: TFpPrettyPrintValueFlags;
|
AFlags: TFpPrettyPrintValueFlags;
|
||||||
ANestLevel: Integer; AnIndent: String
|
ANestLevel: Integer; AnIndent: String;
|
||||||
|
ADisplayFormat: TWatchDisplayFormat;
|
||||||
|
ARepaetCount: Integer = -1
|
||||||
): Boolean;
|
): Boolean;
|
||||||
public
|
public
|
||||||
constructor Create(AnAddressSize: Integer);
|
constructor Create(AnAddressSize: Integer);
|
||||||
function PrintValue(out APrintedValue: String;
|
function PrintValue(out APrintedValue: String;
|
||||||
AValue: TFpDbgValue;
|
AValue: TFpDbgValue;
|
||||||
AFlags: TFpPrettyPrintValueFlags = []): Boolean;
|
ADisplayFormat: TWatchDisplayFormat = wdfDefault;
|
||||||
|
ARepaetCount: Integer = -1
|
||||||
|
): Boolean;
|
||||||
property AddressSize: Integer read FAddressSize write FAddressSize;
|
property AddressSize: Integer read FAddressSize write FAddressSize;
|
||||||
|
property MemManager: TFpDbgMemManager read FMemManager write FMemManager;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -422,7 +428,8 @@ end;
|
|||||||
|
|
||||||
function TFpPascalPrettyPrinter.InternalPrintValue(out APrintedValue: String;
|
function TFpPascalPrettyPrinter.InternalPrintValue(out APrintedValue: String;
|
||||||
AValue: TFpDbgValue; AnAddressSize: Integer; AFlags: TFpPrettyPrintValueFlags;
|
AValue: TFpDbgValue; AnAddressSize: Integer; AFlags: TFpPrettyPrintValueFlags;
|
||||||
ANestLevel: Integer; AnIndent: String): Boolean;
|
ANestLevel: Integer; AnIndent: String; ADisplayFormat: TWatchDisplayFormat;
|
||||||
|
ARepaetCount: Integer): Boolean;
|
||||||
|
|
||||||
|
|
||||||
function ResTypeName: String;
|
function ResTypeName: String;
|
||||||
@ -438,15 +445,29 @@ function TFpPascalPrettyPrinter.InternalPrintValue(out APrintedValue: String;
|
|||||||
s: String;
|
s: String;
|
||||||
v: QWord;
|
v: QWord;
|
||||||
begin
|
begin
|
||||||
s := ResTypeName;
|
if ((ADisplayFormat = wdfDefault) and (ANestLevel=0)) or // default for unested: with typename
|
||||||
v := AValue.AsCardinal;
|
(ADisplayFormat = wdfStructure)
|
||||||
if v = 0 then
|
then
|
||||||
APrintedValue := 'nil'
|
s := ResTypeName
|
||||||
else
|
else
|
||||||
APrintedValue := '$'+IntToHex(AValue.AsCardinal, AnAddressSize);
|
s := '';
|
||||||
|
|
||||||
|
v := AValue.AsCardinal;
|
||||||
|
case ADisplayFormat of
|
||||||
|
wdfDecimal, wdfUnsigned: APrintedValue := IntToStr(AValue.AsCardinal);
|
||||||
|
wdfHex: APrintedValue := '$'+IntToHex(AValue.AsCardinal, AnAddressSize*2);
|
||||||
|
else begin //wdfPointer/Default ;
|
||||||
|
if v = 0 then
|
||||||
|
APrintedValue := 'nil'
|
||||||
|
else
|
||||||
|
APrintedValue := '$'+IntToHex(AValue.AsCardinal, AnAddressSize*2);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
if s <> '' then
|
if s <> '' then
|
||||||
APrintedValue := s + '(' + APrintedValue + ')';
|
APrintedValue := s + '(' + APrintedValue + ')';
|
||||||
|
|
||||||
|
if ADisplayFormat = wdfPointer then exit; // no data
|
||||||
if svfString in AValue.FieldFlags then
|
if svfString in AValue.FieldFlags then
|
||||||
APrintedValue := APrintedValue + ' ' + AValue.AsString;
|
APrintedValue := APrintedValue + ' ' + AValue.AsString;
|
||||||
|
|
||||||
@ -454,14 +475,50 @@ function TFpPascalPrettyPrinter.InternalPrintValue(out APrintedValue: String;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure DoInt;
|
procedure DoInt;
|
||||||
|
var
|
||||||
|
n: Integer;
|
||||||
begin
|
begin
|
||||||
APrintedValue := IntToStr(AValue.AsInteger);
|
case ADisplayFormat of
|
||||||
|
wdfUnsigned: APrintedValue := IntToStr(QWord(AValue.AsInteger));
|
||||||
|
wdfHex: begin
|
||||||
|
if svfSize in AValue.FieldFlags then
|
||||||
|
n := AValue.Size * 2
|
||||||
|
else begin
|
||||||
|
n := 16;
|
||||||
|
if QWord(AValue.AsInteger) <= high(Cardinal) then n := 8;
|
||||||
|
if QWord(AValue.AsInteger) <= high(Word) then n := 3;
|
||||||
|
if QWord(AValue.AsInteger) <= high(Byte) then n := 2;
|
||||||
|
end;
|
||||||
|
APrintedValue := '$'+IntToHex(QWord(AValue.AsInteger), n);
|
||||||
|
end;
|
||||||
|
// TODO wdfChar:
|
||||||
|
else
|
||||||
|
APrintedValue := IntToStr(AValue.AsInteger);
|
||||||
|
end;
|
||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure DoCardinal;
|
procedure DoCardinal;
|
||||||
|
var
|
||||||
|
n: Integer;
|
||||||
begin
|
begin
|
||||||
APrintedValue := IntToStr(AValue.AsCardinal);
|
case ADisplayFormat of
|
||||||
|
wdfDecimal: APrintedValue := IntToStr(Int64(AValue.AsCardinal));
|
||||||
|
wdfHex: begin
|
||||||
|
if svfSize in AValue.FieldFlags then
|
||||||
|
n := AValue.Size * 2
|
||||||
|
else begin
|
||||||
|
n := 16;
|
||||||
|
if AValue.AsCardinal <= high(Cardinal) then n := 8;
|
||||||
|
if AValue.AsCardinal <= high(Word) then n := 4;
|
||||||
|
if AValue.AsCardinal <= high(Byte) then n := 2;
|
||||||
|
end;
|
||||||
|
APrintedValue := '$'+IntToHex(AValue.AsCardinal, n);
|
||||||
|
end;
|
||||||
|
// TODO wdfChar:
|
||||||
|
else
|
||||||
|
APrintedValue := IntToStr(AValue.AsCardinal);
|
||||||
|
end;
|
||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -546,6 +603,14 @@ function TFpPascalPrettyPrinter.InternalPrintValue(out APrintedValue: String;
|
|||||||
Result := True;
|
Result := True;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
if ADisplayFormat = wdfPointer then begin
|
||||||
|
s := ResTypeName;
|
||||||
|
APrintedValue := '$'+IntToHex(AValue.AsCardinal, AnAddressSize*2);
|
||||||
|
if s <> '' then
|
||||||
|
APrintedValue := s + '(' + APrintedValue + ')';
|
||||||
|
Result := True;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
if ( (AValue.Kind in [skClass, skObject]) and (ppvSkipClassBody in AFlags) ) or
|
if ( (AValue.Kind in [skClass, skObject]) and (ppvSkipClassBody in AFlags) ) or
|
||||||
( (AValue.Kind in [skRecord]) and (ppvSkipRecordBody in AFlags) )
|
( (AValue.Kind in [skRecord]) and (ppvSkipRecordBody in AFlags) )
|
||||||
@ -554,7 +619,7 @@ function TFpPascalPrettyPrinter.InternalPrintValue(out APrintedValue: String;
|
|||||||
case AValue.Kind of
|
case AValue.Kind of
|
||||||
skRecord: APrintedValue := '{record:}' + APrintedValue;
|
skRecord: APrintedValue := '{record:}' + APrintedValue;
|
||||||
skObject: APrintedValue := '{object:}' + APrintedValue;
|
skObject: APrintedValue := '{object:}' + APrintedValue;
|
||||||
skClass: APrintedValue := '{class:}' + APrintedValue + '(' + '$'+IntToHex(AValue.AsCardinal, AnAddressSize) + ')';
|
skClass: APrintedValue := '{class:}' + APrintedValue + '(' + '$'+IntToHex(AValue.AsCardinal, AnAddressSize*2) + ')';
|
||||||
end;
|
end;
|
||||||
Result := True;
|
Result := True;
|
||||||
exit;
|
exit;
|
||||||
@ -572,7 +637,7 @@ function TFpPascalPrettyPrinter.InternalPrintValue(out APrintedValue: String;
|
|||||||
if (m = nil) or (m.Kind in [skProcedure, skFunction]) then
|
if (m = nil) or (m.Kind in [skProcedure, skFunction]) then
|
||||||
continue;
|
continue;
|
||||||
s := '';
|
s := '';
|
||||||
InternalPrintValue(s, m, AnAddressSize, fl, ANestLevel+1, AnIndent);
|
InternalPrintValue(s, m, AnAddressSize, fl, ANestLevel+1, AnIndent, ADisplayFormat);
|
||||||
if m.DbgSymbol <> nil then
|
if m.DbgSymbol <> nil then
|
||||||
s := m.DbgSymbol.Name + ' = ' + s;
|
s := m.DbgSymbol.Name + ' = ' + s;
|
||||||
if APrintedValue = ''
|
if APrintedValue = ''
|
||||||
@ -588,48 +653,96 @@ function TFpPascalPrettyPrinter.InternalPrintValue(out APrintedValue: String;
|
|||||||
s: String;
|
s: String;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
m: TFpDbgValue;
|
m: TFpDbgValue;
|
||||||
c, d: Integer;
|
Cnt, FullCnt, d: Integer;
|
||||||
begin
|
begin
|
||||||
APrintedValue := '';
|
APrintedValue := '';
|
||||||
c := AValue.MemberCount;
|
Cnt := AValue.MemberCount;
|
||||||
if (c = 0) and (svfOrdinal in AValue.FieldFlags) then begin // dyn array
|
FullCnt := Cnt;
|
||||||
|
if (Cnt = 0) and (svfOrdinal in AValue.FieldFlags) then begin // dyn array
|
||||||
APrintedValue := 'nil';
|
APrintedValue := 'nil';
|
||||||
Result := True;
|
Result := True;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
if (ANestLevel > 2) then begin
|
if (ANestLevel > 2) then begin
|
||||||
s := ResTypeName;
|
s := ResTypeName;
|
||||||
APrintedValue := s+'(...)'; // TODO len and addr (dyn array)
|
APrintedValue := s+'({'+IntToStr(FullCnt)+' elements})'; // TODO len and addr (dyn array)
|
||||||
Result := True;
|
Result := True;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
if (ANestLevel > 1) and (c > 5) then c := 5
|
if (ANestLevel > 1) and (Cnt > 3) then Cnt := 3
|
||||||
else if (ANestLevel > 0) and (c > 15) then c := 15
|
else if (ANestLevel > 0) and (Cnt > 10) then Cnt := 10
|
||||||
else if (c > 500) then c := 500;
|
else if (Cnt > 300) then Cnt := 300;
|
||||||
d := 0;
|
d := 0;
|
||||||
// TODO: use valueobject for bounds
|
// TODO: use valueobject for bounds
|
||||||
if (AValue.IndexTypeCount > 0) and AValue.IndexType[0].HasBounds then
|
if (AValue.IndexTypeCount > 0) and AValue.IndexType[0].HasBounds then
|
||||||
d := AValue.IndexType[0].OrdLowBound;
|
d := AValue.IndexType[0].OrdLowBound;
|
||||||
for i := d to d + c - 1 do begin
|
for i := d to d + Cnt - 1 do begin
|
||||||
m := AValue.Member[i];
|
m := AValue.Member[i];
|
||||||
if m <> nil then
|
if m <> nil then
|
||||||
InternalPrintValue(s, m, AnAddressSize, AFlags, ANestLevel+1, AnIndent)
|
InternalPrintValue(s, m, AnAddressSize, AFlags, ANestLevel+1, AnIndent, ADisplayFormat)
|
||||||
else
|
else
|
||||||
s := '{error}';
|
s := '{error}';
|
||||||
if APrintedValue = ''
|
if APrintedValue = ''
|
||||||
then APrintedValue := s
|
then APrintedValue := s
|
||||||
else APrintedValue := APrintedValue + ', ' + s;
|
else APrintedValue := APrintedValue + ', ' + s;
|
||||||
end;
|
end;
|
||||||
if c < AValue.MemberCount then
|
if Cnt < FullCnt then
|
||||||
APrintedValue := APrintedValue + ', ...';
|
APrintedValue := APrintedValue + ', {'+IntToStr(FullCnt-Cnt)+' more elements}';
|
||||||
APrintedValue := '(' + APrintedValue + ')';
|
APrintedValue := '(' + APrintedValue + ')';
|
||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
var
|
||||||
|
MemAddr: TFpDbgMemLocation;
|
||||||
|
MemSize: Integer;
|
||||||
|
MemDest: array of Byte;
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
if ANestLevel > 0 then begin
|
if ANestLevel > 0 then begin
|
||||||
AnIndent := AnIndent + ' ';
|
AnIndent := AnIndent + ' ';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if ADisplayFormat = wdfMemDump then begin
|
||||||
|
if FMemManager <> nil then begin
|
||||||
|
MemAddr := UnInitializedLoc;
|
||||||
|
if svfDataAddress in AValue.FieldFlags then begin
|
||||||
|
MemAddr := AValue.DataAddress;
|
||||||
|
MemSize := AValue.DataSize;
|
||||||
|
if MemSize = 0 then MemSize := 256;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if svfAddress in AValue.FieldFlags then begin
|
||||||
|
MemAddr := AValue.Address;
|
||||||
|
MemSize := AValue.Size;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if IsTargetAddr(MemAddr) then begin
|
||||||
|
if MemSize < 32 then MemSize := 32;
|
||||||
|
SetLength(MemDest, MemSize);
|
||||||
|
if FMemManager.ReadMemory(MemAddr, 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
|
||||||
|
APrintedValue := APrintedValue + LineEnding
|
||||||
|
else
|
||||||
|
if (i > 0) and (i mod 8 = 0) then
|
||||||
|
APrintedValue := APrintedValue + ' '
|
||||||
|
else
|
||||||
|
if (i > 0) then
|
||||||
|
APrintedValue := APrintedValue + ' ';
|
||||||
|
APrintedValue := APrintedValue + IntToHex(MemDest[i], 2);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
APrintedValue := 'Cannot read memory at address '+ IntToHex(MemAddr.Address, AnAddressSize*2);
|
||||||
|
end;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
APrintedValue := 'Cannot read memory for expression';
|
||||||
|
exit
|
||||||
|
end;
|
||||||
|
|
||||||
Result := False;
|
Result := False;
|
||||||
case AValue.Kind of
|
case AValue.Kind of
|
||||||
skUnit: ;
|
skUnit: ;
|
||||||
@ -666,9 +779,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpPascalPrettyPrinter.PrintValue(out APrintedValue: String; AValue: TFpDbgValue;
|
function TFpPascalPrettyPrinter.PrintValue(out APrintedValue: String; AValue: TFpDbgValue;
|
||||||
AFlags: TFpPrettyPrintValueFlags): Boolean;
|
ADisplayFormat: TWatchDisplayFormat; ARepaetCount: Integer): Boolean;
|
||||||
begin
|
begin
|
||||||
InternalPrintValue(APrintedValue, AValue, AddressSize, AFlags, 0, '');
|
InternalPrintValue(APrintedValue, AValue, AddressSize, [], 0, '', ADisplayFormat, ARepaetCount);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|||||||
@ -593,7 +593,7 @@ begin
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
FPrettyPrinter.AddressSize:=AContext.SizeOfAddress;
|
FPrettyPrinter.AddressSize:=AContext.SizeOfAddress;
|
||||||
if FPrettyPrinter.PrintValue(AVal, APasExpr.ResultValue, []) then
|
if FPrettyPrinter.PrintValue(AVal, APasExpr.ResultValue) then
|
||||||
begin
|
begin
|
||||||
AWatchValue.Value := AVal; //IntToStr(APasExpr.ResultValue.AsInteger);
|
AWatchValue.Value := AVal; //IntToStr(APasExpr.ResultValue.AsInteger);
|
||||||
AWatchValue.Validity := ddsValid;
|
AWatchValue.Validity := ddsValid;
|
||||||
|
|||||||
@ -937,6 +937,8 @@ var
|
|||||||
PasExpr: TFpPascalExpression;
|
PasExpr: TFpPascalExpression;
|
||||||
ResValue: TFpDbgValue;
|
ResValue: TFpDbgValue;
|
||||||
s: String;
|
s: String;
|
||||||
|
DispFormat: TWatchDisplayFormat;
|
||||||
|
RepeatCnt: Integer;
|
||||||
|
|
||||||
function IsWatchValueAlive: Boolean;
|
function IsWatchValueAlive: Boolean;
|
||||||
begin
|
begin
|
||||||
@ -957,7 +959,7 @@ var
|
|||||||
|
|
||||||
procedure DoPointer;
|
procedure DoPointer;
|
||||||
begin
|
begin
|
||||||
if not FPrettyPrinter.PrintValue(AResText, ResValue, []) then
|
if not FPrettyPrinter.PrintValue(AResText, ResValue, DispFormat, RepeatCnt) 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.AsPointer := Pointer(ResValue.AsCardinal); // TODO: no cut off
|
||||||
@ -966,7 +968,7 @@ var
|
|||||||
|
|
||||||
procedure DoSimple;
|
procedure DoSimple;
|
||||||
begin
|
begin
|
||||||
if not FPrettyPrinter.PrintValue(AResText, ResValue, []) then
|
if not FPrettyPrinter.PrintValue(AResText, ResValue, DispFormat, RepeatCnt) then
|
||||||
exit;
|
exit;
|
||||||
ATypeInfo := TDBGType.Create(skSimple, ResTypeName);
|
ATypeInfo := TDBGType.Create(skSimple, ResTypeName);
|
||||||
ATypeInfo.Value.AsString := AResText;
|
ATypeInfo.Value.AsString := AResText;
|
||||||
@ -974,7 +976,7 @@ var
|
|||||||
|
|
||||||
procedure DoEnum;
|
procedure DoEnum;
|
||||||
begin
|
begin
|
||||||
if not FPrettyPrinter.PrintValue(AResText, ResValue, []) then
|
if not FPrettyPrinter.PrintValue(AResText, ResValue, DispFormat, RepeatCnt) then
|
||||||
exit;
|
exit;
|
||||||
ATypeInfo := TDBGType.Create(skEnum, ResTypeName);
|
ATypeInfo := TDBGType.Create(skEnum, ResTypeName);
|
||||||
ATypeInfo.Value.AsString := AResText;
|
ATypeInfo.Value.AsString := AResText;
|
||||||
@ -982,7 +984,7 @@ var
|
|||||||
|
|
||||||
procedure DoSet;
|
procedure DoSet;
|
||||||
begin
|
begin
|
||||||
if not FPrettyPrinter.PrintValue(AResText, ResValue, []) then
|
if not FPrettyPrinter.PrintValue(AResText, ResValue, DispFormat, RepeatCnt) then
|
||||||
exit;
|
exit;
|
||||||
ATypeInfo := TDBGType.Create(skSet, ResTypeName);
|
ATypeInfo := TDBGType.Create(skSet, ResTypeName);
|
||||||
ATypeInfo.Value.AsString := AResText;
|
ATypeInfo.Value.AsString := AResText;
|
||||||
@ -996,7 +998,7 @@ var
|
|||||||
DBGType: TGDBType;
|
DBGType: TGDBType;
|
||||||
f: TDBGField;
|
f: TDBGField;
|
||||||
begin
|
begin
|
||||||
if not FPrettyPrinter.PrintValue(AResText, ResValue, []) then
|
if not FPrettyPrinter.PrintValue(AResText, ResValue, DispFormat, RepeatCnt) then
|
||||||
exit;
|
exit;
|
||||||
ATypeInfo := TDBGType.Create(skRecord, ResTypeName);
|
ATypeInfo := TDBGType.Create(skRecord, ResTypeName);
|
||||||
ATypeInfo.Value.AsString := AResText;
|
ATypeInfo.Value.AsString := AResText;
|
||||||
@ -1010,7 +1012,7 @@ var
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
DBGType := TGDBType.Create(skSimple, ResTypeName(m));
|
DBGType := TGDBType.Create(skSimple, ResTypeName(m));
|
||||||
FPrettyPrinter.PrintValue(s2, m, []);
|
FPrettyPrinter.PrintValue(s2, m, DispFormat, RepeatCnt);
|
||||||
DBGType.Value.AsString := s2;
|
DBGType.Value.AsString := s2;
|
||||||
n := '';
|
n := '';
|
||||||
if m.DbgSymbol <> nil then n := m.DbgSymbol.Name;
|
if m.DbgSymbol <> nil then n := m.DbgSymbol.Name;
|
||||||
@ -1033,7 +1035,7 @@ var
|
|||||||
PasExpr2: TFpPascalExpression;
|
PasExpr2: TFpPascalExpression;
|
||||||
begin
|
begin
|
||||||
if (ResValue.Kind = skClass) and (ResValue.AsCardinal = 0) then begin
|
if (ResValue.Kind = skClass) and (ResValue.AsCardinal = 0) then begin
|
||||||
if not FPrettyPrinter.PrintValue(AResText, ResValue, []) then
|
if not FPrettyPrinter.PrintValue(AResText, ResValue, DispFormat, RepeatCnt) then
|
||||||
exit;
|
exit;
|
||||||
ATypeInfo := TDBGType.Create(skSimple, ResTypeName);
|
ATypeInfo := TDBGType.Create(skSimple, ResTypeName);
|
||||||
ATypeInfo.Value.AsString := AResText;
|
ATypeInfo.Value.AsString := AResText;
|
||||||
@ -1042,7 +1044,7 @@ var
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
CastName := '';
|
CastName := '';
|
||||||
if (defClassAutoCast in EvalFlags) then begin
|
if (defClassAutoCast in EvalFlags) and (ResValue.Kind = skClass) then begin
|
||||||
if FMemManager.ReadAddress(ResValue.DataAddress, Ctx.SizeOfAddress, ClassAddr) then begin
|
if FMemManager.ReadAddress(ResValue.DataAddress, 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, Ctx.SizeOfAddress, CNameAddr) then begin
|
||||||
@ -1065,7 +1067,7 @@ var
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
if not FPrettyPrinter.PrintValue(AResText, ResValue, []) then
|
if not FPrettyPrinter.PrintValue(AResText, ResValue, DispFormat, RepeatCnt) then
|
||||||
exit;
|
exit;
|
||||||
if CastName <> '' then AResText := CastName + AResText;
|
if CastName <> '' then AResText := CastName + AResText;
|
||||||
//if PasExpr.ResultValue.Kind = skObject then
|
//if PasExpr.ResultValue.Kind = skObject then
|
||||||
@ -1083,7 +1085,7 @@ var
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
DBGType := TGDBType.Create(skSimple, ResTypeName(m));
|
DBGType := TGDBType.Create(skSimple, ResTypeName(m));
|
||||||
FPrettyPrinter.PrintValue(s2, m, []);
|
FPrettyPrinter.PrintValue(s2, m, DispFormat, RepeatCnt);
|
||||||
DBGType.Value.AsString := s2;
|
DBGType.Value.AsString := s2;
|
||||||
n := '';
|
n := '';
|
||||||
if m.DbgSymbol <> nil then n := m.DbgSymbol.Name;
|
if m.DbgSymbol <> nil then n := m.DbgSymbol.Name;
|
||||||
@ -1099,7 +1101,7 @@ var
|
|||||||
|
|
||||||
procedure DoArray;
|
procedure DoArray;
|
||||||
begin
|
begin
|
||||||
if not FPrettyPrinter.PrintValue(AResText, ResValue, []) then
|
if not FPrettyPrinter.PrintValue(AResText, ResValue, DispFormat, RepeatCnt) then
|
||||||
exit;
|
exit;
|
||||||
ATypeInfo := TDBGType.Create(skArray, ResTypeName);
|
ATypeInfo := TDBGType.Create(skArray, ResTypeName);
|
||||||
ATypeInfo.Value.AsString := AResText;
|
ATypeInfo.Value.AsString := AResText;
|
||||||
@ -1122,14 +1124,21 @@ begin
|
|||||||
// FMemReader.FStackFrame := CurrentStackFrame;
|
// FMemReader.FStackFrame := CurrentStackFrame;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if AWatchValue <> nil then
|
if AWatchValue <> nil then begin
|
||||||
Ctx := GetInfoContextForContext(AWatchValue.ThreadId, AWatchValue.StackFrame)
|
Ctx := GetInfoContextForContext(AWatchValue.ThreadId, AWatchValue.StackFrame);
|
||||||
else
|
DispFormat := AWatchValue.DisplayFormat;
|
||||||
|
RepeatCnt := AWatchValue.RepeatCount;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
Ctx := GetInfoContextForContext(CurrentThreadId, CurrentStackFrame);
|
Ctx := GetInfoContextForContext(CurrentThreadId, CurrentStackFrame);
|
||||||
|
DispFormat := wdfDefault;
|
||||||
|
RepeatCnt := -1;
|
||||||
|
end;
|
||||||
if Ctx = nil then exit;
|
if Ctx = nil then exit;
|
||||||
|
|
||||||
FMemManager.DefaultContext := Ctx;
|
FMemManager.DefaultContext := Ctx;
|
||||||
FPrettyPrinter.AddressSize := ctx.SizeOfAddress;
|
FPrettyPrinter.AddressSize := ctx.SizeOfAddress;
|
||||||
|
FPrettyPrinter.MemManager := ctx.MemManager;
|
||||||
|
|
||||||
PasExpr := TFpPascalExpression.Create(AExpression, Ctx);
|
PasExpr := TFpPascalExpression.Create(AExpression, Ctx);
|
||||||
try
|
try
|
||||||
@ -1187,7 +1196,8 @@ DebugLn(ErrorHandler.ErrorAsString(PasExpr.Error));
|
|||||||
PasExpr.FixPCharIndexAccess := True;
|
PasExpr.FixPCharIndexAccess := True;
|
||||||
PasExpr.ResetEvaluation;
|
PasExpr.ResetEvaluation;
|
||||||
ResValue := PasExpr.ResultValue;
|
ResValue := PasExpr.ResultValue;
|
||||||
if (ResValue=nil) or (not FPrettyPrinter.PrintValue(s, ResValue, [])) then s := 'Failed';
|
if (ResValue=nil) or (not FPrettyPrinter.PrintValue(s, ResValue, DispFormat, RepeatCnt)) then
|
||||||
|
s := 'Failed';
|
||||||
AResText := 'PChar: '+AResText+ LineEnding + 'String: '+s;
|
AResText := 'PChar: '+AResText+ LineEnding + 'String: '+s;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user