FpDebug: prepare mem-manager for context

git-svn-id: trunk@44627 -
This commit is contained in:
martin 2014-04-07 00:26:04 +00:00
parent 0eaa8042c5
commit 03d6bdade7
9 changed files with 218 additions and 147 deletions

View File

@ -60,23 +60,26 @@ type
public
class function HandleCompUnit(ACU: TDwarfCompilationUnit): Boolean; override;
class function GetDwarfSymbolClass(ATag: Cardinal): TDbgDwarfSymbolBaseClass; override;
class function CreateContext(AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol;
ADwarf: TFpDwarfInfo): TDbgInfoAddressContext; override;
class function CreateContext(AThreadId, AStackFrame: Integer; AnAddress:
TDbgPtr; ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo): TFpDbgInfoContext; override;
class function CreateProcSymbol(ACompilationUnit: TDwarfCompilationUnit;
AInfo: PDwarfAddressInfo; AAddress: TDbgPtr): TDbgDwarfSymbolBase; override;
end;
{ TFpDwarfInfoAddressContext }
TFpDwarfInfoAddressContext = class(TDbgInfoAddressContext)
TFpDwarfInfoAddressContext = class(TFpDbgInfoContext)
private
FSymbol: TFpDbgSymbol;
FAddress: TDBGPtr;
FThreadId, FStackFrame: Integer;
FDwarf: TFpDwarfInfo;
FlastResult: TFpDbgValue;
protected
function GetSymbolAtAddress: TFpDbgSymbol; override;
function GetAddress: TDbgPtr; override;
function GetThreadId: Integer; override;
function GetStackFrame: Integer; override;
function GetSizeOfAddress: Integer; override;
function GetMemManager: TFpDbgMemManager; override;
@ -96,7 +99,7 @@ type
function FindLocalSymbol(const AName: String; PNameUpper, PNameLower: PChar;
InfoEntry: TDwarfInformationEntry): TFpDbgValue; virtual;
public
constructor Create(AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo);
constructor Create(AThreadId, AStackFrame: Integer; AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo);
destructor Destroy; override;
function FindSymbol(const AName: String): TFpDbgValue; override;
end;
@ -104,8 +107,6 @@ type
TFpDwarfSymbol = class;
TFpDwarfSymbolType = class;
TFpDwarfSymbolValue = class;
TFpDwarfSymbolTypeStructure = class;
//TDbgDwarfIdentifierClass = class of TDbgDwarfIdentifier;
TFpDwarfSymbolValueClass = class of TFpDwarfSymbolValue;
TFpDwarfSymbolTypeClass = class of TFpDwarfSymbolType;
@ -115,9 +116,9 @@ type
TFpDwarfValueBase = class(TFpDbgValue)
private
FContext: TDbgInfoAddressContext;
FContext: TFpDbgInfoContext;
public
property Context: TDbgInfoAddressContext read FContext;
property Context: TFpDbgInfoContext read FContext;
end;
{ TFpDwarfValueTypeDefinition }
@ -918,10 +919,10 @@ begin
end;
end;
class function TFpDwarfDefaultSymbolClassMap.CreateContext(AnAddress: TDbgPtr;
ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo): TDbgInfoAddressContext;
class function TFpDwarfDefaultSymbolClassMap.CreateContext(AThreadId, AStackFrame: Integer;
AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo): TFpDbgInfoContext;
begin
Result := TFpDwarfInfoAddressContext.Create(AnAddress, ASymbol, ADwarf);
Result := TFpDwarfInfoAddressContext.Create(AThreadId, AStackFrame, AnAddress, ASymbol, ADwarf);
end;
class function TFpDwarfDefaultSymbolClassMap.CreateProcSymbol(ACompilationUnit: TDwarfCompilationUnit;
@ -942,6 +943,16 @@ begin
Result := FAddress;
end;
function TFpDwarfInfoAddressContext.GetThreadId: Integer;
begin
Result := FThreadId;
end;
function TFpDwarfInfoAddressContext.GetStackFrame: Integer;
begin
Result := FStackFrame;
end;
function TFpDwarfInfoAddressContext.GetSizeOfAddress: Integer;
begin
assert(FSymbol is TFpDwarfSymbol, 'TDbgDwarfInfoAddressContext.GetSizeOfAddress');
@ -1106,12 +1117,14 @@ begin
end;
end;
constructor TFpDwarfInfoAddressContext.Create(AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol;
ADwarf: TFpDwarfInfo);
constructor TFpDwarfInfoAddressContext.Create(AThreadId, AStackFrame: Integer;
AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo);
begin
inherited Create;
AddReference;
FAddress := AnAddress;
FThreadId := AThreadId;
FStackFrame := AStackFrame;
FDwarf := ADwarf;
FSymbol := ASymbol;
FSymbol.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FSymbol, 'Context to Symbol'){$ENDIF};
@ -2808,7 +2821,8 @@ begin
//exit;
end;
LocationParser := TDwarfLocationExpression.Create(@Val[0], Length(Val), CompilationUnit, AValueObj.MemManager);
LocationParser := TDwarfLocationExpression.Create(@Val[0], Length(Val), CompilationUnit,
AValueObj.MemManager, AValueObj.Context);
InitLocationParser(LocationParser, AValueObj, AnObjectDataAddress);
LocationParser.Evaluate;
@ -3079,8 +3093,8 @@ begin
if (ti = nil) or not (ti.SymbolType = stType) then exit;
FValueObject := TFpDwarfSymbolType(ti).GetTypedValueObject(False);
{$IFDEF WITH_REFCOUNT_DEBUG}FValueObject.DbgRenameReference(@FValueObject, ClassName+'.FValueObject');{$ENDIF}
if FValueObject <> nil then begin
{$IFDEF WITH_REFCOUNT_DEBUG}FValueObject.DbgRenameReference(@FValueObject, ClassName+'.FValueObject');{$ENDIF}
FValueObject.MakePlainRefToCirclular;
FValueObject.SetValueSymbol(self);
end;
@ -4437,7 +4451,8 @@ begin
exit;
end;
FFrameBaseParser := TDwarfLocationExpression.Create(@Val[0], Length(Val), CompilationUnit, ASender.MemManager);
FFrameBaseParser := TDwarfLocationExpression.Create(@Val[0], Length(Val), CompilationUnit,
ASender.MemManager, ASender.Context);
FFrameBaseParser.Evaluate;
end;

View File

@ -435,8 +435,8 @@ type
public
class function HandleCompUnit(ACU: TDwarfCompilationUnit): Boolean; virtual; abstract;
class function GetDwarfSymbolClass(ATag: Cardinal): TDbgDwarfSymbolBaseClass; virtual; abstract;
class function CreateContext(AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol;
ADwarf: TFpDwarfInfo): TDbgInfoAddressContext; virtual; abstract;
class function CreateContext(AThreadId, AStackFrame: Integer; AnAddress: TDbgPtr; ASymbol: TFpDbgSymbol;
ADwarf: TFpDwarfInfo): TFpDbgInfoContext; virtual; abstract;
class function CreateProcSymbol(ACompilationUnit: TDwarfCompilationUnit;
AInfo: PDwarfAddressInfo; AAddress: TDbgPtr): TDbgDwarfSymbolBase; virtual; abstract;
end;
@ -587,7 +587,8 @@ type
public
constructor Create(ALoader: TDbgImageLoader); override;
destructor Destroy; override;
function FindContext(AAddress: TDbgPtr): TDbgInfoAddressContext; override;
function FindContext(AThreadId, AStackFrame: Integer; AAddress: TDbgPtr = 0): TFpDbgInfoContext; override;
function FindContext(AAddress: TDbgPtr): TFpDbgInfoContext; override;
function FindSymbol(AAddress: TDbgPtr): TFpDbgSymbol; override;
//function FindSymbol(const AName: String): TDbgSymbol; override;
function GetLineAddress(const AFileName: String; ALine: Cardinal): TDbgPtr; override;
@ -641,6 +642,7 @@ type
TDwarfLocationExpression = class
private
FContext: TFpDbgAddressContext;
FFrameBase: TDbgPtr;
FLastError: TFpError;
FOnFrameBaseNeeded: TNotifyEvent;
@ -652,7 +654,7 @@ type
public
//TODO: caller keeps data, and determines livetime of data
constructor Create(AExpressionData: Pointer; AMaxCount: Integer; ACU: TDwarfCompilationUnit;
AMemManager: TFpDbgMemManager);
AMemManager: TFpDbgMemManager; AContext: TFpDbgAddressContext);
procedure Evaluate;
function ResultKind: TDwarfLocationStackEntryKind;
function ResultData: TDbgPtr;
@ -661,6 +663,7 @@ type
property OnFrameBaseNeeded: TNotifyEvent read FOnFrameBaseNeeded write FOnFrameBaseNeeded;
property LastError: TFpError read FLastError;
property MemManager: TFpDbgMemManager read FMemManager;
property Context: TFpDbgAddressContext read FContext write FContext;
end;
function ULEB128toOrdinal(var p: PByte): QWord;
@ -1713,12 +1716,14 @@ end;
{ TDwarfLocationExpression }
constructor TDwarfLocationExpression.Create(AExpressionData: Pointer; AMaxCount: Integer;
ACU: TDwarfCompilationUnit; AMemManager: TFpDbgMemManager);
ACU: TDwarfCompilationUnit; AMemManager: TFpDbgMemManager; AContext: TFpDbgAddressContext);
begin
FStack.Clear;
FCU := ACU;
FData := AExpressionData;
FMaxData := FData + AMaxCount;FMemManager := AMemManager;
FMaxData := FData + AMaxCount;
FMemManager := AMemManager;
FContext := AContext;
end;
procedure TDwarfLocationExpression.Evaluate;
@ -1758,7 +1763,7 @@ var
begin
//TODO: zero fill / sign extend
if (ASize > SizeOf(AValue)) or (ASize > AddrSize) then exit(False);
Result := FMemManager.ReadAddress(AnAddress, ASize, AValue);
Result := FMemManager.ReadAddress(AnAddress, ASize, AValue, FContext);
if not Result then
SetError;
end;
@ -1767,7 +1772,7 @@ var
begin
//TODO: zero fill / sign extend
if (ASize > SizeOf(AValue)) or (ASize > AddrSize) then exit(False);
AValue := FMemManager.ReadAddressEx(AnAddress, AnAddrSpace, ASize);
AValue := FMemManager.ReadAddressEx(AnAddress, AnAddrSpace, ASize, FContext);
Result := IsValidLoc(AValue);
if not Result then
SetError;
@ -1805,7 +1810,6 @@ var
Entry, Entry2: TDwarfLocationStackEntry;
begin
AddrSize := FCU.FAddressSize;
FMemManager := FCU.FOwner.FMemManager;
FMemManager.ClearLastError;
FLastError := NoError;
CurData := FData;
@ -1855,14 +1859,14 @@ begin
DW_OP_lit0..DW_OP_lit31: FStack.Push(CurInstr^-DW_OP_lit0, lseValue);
DW_OP_reg0..DW_OP_reg31: begin
if not FMemManager.ReadRegister(CurInstr^-DW_OP_reg0, NewValue) then begin
if not FMemManager.ReadRegister(CurInstr^-DW_OP_reg0, NewValue, FContext) then begin
SetError;
exit;
end;
FStack.Push(NewValue, lseRegister);
end;
DW_OP_regx: begin
if not FMemManager.ReadRegister(ULEB128toOrdinal(CurData), NewValue) then begin
if not FMemManager.ReadRegister(ULEB128toOrdinal(CurData), NewValue, FContext) then begin
SetError;
exit;
end;
@ -1870,7 +1874,7 @@ begin
end;
DW_OP_breg0..DW_OP_breg31: begin
if not FMemManager.ReadRegister(CurInstr^-DW_OP_breg0, NewValue) then begin
if not FMemManager.ReadRegister(CurInstr^-DW_OP_breg0, NewValue, FContext) then begin
SetError;
exit;
end;
@ -1879,7 +1883,7 @@ begin
{$POP}
end;
DW_OP_bregx: begin
if not FMemManager.ReadRegister(ULEB128toOrdinal(CurData), NewValue) then begin
if not FMemManager.ReadRegister(ULEB128toOrdinal(CurData), NewValue, FContext) then begin
SetError;
exit;
end;
@ -2798,7 +2802,8 @@ begin
inherited Destroy;
end;
function TFpDwarfInfo.FindContext(AAddress: TDbgPtr): TDbgInfoAddressContext;
function TFpDwarfInfo.FindContext(AThreadId, AStackFrame: Integer;
AAddress: TDbgPtr): TFpDbgInfoContext;
var
Proc: TDbgDwarfSymbolBase;
begin
@ -2807,10 +2812,16 @@ begin
if Proc = nil then
exit;
Result := Proc.CompilationUnit.DwarfSymbolClassMap.CreateContext(AAddress, Proc, Self);
Result := Proc.CompilationUnit.DwarfSymbolClassMap.CreateContext
(AThreadId, AStackFrame, AAddress, Proc, Self);
Proc.ReleaseReference;
end;
function TFpDwarfInfo.FindContext(AAddress: TDbgPtr): TFpDbgInfoContext;
begin
FindContext(1, 0, AAddress);
end;
function TFpDwarfInfo.FindSymbol(AAddress: TDbgPtr): TFpDbgSymbol;
begin
Result := FindProcSymbol(AAddress);

View File

@ -15,8 +15,8 @@ type
public
class function HandleCompUnit(ACU: TDwarfCompilationUnit): Boolean; override;
//class function GetDwarfSymbolClass(ATag: Cardinal): TDbgDwarfSymbolBaseClass; override;
class function CreateContext(AnAddress: TDBGPtr; ASymbol: TFpDbgSymbol;
ADwarf: TFpDwarfInfo): TDbgInfoAddressContext; override;
class function CreateContext(AThreadId, AStackFrame: Integer; AnAddress: TDBGPtr; ASymbol: TFpDbgSymbol;
ADwarf: TFpDwarfInfo): TFpDbgInfoContext; override;
//class function CreateProcSymbol(ACompilationUnit: TDwarfCompilationUnit;
// AInfo: PDwarfAddressInfo; AAddress: TDbgPtr): TDbgDwarfSymbolBase; override;
end;
@ -42,10 +42,10 @@ begin
Result := pos('free pascal', s) > 0;
end;
class function TFpDwarfFreePascalSymbolClassMap.CreateContext(AnAddress: TDbgPtr;
ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo): TDbgInfoAddressContext;
class function TFpDwarfFreePascalSymbolClassMap.CreateContext(AThreadId, AStackFrame: Integer;
AnAddress: TDBGPtr; ASymbol: TFpDbgSymbol; ADwarf: TFpDwarfInfo): TFpDbgInfoContext;
begin
Result := TFpDwarfFreePascalAddressContext.Create(AnAddress, ASymbol, ADwarf);
Result := TFpDwarfFreePascalAddressContext.Create(AThreadId, AStackFrame, AnAddress, ASymbol, ADwarf);
end;
{ TFpDwarfFreePascalAddressContext }

View File

@ -424,21 +424,17 @@ type
function GetMemberCount: Integer; override;
end;
{ TDbgInfoAddressContext }
{ TFpDbgInfoContext }
TDbgInfoAddressContext = class(TRefCountedObject)
TFpDbgInfoContext = class(TFpDbgAddressContext)
protected
function GetAddress: TDbgPtr; virtual; abstract;
function GetSymbolAtAddress: TFpDbgSymbol; virtual;
function GetMemManager: TFpDbgMemManager; virtual;
function GetSizeOfAddress: Integer; virtual;
public
property Address: TDbgPtr read GetAddress;
property SymbolAtAddress: TFpDbgSymbol read GetSymbolAtAddress;
// search this, and all parent context
function FindSymbol(const {%H-}AName: String): TFpDbgValue; virtual;
property MemManager: TFpDbgMemManager read GetMemManager;
property SizeOfAddress: Integer read GetSizeOfAddress;
end;
{ TDbgInfo }
@ -450,7 +446,13 @@ type
procedure SetHasInfo;
public
constructor Create({%H-}ALoader: TDbgImageLoader); virtual;
function FindContext({%H-}AAddress: TDbgPtr): TDbgInfoAddressContext; virtual;
(* Context should be searched by Thread, and StackFrame. The Address can be
derived from this.
However a different Address may be froced.
TODO: for now address may be needed, as stack decoding is not done yet
*)
function FindContext(AThreadId, AStackFrame: Integer; {%H-}AAddress: TDbgPtr = 0): TFpDbgInfoContext; virtual;
function FindContext({%H-}AAddress: TDbgPtr): TFpDbgInfoContext; virtual; deprecated 'use FindContextFindContext(thread,stack,address)';
function FindSymbol(const {%H-}AName: String): TFpDbgSymbol; virtual; deprecated;
function FindSymbol({%H-}AAddress: TDbgPtr): TFpDbgSymbol; virtual; deprecated;
property HasInfo: Boolean read FHasInfo;
@ -776,22 +778,17 @@ end;
{ TDbgInfoAddressContext }
function TDbgInfoAddressContext.GetMemManager: TFpDbgMemManager;
function TFpDbgInfoContext.GetMemManager: TFpDbgMemManager;
begin
Result := nil;
end;
function TDbgInfoAddressContext.GetSizeOfAddress: Integer;
begin
Result := -1;
end;
function TDbgInfoAddressContext.GetSymbolAtAddress: TFpDbgSymbol;
function TFpDbgInfoContext.GetSymbolAtAddress: TFpDbgSymbol;
begin
Result := nil;
end;
function TDbgInfoAddressContext.FindSymbol(const AName: String): TFpDbgValue;
function TFpDbgInfoContext.FindSymbol(const AName: String): TFpDbgValue;
begin
Result := nil;
end;
@ -1267,7 +1264,13 @@ begin
inherited Create;
end;
function TDbgInfo.FindContext(AAddress: TDbgPtr): TDbgInfoAddressContext;
function TDbgInfo.FindContext(AThreadId, AStackFrame: Integer;
AAddress: TDbgPtr): TFpDbgInfoContext;
begin
Result := nil;;
end;
function TDbgInfo.FindContext(AAddress: TDbgPtr): TFpDbgInfoContext;
begin
Result := nil;
end;

View File

@ -12,8 +12,8 @@ unit FpdMemoryTools;
The code calls MemoryManager with an Address, a Size and a space for the data.
If the data needs to be extended (SizeOf(data) > TargetSize), then
MemConvertor is called to decide where in rovided space the read data should
initially be stored.
MemConvertor is called to decide where in the provided space the read data
should initially be stored.
Then the data is read using MemReader.
@ -24,17 +24,32 @@ unit FpdMemoryTools;
interface
uses
Classes, SysUtils, math, DbgIntfBaseTypes, FpErrorMessages;
Classes, SysUtils, math, DbgIntfBaseTypes, FpErrorMessages, LazClasses;
type
TFpDbgAddressContext = class(TRefCountedObject)
protected
function GetAddress: TDbgPtr; virtual; abstract;
function GetStackFrame: Integer; virtual; abstract;
function GetThreadId: Integer; virtual; abstract;
function GetSizeOfAddress: Integer; virtual; abstract;
public
property Address: TDbgPtr read GetAddress;
property ThreadId: Integer read GetThreadId; // experimental
property StackFrame: Integer read GetStackFrame; // experimental
property SizeOfAddress: Integer read GetSizeOfAddress;
end;
TFpDbgMemReaderBase = class
public
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; virtual; abstract;
function ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; virtual; abstract;
// ReadRegister may need TargetMemConvertor
// Register with reduced size are treated as unsigned
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr): Boolean; virtual; abstract;
// TODO: ReadRegister should only take THREAD-ID, not context
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr; AContext: TFpDbgAddressContext): Boolean; virtual; abstract;
function RegisterSize(ARegNum: Cardinal): Integer; virtual; abstract;
// Registernum from name
end;
@ -183,6 +198,7 @@ type
TFpDbgMemManager = class
private
FDefaultContext: TFpDbgAddressContext;
FLastError: TFpError;
FMemReader: TFpDbgMemReaderBase;
FTargetMemConvertor: TFpDbgMemConvertor;
@ -190,56 +206,64 @@ type
protected
function ReadMemory(AReadDataType: TFpDbgMemReadDataType;
const ALocation: TFpDbgMemLocation; ATargetSize: Cardinal;
ADest: Pointer; ADestSize: Cardinal): Boolean;
ADest: Pointer; ADestSize: Cardinal;
AContext: TFpDbgAddressContext = nil): Boolean;
public
constructor Create(AMemReader: TFpDbgMemReaderBase; AMemConvertor: TFpDbgMemConvertor);
constructor Create(AMemReader: TFpDbgMemReaderBase; ATargenMemConvertor, ASelfMemConvertor: TFpDbgMemConvertor);
procedure ClearLastError;
function ReadMemory(const ALocation: TFpDbgMemLocation; ASize: Cardinal; ADest: Pointer): Boolean;
function ReadMemoryEx(const ALocation: TFpDbgMemLocation; AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr): Boolean;
function ReadMemory(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
ADest: Pointer; AContext: TFpDbgAddressContext = nil): Boolean;
function ReadMemoryEx(const ALocation: TFpDbgMemLocation; AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer; AContext: TFpDbgAddressContext = nil): Boolean;
(* ReadRegister needs a Context, to get the thread/stackframe
*)
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr; AContext: TFpDbgAddressContext {= nil}): Boolean;
// location will be invalid, if read failed
function ReadAddress(const ALocation: TFpDbgMemLocation; ASize: Cardinal): TFpDbgMemLocation;
function ReadAddressEx(const ALocation: TFpDbgMemLocation; AnAddressSpace: TDbgPtr; ASize: Cardinal): TFpDbgMemLocation;
function ReadAddress(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
AContext: TFpDbgAddressContext = nil): TFpDbgMemLocation;
function ReadAddressEx(const ALocation: TFpDbgMemLocation; AnAddressSpace: TDbgPtr;
ASize: Cardinal; AContext: TFpDbgAddressContext = nil): TFpDbgMemLocation;
// ALocation and AnAddress MUST NOT be the same variable on the callers side
function ReadAddress (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
out AnAddress: TFpDbgMemLocation): Boolean; inline;
out AnAddress: TFpDbgMemLocation;
AContext: TFpDbgAddressContext = nil): Boolean; inline;
//function ReadAddress (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
// out AnAddress: TFpDbgMemLocation;
// AnOpts: TFpDbgMemReadOptions): Boolean;
// AnOpts: TFpDbgMemReadOptions; AContext: TFpDbgAddressContext = nil): Boolean;
function ReadUnsignedInt(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
out AValue: QWord): Boolean; inline;
out AValue: QWord; AContext: TFpDbgAddressContext = nil): Boolean; inline;
//function ReadUnsignedInt(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
// out AValue: QWord;
// AnOpts: TFpDbgMemReadOptions): Boolean;
// AnOpts: TFpDbgMemReadOptions; AContext: TFpDbgAddressContext = nil): Boolean;
function ReadSignedInt (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
out AValue: Int64): Boolean; inline;
out AValue: Int64; AContext: TFpDbgAddressContext = nil): Boolean; inline;
//function ReadSignedInt (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
// out AValue: Int64;
// AnOpts: TFpDbgMemReadOptions): Boolean;
// AnOpts: TFpDbgMemReadOptions; AContext: TFpDbgAddressContext = nil): Boolean;
// //enum/set: may need bitorder swapped
function ReadEnum (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
out AValue: QWord): Boolean; inline;
out AValue: QWord; AContext: TFpDbgAddressContext = nil): Boolean; inline;
//function ReadEnum (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
// out AValue: QWord;
// AnOpts: TFpDbgMemReadOptions): Boolean;
// AnOpts: TFpDbgMemReadOptions; AContext: TFpDbgAddressContext = nil): Boolean;
function ReadSet (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
out AValue: TBytes): Boolean; inline;
out AValue: TBytes; AContext: TFpDbgAddressContext = nil): Boolean; inline;
//function ReadSet (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
// out AValue: TBytes;
// AnOpts: TFpDbgMemReadOptions): Boolean;
// AnOpts: TFpDbgMemReadOptions; AContext: TFpDbgAddressContext = nil): Boolean;
function ReadFloat (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
out AValue: Extended): Boolean; inline;
out AValue: Extended; AContext: TFpDbgAddressContext = nil): Boolean; inline;
//function ReadFloat (const ALocation: TFpDbgMemLocation; ASize: Cardinal;
// out AValue: Extended;
// AnOpts: TFpDbgMemReadOptions): Boolean;
// AnOpts: TFpDbgMemReadOptions; AContext: TFpDbgAddressContext = nil): Boolean;
property TargetMemConvertor: TFpDbgMemConvertor read FTargetMemConvertor;
property SelfMemConvertor: TFpDbgMemConvertor read FSelfMemConvertor;
property LastError: TFpError read FLastError;
property DefaultContext: TFpDbgAddressContext read FDefaultContext write FDefaultContext;
end;
function NilLoc: TFpDbgMemLocation; inline;
@ -496,7 +520,7 @@ end;
function TFpDbgMemManager.ReadMemory(AReadDataType: TFpDbgMemReadDataType;
const ALocation: TFpDbgMemLocation; ATargetSize: Cardinal; ADest: Pointer;
ADestSize: Cardinal): Boolean;
ADestSize: Cardinal; AContext: TFpDbgAddressContext): Boolean;
var
Addr2: Pointer;
i: Integer;
@ -505,6 +529,8 @@ var
begin
FLastError := NoError;
Result := False;
if AContext = nil then
AContext := FDefaultContext;
case ALocation.MType of
mlfInvalid, mlfUninitialized:
FLastError := CreateError(fpErrCanNotReadInvalidMem);
@ -545,7 +571,7 @@ begin
i := FMemReader.RegisterSize(Cardinal(ALocation.Address));
if i = 0 then
exit; // failed
if not FMemReader.ReadRegister(Cardinal(ALocation.Address), TmpVal) then
if not FMemReader.ReadRegister(Cardinal(ALocation.Address), TmpVal, AContext) then
exit; // failed
end;
end;
@ -593,7 +619,7 @@ begin
end;
function TFpDbgMemManager.ReadMemory(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
ADest: Pointer): Boolean;
ADest: Pointer; AContext: TFpDbgAddressContext): Boolean;
var
Addr2: Pointer;
i: Integer;
@ -602,6 +628,8 @@ var
begin
FLastError := NoError;
Result := False;
if AContext = nil then
AContext := FDefaultContext;
case ALocation.MType of
mlfInvalid, mlfUninitialized: ;
mlfTargetMem:
@ -626,7 +654,7 @@ begin
i := FMemReader.RegisterSize(Cardinal(ALocation.Address));
if i = 0 then
exit; // failed
if not FMemReader.ReadRegister(Cardinal(ALocation.Address), TmpVal) then
if not FMemReader.ReadRegister(Cardinal(ALocation.Address), TmpVal, AContext) then
exit; // failed
end;
end;
@ -651,79 +679,84 @@ begin
end;
function TFpDbgMemManager.ReadMemoryEx(const ALocation: TFpDbgMemLocation;
AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer;
AContext: TFpDbgAddressContext): Boolean;
begin
FLastError := NoError;
// AnAddressSpace is ignored, when not actually reading from target address
case ALocation.MType of
mlfTargetMem: Result := FMemReader.ReadMemoryEx(ALocation.Address, AnAddressSpace, ASize, ADest);
else
Result := ReadMemory(ALocation, ASize, ADest);
Result := ReadMemory(ALocation, ASize, ADest, AContext);
end;
if (not Result) and (not IsError(FLastError)) then
FLastError := CreateError(fpErrFailedReadMem);
end;
function TFpDbgMemManager.ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr): Boolean;
function TFpDbgMemManager.ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr;
AContext: TFpDbgAddressContext): Boolean;
begin
FLastError := NoError;
Result := FMemReader.ReadRegister(ARegNum, AValue);
// TODO: If stackframe <> 0 then get the register internally (unroll stack)
if AContext = nil then
AContext := FDefaultContext;
Result := FMemReader.ReadRegister(ARegNum, AValue, AContext);
end;
function TFpDbgMemManager.ReadAddress(const ALocation: TFpDbgMemLocation;
ASize: Cardinal): TFpDbgMemLocation;
function TFpDbgMemManager.ReadAddress(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
AContext: TFpDbgAddressContext): TFpDbgMemLocation;
begin
Result.MType := mlfTargetMem;
if not ReadMemory(rdtAddress, ALocation, ASize, @Result.Address, SizeOf(Result.Address)) then
if not ReadMemory(rdtAddress, ALocation, ASize, @Result.Address, SizeOf(Result.Address), AContext) then
Result := InvalidLoc;
end;
function TFpDbgMemManager.ReadAddressEx(const ALocation: TFpDbgMemLocation;
AnAddressSpace: TDbgPtr; ASize: Cardinal): TFpDbgMemLocation;
AnAddressSpace: TDbgPtr; ASize: Cardinal; AContext: TFpDbgAddressContext): TFpDbgMemLocation;
begin
Result := InvalidLoc;
end;
function TFpDbgMemManager.ReadAddress(const ALocation: TFpDbgMemLocation; ASize: Cardinal; out
AnAddress: TFpDbgMemLocation): Boolean;
AnAddress: TFpDbgMemLocation; AContext: TFpDbgAddressContext): Boolean;
begin
Result := ReadMemory(rdtAddress, ALocation, ASize, @AnAddress.Address, SizeOf(AnAddress.Address));
Result := ReadMemory(rdtAddress, ALocation, ASize, @AnAddress.Address, SizeOf(AnAddress.Address), AContext);
if Result
then AnAddress.MType := mlfTargetMem
else AnAddress.MType := mlfInvalid;
end;
function TFpDbgMemManager.ReadUnsignedInt(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
out AValue: QWord): Boolean;
out AValue: QWord; AContext: TFpDbgAddressContext): Boolean;
begin
Result := ReadMemory(rdtUnsignedInt, ALocation, ASize, @AValue, SizeOf(AValue));
Result := ReadMemory(rdtUnsignedInt, ALocation, ASize, @AValue, SizeOf(AValue), AContext);
end;
function TFpDbgMemManager.ReadSignedInt(const ALocation: TFpDbgMemLocation; ASize: Cardinal;
out AValue: Int64): Boolean;
out AValue: Int64; AContext: TFpDbgAddressContext): Boolean;
begin
Result := ReadMemory(rdtSignedInt, ALocation, ASize, @AValue, SizeOf(AValue));
Result := ReadMemory(rdtSignedInt, ALocation, ASize, @AValue, SizeOf(AValue), AContext);
end;
function TFpDbgMemManager.ReadEnum(const ALocation: TFpDbgMemLocation; ASize: Cardinal; out
AValue: QWord): Boolean;
AValue: QWord; AContext: TFpDbgAddressContext): Boolean;
begin
Result := ReadMemory(rdtEnum, ALocation, ASize, @AValue, SizeOf(AValue));
Result := ReadMemory(rdtEnum, ALocation, ASize, @AValue, SizeOf(AValue), AContext);
end;
function TFpDbgMemManager.ReadSet(const ALocation: TFpDbgMemLocation; ASize: Cardinal; out
AValue: TBytes): Boolean;
AValue: TBytes; AContext: TFpDbgAddressContext): Boolean;
begin
SetLength(AValue, ASize);
Result := ASize > 0;
if Result then
Result := ReadMemory(rdtSet, ALocation, ASize, @AValue[0], ASize);
Result := ReadMemory(rdtSet, ALocation, ASize, @AValue[0], ASize, AContext);
end;
function TFpDbgMemManager.ReadFloat(const ALocation: TFpDbgMemLocation; ASize: Cardinal; out
AValue: Extended): Boolean;
AValue: Extended; AContext: TFpDbgAddressContext): Boolean;
begin
Result := ReadMemory(rdtfloat, ALocation, ASize, @AValue, SizeOf(AValue));
Result := ReadMemory(rdtfloat, ALocation, ASize, @AValue, SizeOf(AValue), AContext);
end;
end.

View File

@ -50,7 +50,7 @@ type
TFpPascalExpression = class
private
FError: TFpError;
FContext: TDbgInfoAddressContext;
FContext: TFpDbgInfoContext;
FTextExpression: String;
FExpressionPart: TFpPascalExpressionPart;
FValid: Boolean;
@ -62,9 +62,9 @@ type
protected
function GetDbgSymbolForIdentifier({%H-}AnIdent: String): TFpDbgValue;
property ExpressionPart: TFpPascalExpressionPart read FExpressionPart;
property Context: TDbgInfoAddressContext read FContext;
property Context: TFpDbgInfoContext read FContext;
public
constructor Create(ATextExpression: String; AContext: TDbgInfoAddressContext);
constructor Create(ATextExpression: String; AContext: TFpDbgInfoContext);
destructor Destroy; override;
function DebugDump(AWithResults: Boolean = False): String;
property Error: TFpError read FError;
@ -399,13 +399,13 @@ type
private
FPointerLevels: Integer;
FPointedTo: TFpDbgSymbol;
FContext: TDbgInfoAddressContext;
FContext: TFpDbgInfoContext;
protected
// NameNeeded // "^TPointedTo"
procedure TypeInfoNeeded; override;
public
constructor Create(const APointedTo: TFpDbgSymbol; AContext: TDbgInfoAddressContext; APointerLevels: Integer);
constructor Create(const APointedTo: TFpDbgSymbol; AContext: TDbgInfoAddressContext);
constructor Create(const APointedTo: TFpDbgSymbol; AContext: TFpDbgInfoContext; APointerLevels: Integer);
constructor Create(const APointedTo: TFpDbgSymbol; AContext: TFpDbgInfoContext);
destructor Destroy; override;
function TypeCastValue(AValue: TFpDbgValue): TFpDbgValue; override;
end;
@ -432,12 +432,12 @@ type
TFpPasParserValue = class(TFpDbgValue)
private
FContext: TDbgInfoAddressContext;
FContext: TFpDbgInfoContext;
protected
function DebugText(AIndent: String): String; virtual;
public
constructor Create(AContext: TDbgInfoAddressContext);
property Context: TDbgInfoAddressContext read FContext;
constructor Create(AContext: TFpDbgInfoContext);
property Context: TFpDbgInfoContext read FContext;
end;
{ TFpPasParserValueCastToPointer
@ -459,7 +459,7 @@ type
function GetDataAddress: TFpDbgMemLocation; override;
function GetMember(AIndex: Int64): TFpDbgValue; override;
public
constructor Create(AValue: TFpDbgValue; ATypeInfo: TFpDbgSymbol; AContext: TDbgInfoAddressContext);
constructor Create(AValue: TFpDbgValue; ATypeInfo: TFpDbgSymbol; AContext: TFpDbgInfoContext);
destructor Destroy; override;
end;
@ -474,7 +474,7 @@ type
protected
function GetDbgSymbol: TFpDbgSymbol; override; // returns a TPasParserSymbolPointer
public
constructor Create(ATypeInfo: TFpDbgSymbol; AContext: TDbgInfoAddressContext);
constructor Create(ATypeInfo: TFpDbgSymbol; AContext: TFpDbgInfoContext);
destructor Destroy; override;
procedure IncRefLevel;
function GetTypeCastedValue(ADataVal: TFpDbgValue): TFpDbgValue; override;
@ -499,8 +499,8 @@ type
function GetAsCardinal: QWord; override; // reads men
function GetTypeInfo: TFpDbgSymbol; override; // TODO: Cardinal? Why? // TODO: does not handle AOffset
public
constructor Create(AValue: TFpDbgValue; AContext: TDbgInfoAddressContext);
constructor Create(AValue: TFpDbgValue; AContext: TDbgInfoAddressContext; AOffset: Int64);
constructor Create(AValue: TFpDbgValue; AContext: TFpDbgInfoContext);
constructor Create(AValue: TFpDbgValue; AContext: TFpDbgInfoContext; AOffset: Int64);
destructor Destroy; override;
end;
@ -523,7 +523,7 @@ type
function GetDataAddress: TFpDbgMemLocation; override;
function GetMember(AIndex: Int64): TFpDbgValue; override;
public
constructor Create(AValue: TFpDbgValue; AContext: TDbgInfoAddressContext);
constructor Create(AValue: TFpDbgValue; AContext: TFpDbgInfoContext);
destructor Destroy; override;
property PointedToValue: TFpDbgValue read GetPointedToValue;
end;
@ -551,7 +551,7 @@ begin
Result := AIndent + DbgSName(Self) + ' DbsSym='+DbgSName(DbgSymbol)+' Type='+DbgSName(TypeInfo) + LineEnding;
end;
constructor TFpPasParserValue.Create(AContext: TDbgInfoAddressContext);
constructor TFpPasParserValue.Create(AContext: TFpDbgInfoContext);
begin
FContext := AContext;
inherited Create;
@ -638,7 +638,7 @@ begin
end;
constructor TFpPasParserValueCastToPointer.Create(AValue: TFpDbgValue;
ATypeInfo: TFpDbgSymbol; AContext: TDbgInfoAddressContext);
ATypeInfo: TFpDbgSymbol; AContext: TFpDbgInfoContext);
begin
inherited Create(AContext);
FValue := AValue;
@ -676,7 +676,7 @@ begin
end;
constructor TFpPasParserValueMakeReftype.Create(ATypeInfo: TFpDbgSymbol;
AContext: TDbgInfoAddressContext);
AContext: TFpDbgInfoContext);
begin
inherited Create(AContext);
FSourceTypeSymbol := ATypeInfo;
@ -755,7 +755,7 @@ function TFpPasParserValueDerefPointer.GetAsCardinal: QWord;
var
m: TFpDbgMemManager;
Addr: TFpDbgMemLocation;
Ctx: TDbgInfoAddressContext;
Ctx: TFpDbgInfoContext;
AddrSize: Integer;
begin
Result := FCardinal;
@ -790,13 +790,13 @@ begin
end;
constructor TFpPasParserValueDerefPointer.Create(AValue: TFpDbgValue;
AContext: TDbgInfoAddressContext);
AContext: TFpDbgInfoContext);
begin
Create(AValue, AContext, 0);
end;
constructor TFpPasParserValueDerefPointer.Create(AValue: TFpDbgValue;
AContext: TDbgInfoAddressContext; AOffset: Int64);
AContext: TFpDbgInfoContext; AOffset: Int64);
begin
inherited Create(AContext);
FValue := AValue;
@ -897,7 +897,7 @@ begin
end;
constructor TFpPasParserValueAddressOf.Create(AValue: TFpDbgValue;
AContext: TDbgInfoAddressContext);
AContext: TFpDbgInfoContext);
begin
inherited Create(AContext);
FValue := AValue;
@ -952,7 +952,7 @@ begin
end;
constructor TPasParserSymbolPointer.Create(const APointedTo: TFpDbgSymbol;
AContext: TDbgInfoAddressContext; APointerLevels: Integer);
AContext: TFpDbgInfoContext; APointerLevels: Integer);
begin
inherited Create('');
FContext := AContext;
@ -966,7 +966,7 @@ begin
end;
constructor TPasParserSymbolPointer.Create(const APointedTo: TFpDbgSymbol;
AContext: TDbgInfoAddressContext);
AContext: TFpDbgInfoContext);
begin
Create(APointedTo, AContext, 1);
end;
@ -1613,7 +1613,7 @@ begin
end;
constructor TFpPascalExpression.Create(ATextExpression: String;
AContext: TDbgInfoAddressContext);
AContext: TFpDbgInfoContext);
begin
FContext := AContext;
FTextExpression := ATextExpression;

View File

@ -22,7 +22,8 @@ type
constructor Create;
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
function ReadMemoryEx({%H-}AnAddress, {%H-}AnAddressSpace: TDbgPtr; {%H-}ASize: Cardinal; {%H-}ADest: Pointer): Boolean; override;
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr): Boolean; override;
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr;
AContext: TFpDbgAddressContext): Boolean; override;
function RegisterSize(ARegNum: Cardinal): Integer; override;
end;
@ -413,7 +414,8 @@ begin
Result := False;
end;
function TTestMemReader.ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr): Boolean;
function TTestMemReader.ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr;
AContext: TFpDbgAddressContext): Boolean;
begin
Result := True;
AValue := RegisterValues[ARegNum];

View File

@ -19,9 +19,9 @@ type
TTestTypeInfo = class(TTestCase)
protected
FDwarfInfo: TDbgDwarf;
FDwarfInfo: TFpDwarfInfo;
FCurrentTestName: String;
FCurrentContext: TDbgInfoAddressContext;
FCurrentContext: TFpDbgInfoContext;
FExpression: TFpPascalExpression;
FImageLoader: TTestDummyImageLoader;
FMemReader: TTestMemReader;
@ -322,7 +322,7 @@ begin
FImageLoader := ALoaderClass.Create;
FMemReader := TTestMemReader.Create;
FMemManager := TFpDbgMemManager.Create(FMemReader, TFpDbgMemConvertorLittleEndian.Create);
FDwarfInfo := TDbgDwarf.Create(FImageLoader);
FDwarfInfo := TFpDwarfInfo.Create(FImageLoader);
FDwarfInfo.MemManager := FMemManager;
FDwarfInfo.LoadCompilationUnits;
end;

View File

@ -35,13 +35,13 @@ type
FCmd: TGDBMIDebuggerCommandMemReader;
protected
// TODO: needs to be handled by memory manager
FThreadId, FStackFrame: Integer;
//FThreadId, FStackFrame: Integer;
public
constructor Create(ADebugger: TFpGDBMIDebugger);
destructor Destroy; override;
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
function ReadMemoryEx({%H-}AnAddress, {%H-}AnAddressSpace:{%H-} TDbgPtr; ASize: {%H-}Cardinal; ADest: Pointer): Boolean; override;
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr): Boolean; override;
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr; AContext: TFpDbgAddressContext): Boolean; override;
function RegisterSize({%H-}ARegNum: Cardinal): Integer; override;
end;
@ -74,7 +74,7 @@ type
FMemManager: TFpDbgMemManager;
// cache last context
FlastStackFrame, FLastThread: Integer;
FLastContext: array [0..MAX_CTX_CACHE-1] of TDbgInfoAddressContext;
FLastContext: array [0..MAX_CTX_CACHE-1] of TFpDbgInfoContext;
protected
function CreateCommandStartDebugging(AContinueCommand: TGDBMIDebuggerCommand): TGDBMIDebuggerCommandStartDebugging; override;
function CreateLineInfo: TDBGLineInfo; override;
@ -88,7 +88,7 @@ type
procedure GetCurrentContext(out AThreadId, AStackFrame: Integer);
function GetLocationForContext(AThreadId, AStackFrame: Integer): TDBGPtr;
function GetInfoContextForContext(AThreadId, AStackFrame: Integer): TDbgInfoAddressContext;
function GetInfoContextForContext(AThreadId, AStackFrame: Integer): TFpDbgInfoContext;
property CurrentCommand;
property TargetPID;
protected
@ -320,8 +320,8 @@ begin
Result := False;
end;
function TFpGDBMIDbgMemReader.ReadRegister(ARegNum: Cardinal; out
AValue: TDbgPtr): Boolean;
function TFpGDBMIDbgMemReader.ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr;
AContext: TFpDbgAddressContext): Boolean;
var
rname: String;
v: String;
@ -367,7 +367,7 @@ begin
exit;
end;
{$ENDIF}
Reg := FDebugger.Registers.CurrentRegistersList[FThreadId, FStackFrame];
Reg := FDebugger.Registers.CurrentRegistersList[AContext.ThreadId, AContext.StackFrame];
for i := 0 to Reg.Count - 1 do
if UpperCase(Reg[i].Name) = rname then
begin
@ -750,9 +750,10 @@ begin
end;
function TFpGDBMIDebugger.GetInfoContextForContext(AThreadId,
AStackFrame: Integer): TDbgInfoAddressContext;
AStackFrame: Integer): TFpDbgInfoContext;
var
Addr: TDBGPtr;
i: Integer;
begin
Result := nil;
if FDwarfInfo = nil then
@ -769,17 +770,20 @@ begin
exit;
end;
if (AStackFrame >= FlastStackFrame) and
(AStackFrame - FlastStackFrame < MAX_CTX_CACHE) and
(FLastContext[AStackFrame - FlastStackFrame] <> nil) and
(FLastContext[AStackFrame - FlastStackFrame].Address = Addr)
i := AStackFrame - FlastStackFrame;
if (i >= 0) and
(i < MAX_CTX_CACHE) and
(FLastContext[i] <> nil) and
(FLastContext[i].Address = Addr) and
(FLastContext[i].ThreadId = AThreadId) and
(FLastContext[i].StackFrame = AStackFrame)
then begin
Result := FLastContext[AStackFrame - FlastStackFrame];
exit;
end;
DebugLn(['* FDwarfInfo.FindContext ', dbgs(Addr)]);
Result := FDwarfInfo.FindContext(Addr);
Result := FDwarfInfo.FindContext(AThreadId, AStackFrame, Addr);
FLastThread := AThreadId;
FlastStackFrame := AStackFrame;
@ -802,7 +806,7 @@ function TFpGDBMIDebugger.EvaluateExpression(AWatchValue: TWatchValue;
AExpression: String; var AResText: String; out ATypeInfo: TDBGType;
EvalFlags: TDBGEvaluateFlags): Boolean;
var
Ctx: TDbgInfoAddressContext;
Ctx: TFpDbgInfoContext;
PasExpr: TFpPascalExpression;
ResValue: TFpDbgValue;
@ -982,12 +986,12 @@ begin
if AWatchValue <> nil then begin
EvalFlags := AWatchValue.EvaluateFlags;
AExpression := AWatchValue.Expression;
FMemReader.FThreadId := AWatchValue.ThreadId;
FMemReader.FStackFrame := AWatchValue.StackFrame;
end
else begin
FMemReader.FThreadId := CurrentThreadId;
FMemReader.FStackFrame := CurrentStackFrame;
//FMemReader.FThreadId := AWatchValue.ThreadId;
//FMemReader.FStackFrame := AWatchValue.StackFrame;
//end
//else begin
// FMemReader.FThreadId := CurrentThreadId;
// FMemReader.FStackFrame := CurrentStackFrame;
end;
if AWatchValue <> nil then
@ -995,6 +999,8 @@ begin
else
Ctx := GetInfoContextForContext(CurrentThreadId, CurrentStackFrame);
if Ctx = nil then exit;
FMemManager.DefaultContext := Ctx;
FPrettyPrinter.AddressSize := ctx.SizeOfAddress;
PasExpr := TFpPascalExpression.Create(AExpression, Ctx);
@ -1063,6 +1069,7 @@ DebugLn(ErrorHandler.ErrorAsString(PasExpr.Error));
finally
PasExpr.Free;
FMemManager.DefaultContext := nil;
end;
end;