mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 22:40:15 +02:00
FpDebug: Fixed reading memory for #0 terminated string data
git-svn-id: trunk@63391 -
This commit is contained in:
parent
cffa67bd52
commit
f59a294a01
@ -127,7 +127,8 @@ type
|
|||||||
function GetDbgProcess: TDbgProcess; virtual; abstract;
|
function GetDbgProcess: TDbgProcess; virtual; abstract;
|
||||||
function GetDbgThread(AContext: TFpDbgAddressContext): TDbgThread; virtual;
|
function GetDbgThread(AContext: TFpDbgAddressContext): TDbgThread; virtual;
|
||||||
public
|
public
|
||||||
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
|
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override; overload;
|
||||||
|
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer; out ABytesRead: Cardinal): Boolean; override; overload;
|
||||||
function ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
|
function ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
|
||||||
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr; AContext: TFpDbgAddressContext): 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;
|
||||||
@ -1183,6 +1184,12 @@ begin
|
|||||||
result := GetDbgProcess.ReadData(AnAddress, ASize, ADest^);
|
result := GetDbgProcess.ReadData(AnAddress, ASize, ADest^);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TDbgMemReader.ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal;
|
||||||
|
ADest: Pointer; out ABytesRead: Cardinal): Boolean;
|
||||||
|
begin
|
||||||
|
result := GetDbgProcess.ReadData(AnAddress, ASize, ADest^, ABytesRead);
|
||||||
|
end;
|
||||||
|
|
||||||
function TDbgMemReader.ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
|
function TDbgMemReader.ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
|
||||||
begin
|
begin
|
||||||
Assert(AnAddressSpace>0,'TDbgMemReader.ReadMemoryEx ignores AddressSpace');
|
Assert(AnAddressSpace>0,'TDbgMemReader.ReadMemoryEx ignores AddressSpace');
|
||||||
|
@ -2075,7 +2075,7 @@ end;
|
|||||||
function TFpValueDwarfPointer.GetAsString: AnsiString;
|
function TFpValueDwarfPointer.GetAsString: AnsiString;
|
||||||
var
|
var
|
||||||
t: TFpSymbol;
|
t: TFpSymbol;
|
||||||
i: Integer;
|
i: Cardinal;
|
||||||
Size: TFpDbgValueSize;
|
Size: TFpDbgValueSize;
|
||||||
begin
|
begin
|
||||||
Result := '';
|
Result := '';
|
||||||
@ -2096,13 +2096,14 @@ begin
|
|||||||
if (MemManager <> nil) and (t <> nil) and (t.Kind = skChar) and IsReadableMem(GetDerefAddress) then begin // pchar
|
if (MemManager <> nil) and (t <> nil) and (t.Kind = skChar) and IsReadableMem(GetDerefAddress) then begin // pchar
|
||||||
SetLength(Result, 2000);
|
SetLength(Result, 2000);
|
||||||
i := 2000;
|
i := 2000;
|
||||||
while (i > 0) and (not MemManager.ReadMemory(GetDerefAddress, SizeVal(i), @Result[1])) do
|
|
||||||
i := i div 2;
|
if not MemManager.ReadMemory(GetDerefAddress, SizeVal(i), @Result[1], nil, [mmfPartialRead]) then begin
|
||||||
if i = 0 then begin
|
|
||||||
Result := '';
|
Result := '';
|
||||||
SetLastError(MemManager.LastError);
|
SetLastError(MemManager.LastError);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
i := MemManager.PartialReadResultLenght;
|
||||||
SetLength(Result,i);
|
SetLength(Result,i);
|
||||||
i := pos(#0, Result);
|
i := pos(#0, Result);
|
||||||
if i > 0 then
|
if i > 0 then
|
||||||
@ -2115,7 +2116,7 @@ end;
|
|||||||
function TFpValueDwarfPointer.GetAsWideString: WideString;
|
function TFpValueDwarfPointer.GetAsWideString: WideString;
|
||||||
var
|
var
|
||||||
t: TFpSymbol;
|
t: TFpSymbol;
|
||||||
i: Integer;
|
i: Cardinal;
|
||||||
begin
|
begin
|
||||||
t := TypeInfo;
|
t := TypeInfo;
|
||||||
if (t <> nil) then t := t.TypeInfo;
|
if (t <> nil) then t := t.TypeInfo;
|
||||||
@ -2123,13 +2124,14 @@ begin
|
|||||||
if (MemManager <> nil) and (t <> nil) and (t.Kind = skChar) and IsReadableMem(GetDerefAddress) then begin // pchar
|
if (MemManager <> nil) and (t <> nil) and (t.Kind = skChar) and IsReadableMem(GetDerefAddress) then begin // pchar
|
||||||
SetLength(Result, 2000);
|
SetLength(Result, 2000);
|
||||||
i := 4000; // 2000 * 16 bit
|
i := 4000; // 2000 * 16 bit
|
||||||
while (i > 0) and (not MemManager.ReadMemory(GetDerefAddress, SizeVal(i), @Result[1])) do
|
|
||||||
i := i div 2;
|
if not MemManager.ReadMemory(GetDerefAddress, SizeVal(i), @Result[1], nil, [mmfPartialRead]) then begin
|
||||||
if i = 0 then begin
|
|
||||||
Result := '';
|
Result := '';
|
||||||
SetLastError(MemManager.LastError);
|
SetLastError(MemManager.LastError);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
i := MemManager.PartialReadResultLenght;
|
||||||
SetLength(Result, i div 2);
|
SetLength(Result, i div 2);
|
||||||
i := pos(#0, Result);
|
i := pos(#0, Result);
|
||||||
if i > 0 then
|
if i > 0 then
|
||||||
|
@ -78,9 +78,13 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TFpDbgMemReaderBase }
|
||||||
|
|
||||||
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; overload;
|
||||||
|
// inherited Memreaders should implement partial size ReadMemory, and forward it to the TDbgProcess class
|
||||||
|
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer; out ABytesRead: Cardinal): Boolean; virtual; overload;
|
||||||
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
|
||||||
@ -225,7 +229,8 @@ type
|
|||||||
function AddCacheEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal): TFpDbgMemCacheBase; virtual;
|
function AddCacheEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal): TFpDbgMemCacheBase; virtual;
|
||||||
procedure RemoveCache(ACache: TFpDbgMemCacheBase); virtual;
|
procedure RemoveCache(ACache: TFpDbgMemCacheBase); virtual;
|
||||||
|
|
||||||
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; virtual;
|
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; virtual; overload;
|
||||||
|
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer; ABytesRead: Cardinal): Boolean; virtual; overload;
|
||||||
function ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; virtual;
|
function ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; virtual;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -258,7 +263,9 @@ type
|
|||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
function HasMemory(AnAddress: TDbgPtr; ASize: Cardinal): Boolean;
|
function HasMemory(AnAddress: TDbgPtr; ASize: Cardinal): Boolean;
|
||||||
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
|
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override; overload;
|
||||||
|
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer;
|
||||||
|
ABytesRead: Cardinal): Boolean; override; overload;
|
||||||
|
|
||||||
function AddCache(AnAddress: TDbgPtr; ASize: Cardinal): TFpDbgMemCacheBase;
|
function AddCache(AnAddress: TDbgPtr; ASize: Cardinal): TFpDbgMemCacheBase;
|
||||||
override;
|
override;
|
||||||
@ -280,6 +287,9 @@ type
|
|||||||
* TODO: allow to pre-read and cache Target mem (e.g. before reading all fields of a record
|
* TODO: allow to pre-read and cache Target mem (e.g. before reading all fields of a record
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
TFpDbgMemManagerFlag = (mmfPartialRead);
|
||||||
|
TFpDbgMemManagerFlags = set of TFpDbgMemManagerFlag;
|
||||||
|
|
||||||
{ TFpDbgMemManager }
|
{ TFpDbgMemManager }
|
||||||
|
|
||||||
TFpDbgMemManager = class
|
TFpDbgMemManager = class
|
||||||
@ -290,6 +300,7 @@ type
|
|||||||
FDefaultContext: TFpDbgAddressContext;
|
FDefaultContext: TFpDbgAddressContext;
|
||||||
FLastError: TFpError;
|
FLastError: TFpError;
|
||||||
FMemReader: TFpDbgMemReaderBase;
|
FMemReader: TFpDbgMemReaderBase;
|
||||||
|
FPartialReadResultLenght: QWord;
|
||||||
FTmpMem: array[0..(TMP_MEM_SIZE div 8)+1] of qword; // MUST have at least ONE extra byte
|
FTmpMem: array[0..(TMP_MEM_SIZE div 8)+1] of qword; // MUST have at least ONE extra byte
|
||||||
FTargetMemConvertor: TFpDbgMemConvertor;
|
FTargetMemConvertor: TFpDbgMemConvertor;
|
||||||
FSelfMemConvertor: TFpDbgMemConvertor; // used when resizing constants (or register values, which are already in self format)
|
FSelfMemConvertor: TFpDbgMemConvertor; // used when resizing constants (or register values, which are already in self format)
|
||||||
@ -298,7 +309,8 @@ type
|
|||||||
protected
|
protected
|
||||||
function ReadMemory(AReadDataType: TFpDbgMemReadDataType;
|
function ReadMemory(AReadDataType: TFpDbgMemReadDataType;
|
||||||
const ASourceLocation: TFpDbgMemLocation; const ASourceSize: TFpDbgValueSize;
|
const ASourceLocation: TFpDbgMemLocation; const ASourceSize: TFpDbgValueSize;
|
||||||
const ADest: Pointer; const ADestSize: QWord; AContext: TFpDbgAddressContext
|
const ADest: Pointer; const ADestSize: QWord; AContext: TFpDbgAddressContext;
|
||||||
|
const AFlags: TFpDbgMemManagerFlags = []
|
||||||
): Boolean;
|
): Boolean;
|
||||||
public
|
public
|
||||||
procedure SetCacheManager(ACacheMgr: TFpDbgMemCacheManagerBase);
|
procedure SetCacheManager(ACacheMgr: TFpDbgMemCacheManagerBase);
|
||||||
@ -310,7 +322,8 @@ type
|
|||||||
procedure ClearLastError;
|
procedure ClearLastError;
|
||||||
|
|
||||||
function ReadMemory(const ASourceLocation: TFpDbgMemLocation; const ASize: TFpDbgValueSize;
|
function ReadMemory(const ASourceLocation: TFpDbgMemLocation; const ASize: TFpDbgValueSize;
|
||||||
const ADest: Pointer; AContext: TFpDbgAddressContext = nil
|
const ADest: Pointer; AContext: TFpDbgAddressContext = nil;
|
||||||
|
const AFlags: TFpDbgMemManagerFlags = []
|
||||||
): Boolean; inline;
|
): Boolean; inline;
|
||||||
function ReadMemoryEx(const ASourceLocation: TFpDbgMemLocation; AnAddressSpace: TDbgPtr; ASize: TFpDbgValueSize; ADest: Pointer; AContext: TFpDbgAddressContext = nil): Boolean;
|
function ReadMemoryEx(const ASourceLocation: TFpDbgMemLocation; AnAddressSpace: TDbgPtr; ASize: TFpDbgValueSize; ADest: Pointer; AContext: TFpDbgAddressContext = nil): Boolean;
|
||||||
(* ReadRegister needs a Context, to get the thread/stackframe
|
(* ReadRegister needs a Context, to get the thread/stackframe
|
||||||
@ -359,6 +372,7 @@ type
|
|||||||
|
|
||||||
property TargetMemConvertor: TFpDbgMemConvertor read FTargetMemConvertor;
|
property TargetMemConvertor: TFpDbgMemConvertor read FTargetMemConvertor;
|
||||||
property SelfMemConvertor: TFpDbgMemConvertor read FSelfMemConvertor;
|
property SelfMemConvertor: TFpDbgMemConvertor read FSelfMemConvertor;
|
||||||
|
property PartialReadResultLenght: QWord read FPartialReadResultLenght;
|
||||||
property LastError: TFpError read FLastError;
|
property LastError: TFpError read FLastError;
|
||||||
property DefaultContext: TFpDbgAddressContext read FDefaultContext write FDefaultContext;
|
property DefaultContext: TFpDbgAddressContext read FDefaultContext write FDefaultContext;
|
||||||
end;
|
end;
|
||||||
@ -762,6 +776,41 @@ begin
|
|||||||
WriteStr(Result, AReadDataType);
|
WriteStr(Result, AReadDataType);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TFpDbgMemReaderBase }
|
||||||
|
|
||||||
|
function TFpDbgMemReaderBase.ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal;
|
||||||
|
ADest: Pointer; out ABytesRead: Cardinal): Boolean;
|
||||||
|
var
|
||||||
|
SizeRemaining, sz: Cardinal;
|
||||||
|
Offs: Integer;
|
||||||
|
begin
|
||||||
|
ABytesRead := ASize;
|
||||||
|
Result := ReadMemory(AnAddress, ASize, ADest);
|
||||||
|
if Result then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
SizeRemaining := ASize;
|
||||||
|
Offs := 0;
|
||||||
|
ABytesRead := 0;
|
||||||
|
|
||||||
|
while SizeRemaining > 0 do begin
|
||||||
|
Result := False;
|
||||||
|
sz := SizeRemaining;
|
||||||
|
while (not Result) and (sz > 1) do begin
|
||||||
|
sz := sz div 2;
|
||||||
|
Result := ReadMemory(AnAddress, sz, Pointer(PByte(ADest) + Offs));
|
||||||
|
end;
|
||||||
|
if not Result then
|
||||||
|
break;
|
||||||
|
|
||||||
|
ABytesRead := ABytesRead + sz;
|
||||||
|
Offs := Offs + sz;
|
||||||
|
SizeRemaining := SizeRemaining - sz;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := ABytesRead > 0;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TFpDbgMemConvertorLittleEndian }
|
{ TFpDbgMemConvertorLittleEndian }
|
||||||
|
|
||||||
function TFpDbgMemConvertorLittleEndian.PrepareTargetRead(
|
function TFpDbgMemConvertorLittleEndian.PrepareTargetRead(
|
||||||
@ -937,6 +986,12 @@ begin
|
|||||||
Result := FMemReader.ReadMemory(AnAddress, ASize, ADest);
|
Result := FMemReader.ReadMemory(AnAddress, ASize, ADest);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFpDbgMemCacheManagerBase.ReadMemory(AnAddress: TDbgPtr;
|
||||||
|
ASize: Cardinal; ADest: Pointer; ABytesRead: Cardinal): Boolean;
|
||||||
|
begin
|
||||||
|
Result := FMemReader.ReadMemory(AnAddress, ASize, ADest, ABytesRead);
|
||||||
|
end;
|
||||||
|
|
||||||
function TFpDbgMemCacheManagerBase.ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr;
|
function TFpDbgMemCacheManagerBase.ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr;
|
||||||
ASize: Cardinal; ADest: Pointer): Boolean;
|
ASize: Cardinal; ADest: Pointer): Boolean;
|
||||||
begin
|
begin
|
||||||
@ -1061,6 +1116,30 @@ begin
|
|||||||
Result := inherited ReadMemory(AnAddress, ASize, ADest);
|
Result := inherited ReadMemory(AnAddress, ASize, ADest);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFpDbgMemCacheManagerSimple.ReadMemory(AnAddress: TDbgPtr;
|
||||||
|
ASize: Cardinal; ADest: Pointer; ABytesRead: Cardinal): Boolean;
|
||||||
|
var
|
||||||
|
Node: TAVLTreeNode;
|
||||||
|
begin
|
||||||
|
Node := FCaches.FindNearestKey(@AnAddress, @CompareKey);
|
||||||
|
if Node = nil then
|
||||||
|
exit(inherited ReadMemory(AnAddress, ASize, ADest, ABytesRead));
|
||||||
|
|
||||||
|
if TFpDbgMemCacheSimple(Node.Data).CacheAddress > AnAddress then
|
||||||
|
Node := Node.Precessor;;
|
||||||
|
if Node = nil then
|
||||||
|
exit(inherited ReadMemory(AnAddress, ASize, ADest, ABytesRead));
|
||||||
|
|
||||||
|
// TODO: Allow to cache partial mem reads
|
||||||
|
if TFpDbgMemCacheSimple(Node.Data).ContainsMemory(AnAddress, ASize) then begin
|
||||||
|
ABytesRead := ASize;
|
||||||
|
Result := TFpDbgMemCacheSimple(Node.Data).ReadMemory(AnAddress, ASize, ADest);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := inherited ReadMemory(AnAddress, ASize, ADest, ABytesRead);
|
||||||
|
end;
|
||||||
|
|
||||||
function TFpDbgMemCacheManagerSimple.AddCache(AnAddress: TDbgPtr;
|
function TFpDbgMemCacheManagerSimple.AddCache(AnAddress: TDbgPtr;
|
||||||
ASize: Cardinal): TFpDbgMemCacheBase;
|
ASize: Cardinal): TFpDbgMemCacheBase;
|
||||||
begin
|
begin
|
||||||
@ -1115,8 +1194,8 @@ end;
|
|||||||
|
|
||||||
function TFpDbgMemManager.ReadMemory(AReadDataType: TFpDbgMemReadDataType;
|
function TFpDbgMemManager.ReadMemory(AReadDataType: TFpDbgMemReadDataType;
|
||||||
const ASourceLocation: TFpDbgMemLocation; const ASourceSize: TFpDbgValueSize;
|
const ASourceLocation: TFpDbgMemLocation; const ASourceSize: TFpDbgValueSize;
|
||||||
const ADest: Pointer; const ADestSize: QWord; AContext: TFpDbgAddressContext
|
const ADest: Pointer; const ADestSize: QWord; AContext: TFpDbgAddressContext;
|
||||||
): Boolean;
|
const AFlags: TFpDbgMemManagerFlags): Boolean;
|
||||||
var
|
var
|
||||||
ConvData: TFpDbgMemConvData;
|
ConvData: TFpDbgMemConvData;
|
||||||
ReadData, ReadData2: Pointer;
|
ReadData, ReadData2: Pointer;
|
||||||
@ -1125,6 +1204,7 @@ var
|
|||||||
SourceReadSize, SourceFullSize: QWord;
|
SourceReadSize, SourceFullSize: QWord;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
|
FPartialReadResultLenght := SizeToFullBytes(ASourceSize);
|
||||||
DebugLn(FPDBG_VERBOSE_MEM, ['$ReadMem: ', dbgs(AReadDataType),' ', dbgs(ASourceLocation), ' ', dbgs(ASourceSize), ' Dest ', ADestSize]);
|
DebugLn(FPDBG_VERBOSE_MEM, ['$ReadMem: ', dbgs(AReadDataType),' ', dbgs(ASourceLocation), ' ', dbgs(ASourceSize), ' Dest ', ADestSize]);
|
||||||
if (ASourceLocation.MType in [mlfInvalid, mlfUninitialized]) or
|
if (ASourceLocation.MType in [mlfInvalid, mlfUninitialized]) or
|
||||||
(ASourceSize <= 0)
|
(ASourceSize <= 0)
|
||||||
@ -1190,7 +1270,10 @@ begin
|
|||||||
if SourceReadSize <= ConvData.DestSize then begin
|
if SourceReadSize <= ConvData.DestSize then begin
|
||||||
// full read to ADest
|
// full read to ADest
|
||||||
ReadData := ADest;
|
ReadData := ADest;
|
||||||
Result := CacheManager.ReadMemory(ConvData.SourceLocation.Address, SourceReadSize, ADest);
|
if mmfPartialRead in AFlags then
|
||||||
|
Result := CacheManager.ReadMemory(ConvData.SourceLocation.Address, SourceReadSize, ADest, FPartialReadResultLenght)
|
||||||
|
else
|
||||||
|
Result := CacheManager.ReadMemory(ConvData.SourceLocation.Address, SourceReadSize, ADest);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if SourceReadSize <= TMP_MEM_SIZE then begin
|
if SourceReadSize <= TMP_MEM_SIZE then begin
|
||||||
@ -1198,6 +1281,7 @@ begin
|
|||||||
// This is the ONLY read that has ReadData <> ADest
|
// This is the ONLY read that has ReadData <> ADest
|
||||||
// *** FinishTargetRead must copy the data ***
|
// *** FinishTargetRead must copy the data ***
|
||||||
ReadData := @FTmpMem[0];
|
ReadData := @FTmpMem[0];
|
||||||
|
// TODO: partial reads for bit shifting?
|
||||||
Result := CacheManager.ReadMemory(ConvData.SourceLocation.Address, SourceReadSize, ReadData);
|
Result := CacheManager.ReadMemory(ConvData.SourceLocation.Address, SourceReadSize, ReadData);
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
@ -1207,6 +1291,7 @@ begin
|
|||||||
assert(BitOffset <> 0, 'TFpDbgMemManager.ReadMemory: BitOffset <> 0');
|
assert(BitOffset <> 0, 'TFpDbgMemManager.ReadMemory: BitOffset <> 0');
|
||||||
ReadData := ADest;
|
ReadData := ADest;
|
||||||
ReadData2 := @FTmpMem[0];
|
ReadData2 := @FTmpMem[0];
|
||||||
|
// TODO: partial reads for bit shifting?
|
||||||
Result := CacheManager.ReadMemory(ConvData.SourceLocation.Address, ConvData.DestSize, ADest);
|
Result := CacheManager.ReadMemory(ConvData.SourceLocation.Address, ConvData.DestSize, ADest);
|
||||||
if Result then
|
if Result then
|
||||||
Result := CacheManager.ReadMemory(ConvData.SourceLocation.Address + ConvData.DestSize, SourceReadSize - ConvData.DestSize, ReadData2);
|
Result := CacheManager.ReadMemory(ConvData.SourceLocation.Address + ConvData.DestSize, SourceReadSize - ConvData.DestSize, ReadData2);
|
||||||
@ -1354,9 +1439,9 @@ end;
|
|||||||
|
|
||||||
function TFpDbgMemManager.ReadMemory(const ASourceLocation: TFpDbgMemLocation;
|
function TFpDbgMemManager.ReadMemory(const ASourceLocation: TFpDbgMemLocation;
|
||||||
const ASize: TFpDbgValueSize; const ADest: Pointer;
|
const ASize: TFpDbgValueSize; const ADest: Pointer;
|
||||||
AContext: TFpDbgAddressContext): Boolean;
|
AContext: TFpDbgAddressContext; const AFlags: TFpDbgMemManagerFlags): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := ReadMemory(rdtRawRead, ASourceLocation, ASize, ADest, ASize.Size, AContext);
|
Result := ReadMemory(rdtRawRead, ASourceLocation, ASize, ADest, ASize.Size, AContext, AFlags);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpDbgMemManager.ReadMemoryEx(
|
function TFpDbgMemManager.ReadMemoryEx(
|
||||||
|
@ -214,7 +214,7 @@ type
|
|||||||
FExceptionStepper: TFpDebugExceptionStepping;
|
FExceptionStepper: TFpDebugExceptionStepping;
|
||||||
FConsoleOutputThread: TThread;
|
FConsoleOutputThread: TThread;
|
||||||
// Helper vars to run in debug-thread
|
// Helper vars to run in debug-thread
|
||||||
FCacheLine: cardinal;
|
FCacheLine, FCacheBytesRead: cardinal;
|
||||||
FCacheFileName: string;
|
FCacheFileName: string;
|
||||||
FCacheLib: TDbgLibrary;
|
FCacheLib: TDbgLibrary;
|
||||||
FCacheBreakpoint: TFpDbgBreakpoint;
|
FCacheBreakpoint: TFpDbgBreakpoint;
|
||||||
@ -295,6 +295,7 @@ type
|
|||||||
procedure DoAddBreakLocation;
|
procedure DoAddBreakLocation;
|
||||||
procedure DoAddBWatch;
|
procedure DoAddBWatch;
|
||||||
procedure DoReadData;
|
procedure DoReadData;
|
||||||
|
procedure DoReadPartialData;
|
||||||
procedure DoPrepareCallStackEntryList;
|
procedure DoPrepareCallStackEntryList;
|
||||||
procedure DoFreeBreakpoint;
|
procedure DoFreeBreakpoint;
|
||||||
procedure DoFindContext;
|
procedure DoFindContext;
|
||||||
@ -308,6 +309,7 @@ type
|
|||||||
AScope: TDBGWatchPointScope): TFpDbgBreakpoint;
|
AScope: TDBGWatchPointScope): TFpDbgBreakpoint;
|
||||||
procedure FreeBreakpoint(const ABreakpoint: TFpDbgBreakpoint);
|
procedure FreeBreakpoint(const ABreakpoint: TFpDbgBreakpoint);
|
||||||
function ReadData(const AAdress: TDbgPtr; const ASize: Cardinal; out AData): Boolean; inline;
|
function ReadData(const AAdress: TDbgPtr; const ASize: Cardinal; out AData): Boolean; inline;
|
||||||
|
function ReadData(const AAdress: TDbgPtr; const ASize: Cardinal; out AData; out ABytesRead: Cardinal): Boolean; inline;
|
||||||
function ReadAddress(const AAdress: TDbgPtr; out AData: TDBGPtr): Boolean;
|
function ReadAddress(const AAdress: TDbgPtr; out AData: TDBGPtr): Boolean;
|
||||||
procedure PrepareCallStackEntryList(AFrameRequired: Integer = -1; AThread: TDbgThread = nil); inline;
|
procedure PrepareCallStackEntryList(AFrameRequired: Integer = -1; AThread: TDbgThread = nil); inline;
|
||||||
function FindContext(AThreadId, AStackFrame: Integer): TFpDbgInfoContext; inline;
|
function FindContext(AThreadId, AStackFrame: Integer): TFpDbgInfoContext; inline;
|
||||||
@ -495,7 +497,9 @@ type
|
|||||||
function GetDbgThread(AContext: TFpDbgAddressContext): TDbgThread; override;
|
function GetDbgThread(AContext: TFpDbgAddressContext): TDbgThread; override;
|
||||||
public
|
public
|
||||||
constructor create(AFpDebugDebuger: TFpDebugDebugger);
|
constructor create(AFpDebugDebuger: TFpDebugDebugger);
|
||||||
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
|
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override; overload;
|
||||||
|
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer;
|
||||||
|
out ABytesRead: Cardinal): Boolean; override; overload;
|
||||||
function ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
|
function ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
|
||||||
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr;
|
function ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr;
|
||||||
AContext: TFpDbgAddressContext): Boolean; override;
|
AContext: TFpDbgAddressContext): Boolean; override;
|
||||||
@ -841,6 +845,12 @@ begin
|
|||||||
result := FFpDebugDebugger.ReadData(AnAddress, ASize, ADest^);
|
result := FFpDebugDebugger.ReadData(AnAddress, ASize, ADest^);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFpDbgMemReader.ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal;
|
||||||
|
ADest: Pointer; out ABytesRead: Cardinal): Boolean;
|
||||||
|
begin
|
||||||
|
result := FFpDebugDebugger.ReadData(AnAddress, ASize, ADest^, ABytesRead);
|
||||||
|
end;
|
||||||
|
|
||||||
function TFpDbgMemReader.ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
|
function TFpDbgMemReader.ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
|
||||||
begin
|
begin
|
||||||
Assert(AnAddressSpace>0,'TFpDbgMemReader.ReadMemoryEx ignores AddressSpace');
|
Assert(AnAddressSpace>0,'TFpDbgMemReader.ReadMemoryEx ignores AddressSpace');
|
||||||
@ -3206,6 +3216,11 @@ begin
|
|||||||
FCacheBoolean:=FDbgController.CurrentProcess.ReadData(FCacheLocation, FCacheLine, FCachePointer^);
|
FCacheBoolean:=FDbgController.CurrentProcess.ReadData(FCacheLocation, FCacheLine, FCachePointer^);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TFpDebugDebugger.DoReadPartialData;
|
||||||
|
begin
|
||||||
|
FCacheBoolean:=FDbgController.CurrentProcess.ReadData(FCacheLocation, FCacheLine, FCachePointer^, FCacheBytesRead);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TFpDebugDebugger.DoPrepareCallStackEntryList;
|
procedure TFpDebugDebugger.DoPrepareCallStackEntryList;
|
||||||
begin
|
begin
|
||||||
FCallStackEntryListThread.PrepareCallStackEntryList(FCallStackEntryListFrameRequired);
|
FCallStackEntryListThread.PrepareCallStackEntryList(FCallStackEntryListFrameRequired);
|
||||||
@ -3332,6 +3347,24 @@ begin
|
|||||||
result:=FDbgController.CurrentProcess.ReadData(AAdress, ASize, AData);
|
result:=FDbgController.CurrentProcess.ReadData(AAdress, ASize, AData);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFpDebugDebugger.ReadData(const AAdress: TDbgPtr;
|
||||||
|
const ASize: Cardinal; out AData; out ABytesRead: Cardinal): Boolean;
|
||||||
|
begin
|
||||||
|
if FDbgController.CurrentProcess.RequiresExecutionInDebuggerThread then
|
||||||
|
begin
|
||||||
|
FCacheLocation := AAdress;
|
||||||
|
FCacheLine:=ASize;
|
||||||
|
FCachePointer := @AData;
|
||||||
|
FCacheBoolean := False;
|
||||||
|
FCacheBytesRead := 0;
|
||||||
|
ExecuteInDebugThread(@DoReadPartialData);
|
||||||
|
result := FCacheBoolean;
|
||||||
|
ABytesRead := FCacheBytesRead;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result:=FDbgController.CurrentProcess.ReadData(AAdress, ASize, AData, ABytesRead);
|
||||||
|
end;
|
||||||
|
|
||||||
function TFpDebugDebugger.ReadAddress(const AAdress: TDbgPtr; out AData: TDBGPtr): Boolean;
|
function TFpDebugDebugger.ReadAddress(const AAdress: TDbgPtr; out AData: TDBGPtr): Boolean;
|
||||||
var
|
var
|
||||||
dw: DWord;
|
dw: DWord;
|
||||||
|
Loading…
Reference in New Issue
Block a user