FpDebugger (pure): Let the memory-manager read memory from within the debugging-thread on Linux.

More fixes for getting the instruction-register on x86_64
Fixxed setting the line-info on Darwin and Linux

git-svn-id: trunk@45817 -
This commit is contained in:
joost 2014-07-08 21:15:04 +00:00
parent a3a3e0ba9a
commit 600fc1036c
7 changed files with 119 additions and 56 deletions

View File

@ -38,6 +38,8 @@ interface
uses
Classes, SysUtils, FileUtil, FpDbgInfo, FpDbgClasses, FpDbgDisasX86, DbgIntfBaseTypes,
FpDbgDwarf,
FpdMemoryTools,
CustApp;
type
@ -47,17 +49,21 @@ type
TFPDLoop = class(TCustomApplication)
private
FLast: string;
FMemReader: TDbgMemReader;
FMemManager: TFpDbgMemManager;
procedure ShowDisas;
procedure ShowCode;
procedure GControllerExceptionEvent(var continue: boolean; const ExceptionClass, ExceptionMessage: string);
procedure GControllerCreateProcessEvent(var continue: boolean);
procedure GControllerHitBreakpointEvent(var continue: boolean; const Breakpoint: TDbgBreakpoint);
procedure GControllerProcessExitEvent(ExitCode: DWord);
procedure GControllerDebugInfoLoaded(Sender: TObject);
procedure OnLog(const AString: string; const ALogLevel: TFPDLogLevel);
protected
Procedure DoRun; override;
public
procedure Initialize; override;
destructor Destroy; override;
end;
implementation
@ -67,11 +73,41 @@ uses
FpDbgUtil,
FPDGlobal;
type
{ TPDDbgMemReader }
TPDDbgMemReader = class(TDbgMemReader)
protected
function GetDbgProcess: TDbgProcess; override;
public
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
function ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
end;
resourcestring
sBreakpointReached = 'Breakpoint reached at %s.';
sProcessPaused = 'Process paused.';
sProcessExited = 'Process ended with exit-code %d.';
{ TPDDbgMemReader }
function TPDDbgMemReader.GetDbgProcess: TDbgProcess;
begin
result := GController.CurrentProcess;
end;
function TPDDbgMemReader.ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
begin
result := GetDbgProcess.ReadData(AnAddress, ASize, ADest^);
end;
function TPDDbgMemReader.ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
begin
result := GetDbgProcess.ReadData(AnAddress, ASize, ADest^);
end;
{ TFPDLoop }
procedure TFPDLoop.GControllerExceptionEvent(var continue: boolean; const ExceptionClass, ExceptionMessage: string);
@ -95,6 +131,11 @@ begin
writeln(format(sProcessExited,[ExitCode]));
end;
procedure TFPDLoop.GControllerDebugInfoLoaded(Sender: TObject);
begin
TFpDwarfInfo(GController.CurrentProcess.DbgInfo).MemManager := FMemManager;
end;
procedure TFPDLoop.ShowDisas;
var
a: TDbgPtr;
@ -239,11 +280,21 @@ end;
procedure TFPDLoop.Initialize;
begin
inherited Initialize;
FMemReader := TPDDbgMemReader.Create;
FMemManager := TFpDbgMemManager.Create(FMemReader, TFpDbgMemConvertorLittleEndian.Create);
GController.OnLog:=@OnLog;
GController.OnHitBreakpointEvent:=@GControllerHitBreakpointEvent;
GController.OnCreateProcessEvent:=@GControllerCreateProcessEvent;
GController.OnExceptionEvent:=@GControllerExceptionEvent;
GController.OnProcessExitEvent:=@GControllerProcessExitEvent;
GController.OnDebugInfoLoaded:=@GControllerDebugInfoLoaded;
end;
destructor TFPDLoop.Destroy;
begin
FMemManager.Free;
FMemReader.Free;
inherited Destroy;
end;
initialization

View File

@ -115,12 +115,9 @@ type
{ TDbgMemReader }
TDbgMemReader = class(TFpDbgMemReaderBase)
private
FDbgProcess: TDbgProcess;
protected
function GetDbgProcess: TDbgProcess; virtual; abstract;
public
constructor Create(ADbgProcess: TDbgProcess);
function ReadMemory(AnAddress: 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 RegisterSize(ARegNum: Cardinal): Integer; override;
end;
@ -190,14 +187,12 @@ type
private
FMode: TFPDMode;
FName: String;
FOnDebugInfoLoaded: TNotifyEvent;
FProcess: TDbgProcess;
FDbgInfo: TDbgInfo;
FSymbolTableInfo: TFpSymbolInfo;
FLoader: TDbgImageLoader;
protected
procedure LoadInfo; virtual;
function InitializeLoader: TDbgImageLoader; virtual;
procedure SetName(const AValue: String);
public
@ -208,11 +203,11 @@ type
function AddrOffset: Int64; virtual; // gives the offset between the loaded addresses and the compiled addresses
function FindSymbol(AAdress: TDbgPtr): TFpDbgSymbol;
function RemoveBreak(const AFileName: String; ALine: Cardinal): Boolean;
procedure LoadInfo; virtual;
property Process: TDbgProcess read FProcess;
property DbgInfo: TDbgInfo read FDbgInfo;
property SymbolTableInfo: TFpSymbolInfo read FSymbolTableInfo;
property OnDebugInfoLoaded: TNotifyEvent read FOnDebugInfoLoaded write FOnDebugInfoLoaded;
property Mode: TFPDMode read FMode;
end;
@ -239,8 +234,6 @@ type
FOnLog: TOnLog;
FProcessID: Integer;
FThreadID: Integer;
FMemReader: TDbgMemReader;
FMemManager: TFpDbgMemManager;
procedure ThreadDestroyed(const AThread: TDbgThread);
protected
@ -257,7 +250,6 @@ type
FRunToBreakpoint: TDbgBreakpoint;
FMainThread: TDbgThread;
procedure LoadInfo; override;
function GetHandle: THandle; virtual;
procedure SetExitCode(AValue: DWord);
function GetLastEventProcessIdentifier: THandle; virtual;
@ -295,6 +287,7 @@ type
function ResolveDebugEvent(AThread: TDbgThread): TFPDEvent; virtual;
function AddThread(AThreadIdentifier: THandle): TDbgThread;
procedure LoadInfo; override;
function WriteData(const AAdress: TDbgPtr; const ASize: Cardinal; const AData): Boolean; virtual;
@ -439,22 +432,6 @@ end;
{ TDbgMemReader }
constructor TDbgMemReader.Create(ADbgProcess: TDbgProcess);
begin
FDbgProcess := ADbgProcess;
end;
function TDbgMemReader.ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
begin
result := FDbgProcess.ReadData(AnAddress, ASize, ADest^);
end;
function TDbgMemReader.ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr;
ASize: Cardinal; ADest: Pointer): Boolean;
begin
result := FDbgProcess.ReadData(AnAddress, ASize, ADest^);
end;
function TDbgMemReader.ReadRegister(ARegNum: Cardinal; out AValue: TDbgPtr; AContext: TFpDbgAddressContext): Boolean;
var
ARegister: TDbgRegisterValue;
@ -468,12 +445,12 @@ begin
StackFrame := 0;
if StackFrame = 0 then
begin
ARegister:=FDbgProcess.MainThread.RegisterValueList.FindRegisterByDwarfIndex(ARegNum);
ARegister:=GetDbgProcess.MainThread.RegisterValueList.FindRegisterByDwarfIndex(ARegNum);
end
else
begin
FDbgProcess.MainThread.PrepareCallStackEntryList(StackFrame);
AFrame := FDbgProcess.MainThread.CallStackEntryList[StackFrame];
GetDbgProcess.MainThread.PrepareCallStackEntryList(StackFrame);
AFrame := GetDbgProcess.MainThread.CallStackEntryList[StackFrame];
if AFrame <> nil then
ARegister:=AFrame.RegisterValueList.FindRegisterByDwarfIndex(ARegNum)
else
@ -492,7 +469,7 @@ function TDbgMemReader.RegisterSize(ARegNum: Cardinal): Integer;
var
ARegister: TDbgRegisterValue;
begin
ARegister:=FDbgProcess.MainThread.RegisterValueList.FindRegisterByDwarfIndex(ARegNum);
ARegister:=GetDbgProcess.MainThread.RegisterValueList.FindRegisterByDwarfIndex(ARegNum);
if assigned(ARegister) then
result := ARegister.Size
else
@ -629,8 +606,6 @@ begin
FDbgInfo := TFpDwarfInfo.Create(FLoader);
TFpDwarfInfo(FDbgInfo).LoadCompilationUnits;
FSymbolTableInfo := TFpSymbolInfo.Create(FLoader);
if Assigned(FOnDebugInfoLoaded) then
FOnDebugInfoLoaded(Self);
end;
function TDbgInstance.RemoveBreak(const AFileName: String; ALine: Cardinal): Boolean;
@ -689,9 +664,6 @@ begin
FBreakMap := TMap.Create(MAP_ID_SIZE, SizeOf(TDbgBreakpoint));
FCurrentBreakpoint := nil;
FMemReader := TDbgMemReader.Create(Self);
FMemManager := TFpDbgMemManager.Create(FMemReader, TFpDbgMemConvertorLittleEndian.Create);
FSymInstances := TList.Create;
SetName(AName);
@ -722,8 +694,6 @@ begin
FreeAndNil(FThreadMap);
FreeAndNil(FLibMap);
FreeAndNil(FSymInstances);
FreeAndNil(FMemManager);
FreeAndNil(FMemReader);
inherited;
end;
@ -977,7 +947,9 @@ end;
procedure TDbgProcess.LoadInfo;
begin
inherited LoadInfo;
TFpDwarfInfo(FDbgInfo).MemManager := FMemManager;
if DbgInfo.HasInfo then
FSymInstances.Add(Self);
end;
function TDbgProcess.GetLastEventProcessIdentifier: THandle;

View File

@ -408,7 +408,6 @@ begin
if assigned(FCurrentProcess) then
begin
FProcessMap.Add(FCurrentProcess.ProcessID, FCurrentProcess);
FCurrentProcess.OnDebugInfoLoaded := @DoOnDebugInfoLoaded;
Log('Got PID: %d, TID: %d', [FCurrentProcess.ProcessID, FCurrentProcess.ThreadID]);
result := true;
end;
@ -538,6 +537,9 @@ begin
case FPDEvent of
deCreateProcess:
begin
FCurrentProcess.LoadInfo;
DoOnDebugInfoLoaded(self);
continue:=true;
if assigned(OnCreateProcessEvent) then
OnCreateProcessEvent(continue);

View File

@ -572,11 +572,6 @@ var
begin
inherited Create(AName, AProcessID, AThreadID, AOnLog);
LoadInfo;
if DbgInfo.HasInfo
then FSymInstances.Add(Self);
GetDebugAccessRights;
aKernResult:=task_for_pid(mach_task_self, AProcessID, FTaskPort);
if aKernResult <> KERN_SUCCESS then

View File

@ -402,11 +402,6 @@ constructor TDbgLinuxProcess.Create(const AName: string; const AProcessID,
AThreadID: Integer; AOnLog: TOnLog);
begin
inherited Create(AName, AProcessID, AThreadID, AOnLog);
LoadInfo;
if DbgInfo.HasInfo
then FSymInstances.Add(Self);
end;
destructor TDbgLinuxProcess.Destroy;

View File

@ -876,11 +876,6 @@ begin
s := GetProcFilename(Self, AInfo.lpImageName, AInfo.fUnicode, 0);
if s <> ''
then SetName(s);
LoadInfo;
if DbgInfo.HasInfo
then FSymInstances.Add(Self);
end;
function TDbgWinProcess.GetInstructionPointerRegisterValue: TDbgPtr;

View File

@ -18,6 +18,7 @@ uses
FpPascalBuilder,
DbgIntfBaseTypes,
DbgIntfDebuggerBase,
FpdMemoryTools,
FpPascalParser,
FPDbgController, FpDbgDwarfDataClasses;
@ -65,6 +66,8 @@ type
FRaiseExceptionBreakpoint: FpDbgClasses.TDBGBreakPoint;
FDbgLogMessageList: array of TFpDbgLogMessage;
FLogCritSection: TRTLCriticalSection;
FMemReader: TDbgMemReader;
FMemManager: TFpDbgMemManager;
{$ifdef linux}
FCacheLine: cardinal;
FCacheFileName: string;
@ -240,11 +243,48 @@ uses
FpDbgUtil,
FpDbgDisasX86;
type
{ TFpDbgMemReader }
TFpDbgMemReader = class(TDbgMemReader)
private
FFpDebugDebugger: TFpDebugDebugger;
protected
function GetDbgProcess: TDbgProcess; override;
public
constructor create(AFpDebugDebuger: TFpDebugDebugger);
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
function ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
end;
procedure Register;
begin
RegisterDebugger(TFpDebugDebugger);
end;
{ TFpDbgMemReader }
function TFpDbgMemReader.GetDbgProcess: TDbgProcess;
begin
result := FFpDebugDebugger.FDbgController.CurrentProcess;
end;
constructor TFpDbgMemReader.create(AFpDebugDebuger: TFpDebugDebugger);
begin
FFpDebugDebugger := AFpDebugDebuger;
end;
function TFpDbgMemReader.ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
begin
result := FFpDebugDebugger.ReadData(AnAddress, ASize, ADest^);
end;
function TFpDbgMemReader.ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
begin
result := FFpDebugDebugger.ReadData(AnAddress, ASize, ADest^);
end;
{ TFPCallStackSupplier }
procedure TFPCallStackSupplier.DoStateLeavePause;
@ -385,7 +425,11 @@ begin
end
else
RegList := AController.CurrentProcess.MainThread.RegisterValueList;
Reg := RegList.FindRegisterByDwarfIndex(8);
{$ifdef i386}
Reg := RegList.FindRegisterByDwarfIndex(8);
{$else}
Reg := RegList.FindRegisterByDwarfIndex(16);
{$endif}
if Reg <> nil then
AContext := AController.CurrentProcess.DbgInfo.FindContext(CurThreadId, CurStackFrame, Reg.NumValue)
else
@ -913,7 +957,11 @@ begin
end
else
RegList := AController.CurrentProcess.MainThread.RegisterValueList;
{$ifdef i386}
Reg := RegList.FindRegisterByDwarfIndex(8);
{$else}
Reg := RegList.FindRegisterByDwarfIndex(16);
{$endif}
if Reg <> nil then
AContext := ADbgInfo.FindContext(ThreadId, StackFrame, Reg.NumValue)
else
@ -1007,6 +1055,7 @@ end;
procedure TFpDebugDebugger.FDbgControllerDebugInfoLoaded(Sender: TObject);
begin
TFpDwarfInfo(FDbgController.CurrentProcess.DbgInfo).MemManager := FMemManager;
if LineInfo <> nil then begin
TFpLineInfo(LineInfo).DebugInfoChanged;
end;
@ -1444,6 +1493,8 @@ begin
FWatchEvalList := TList.Create;
FPrettyPrinter := TFpPascalPrettyPrinter.Create(sizeof(pointer));
InitCriticalSection(FLogCritSection);
FMemReader := TFpDbgMemReader.Create(self);
FMemManager := TFpDbgMemManager.Create(FMemReader, TFpDbgMemConvertorLittleEndian.Create);
FDbgController := TDbgController.Create;
FDbgController.OnLog:=@OnLog;
FDbgController.OnCreateProcessEvent:=@FDbgControllerCreateProcessEvent;
@ -1460,6 +1511,8 @@ begin
FDbgController.Free;
FPrettyPrinter.Free;
FWatchEvalList.Free;
FMemManager.Free;
FMemReader.Free;
DoneCriticalsection(FLogCritSection);
inherited Destroy;
end;