mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-23 01:39:31 +02:00
FpDebug: prepare mem-manager for context
git-svn-id: trunk@44627 -
This commit is contained in:
parent
0eaa8042c5
commit
03d6bdade7
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 }
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user