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

View File

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

View File

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

View File

@ -424,21 +424,17 @@ type
function GetMemberCount: Integer; override; function GetMemberCount: Integer; override;
end; end;
{ TDbgInfoAddressContext } { TFpDbgInfoContext }
TDbgInfoAddressContext = class(TRefCountedObject) TFpDbgInfoContext = class(TFpDbgAddressContext)
protected protected
function GetAddress: TDbgPtr; virtual; abstract;
function GetSymbolAtAddress: TFpDbgSymbol; virtual; function GetSymbolAtAddress: TFpDbgSymbol; virtual;
function GetMemManager: TFpDbgMemManager; virtual; function GetMemManager: TFpDbgMemManager; virtual;
function GetSizeOfAddress: Integer; virtual;
public public
property Address: TDbgPtr read GetAddress;
property SymbolAtAddress: TFpDbgSymbol read GetSymbolAtAddress; property SymbolAtAddress: TFpDbgSymbol read GetSymbolAtAddress;
// search this, and all parent context // search this, and all parent context
function FindSymbol(const {%H-}AName: String): TFpDbgValue; virtual; function FindSymbol(const {%H-}AName: String): TFpDbgValue; virtual;
property MemManager: TFpDbgMemManager read GetMemManager; property MemManager: TFpDbgMemManager read GetMemManager;
property SizeOfAddress: Integer read GetSizeOfAddress;
end; end;
{ TDbgInfo } { TDbgInfo }
@ -450,7 +446,13 @@ type
procedure SetHasInfo; procedure SetHasInfo;
public public
constructor Create({%H-}ALoader: TDbgImageLoader); virtual; 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(const {%H-}AName: String): TFpDbgSymbol; virtual; deprecated;
function FindSymbol({%H-}AAddress: TDbgPtr): TFpDbgSymbol; virtual; deprecated; function FindSymbol({%H-}AAddress: TDbgPtr): TFpDbgSymbol; virtual; deprecated;
property HasInfo: Boolean read FHasInfo; property HasInfo: Boolean read FHasInfo;
@ -776,22 +778,17 @@ end;
{ TDbgInfoAddressContext } { TDbgInfoAddressContext }
function TDbgInfoAddressContext.GetMemManager: TFpDbgMemManager; function TFpDbgInfoContext.GetMemManager: TFpDbgMemManager;
begin begin
Result := nil; Result := nil;
end; end;
function TDbgInfoAddressContext.GetSizeOfAddress: Integer; function TFpDbgInfoContext.GetSymbolAtAddress: TFpDbgSymbol;
begin
Result := -1;
end;
function TDbgInfoAddressContext.GetSymbolAtAddress: TFpDbgSymbol;
begin begin
Result := nil; Result := nil;
end; end;
function TDbgInfoAddressContext.FindSymbol(const AName: String): TFpDbgValue; function TFpDbgInfoContext.FindSymbol(const AName: String): TFpDbgValue;
begin begin
Result := nil; Result := nil;
end; end;
@ -1267,7 +1264,13 @@ begin
inherited Create; inherited Create;
end; 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 begin
Result := nil; Result := nil;
end; end;

View File

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

View File

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

View File

@ -22,7 +22,8 @@ type
constructor Create; constructor Create;
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override; 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 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; function RegisterSize(ARegNum: Cardinal): Integer; override;
end; end;
@ -413,7 +414,8 @@ begin
Result := False; Result := False;
end; end;
function TTestMemReader.ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr): Boolean; function TTestMemReader.ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr;
AContext: TFpDbgAddressContext): Boolean;
begin begin
Result := True; Result := True;
AValue := RegisterValues[ARegNum]; AValue := RegisterValues[ARegNum];

View File

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

View File

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