mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-24 13:19:18 +02:00
fpdebug: Improved handling of threads, removed several assumptions that the main-thread was being debugged
git-svn-id: trunk@58128 -
This commit is contained in:
parent
9662fcc1b5
commit
1f5eb8d171
@ -123,6 +123,7 @@ type
|
||||
TDbgMemReader = class(TFpDbgMemReaderBase)
|
||||
protected
|
||||
function GetDbgProcess: TDbgProcess; virtual; abstract;
|
||||
function GetDbgThread(AContext: TFpDbgAddressContext): TDbgThread; virtual;
|
||||
public
|
||||
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
|
||||
function ReadMemoryEx(AnAddress, AnAddressSpace: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
|
||||
@ -158,6 +159,11 @@ type
|
||||
function AddWatchpoint(AnAddr: TDBGPtr): integer; virtual;
|
||||
function RemoveWatchpoint(AnId: integer): boolean; virtual;
|
||||
function DetectHardwareWatchpoint: integer; virtual;
|
||||
|
||||
function GetInstructionPointerRegisterValue: TDbgPtr; virtual; abstract;
|
||||
function GetStackBasePointerRegisterValue: TDbgPtr; virtual; abstract;
|
||||
function GetStackPointerRegisterValue: TDbgPtr; virtual; abstract;
|
||||
|
||||
procedure PrepareCallStackEntryList(AFrameRequired: Integer = -1); virtual;
|
||||
procedure ClearCallStack;
|
||||
destructor Destroy; override;
|
||||
@ -334,10 +340,6 @@ type
|
||||
|
||||
function WriteData(const AAdress: TDbgPtr; const ASize: Cardinal; const AData): Boolean; virtual;
|
||||
|
||||
function GetInstructionPointerRegisterValue: TDbgPtr; virtual; abstract;
|
||||
function GetStackBasePointerRegisterValue: TDbgPtr; virtual; abstract;
|
||||
function GetStackPointerRegisterValue: TDbgPtr; virtual; abstract;
|
||||
|
||||
procedure TerminateProcess; virtual; abstract;
|
||||
|
||||
property Handle: THandle read GetHandle;
|
||||
@ -453,7 +455,7 @@ begin
|
||||
if assigned(ProcSymbol) then begin
|
||||
ProcVal := ProcSymbol.Value;
|
||||
if (ProcVal <> nil) then begin
|
||||
InstrPointerValue := FThread.Process.GetInstructionPointerRegisterValue;
|
||||
InstrPointerValue := FThread.GetInstructionPointerRegisterValue;
|
||||
if InstrPointerValue <> 0 then begin
|
||||
AContext := FThread.Process.DbgInfo.FindContext(FThread.ID, Index, InstrPointerValue);
|
||||
if AContext <> nil then begin
|
||||
@ -519,6 +521,15 @@ end;
|
||||
|
||||
{ TDbgMemReader }
|
||||
|
||||
function TDbgMemReader.GetDbgThread(AContext: TFpDbgAddressContext): TDbgThread;
|
||||
var
|
||||
Process: TDbgProcess;
|
||||
begin
|
||||
Process := GetDbgProcess;
|
||||
if not Process.GetThread(AContext.ThreadId, Result) then
|
||||
Result := Process.MainThread;
|
||||
end;
|
||||
|
||||
function TDbgMemReader.ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean;
|
||||
begin
|
||||
result := GetDbgProcess.ReadData(AnAddress, ASize, ADest^);
|
||||
@ -543,12 +554,12 @@ begin
|
||||
StackFrame := 0;
|
||||
if StackFrame = 0 then
|
||||
begin
|
||||
ARegister:=GetDbgProcess.MainThread.RegisterValueList.FindRegisterByDwarfIndex(ARegNum);
|
||||
ARegister:=GetDbgThread(AContext).RegisterValueList.FindRegisterByDwarfIndex(ARegNum);
|
||||
end
|
||||
else
|
||||
begin
|
||||
GetDbgProcess.MainThread.PrepareCallStackEntryList(StackFrame);
|
||||
AFrame := GetDbgProcess.MainThread.CallStackEntryList[StackFrame];
|
||||
GetDbgThread(AContext).PrepareCallStackEntryList(StackFrame);
|
||||
AFrame := GetDbgThread(AContext).CallStackEntryList[StackFrame];
|
||||
if AFrame <> nil then
|
||||
ARegister:=AFrame.RegisterValueList.FindRegisterByDwarfIndex(ARegNum)
|
||||
else
|
||||
@ -750,7 +761,7 @@ var
|
||||
begin
|
||||
Result := OSDbgClasses.DbgBreakpointClass.Create(Self, ALocation);
|
||||
// TODO: empty breakpoint (all address failed to set) = nil
|
||||
ip := GetInstructionPointerRegisterValue;
|
||||
ip := FMainThread.GetInstructionPointerRegisterValue;
|
||||
if not assigned(FCurrentBreakpoint) then
|
||||
for a in ALocation do
|
||||
if ip=a then begin
|
||||
@ -938,24 +949,24 @@ begin
|
||||
end;
|
||||
|
||||
// Determine the address where the execution has stopped
|
||||
CurrentAddr:=GetInstructionPointerRegisterValue;
|
||||
CurrentAddr:=AThread.GetInstructionPointerRegisterValue;
|
||||
FCurrentWatchpoint:=AThread.DetectHardwareWatchpoint;
|
||||
if not (FMainThread.NextIsSingleStep or assigned(FCurrentBreakpoint) or (FCurrentWatchpoint>-1)) then
|
||||
if not (AThread.NextIsSingleStep or assigned(FCurrentBreakpoint) or (FCurrentWatchpoint>-1)) then
|
||||
begin
|
||||
// The debugger did not stop due to single-stepping or a watchpoint,
|
||||
// so a breakpoint has been hit. But breakpoints stop *after* they
|
||||
// have been hit. So decrement the CurrentAddr.
|
||||
FMainThread.FNeedIPDecrement:=true;
|
||||
AThread.FNeedIPDecrement:=true;
|
||||
dec(CurrentAddr);
|
||||
end
|
||||
else
|
||||
FMainThread.FNeedIPDecrement:=false;
|
||||
AThread.FNeedIPDecrement:=false;
|
||||
FCurrentBreakpoint:=nil;
|
||||
AThread.NextIsSingleStep:=false;
|
||||
|
||||
// Whatever reason there was to change the result to deInternalContinue,
|
||||
// if a breakpoint has been hit, always trigger it...
|
||||
if DoBreak(CurrentAddr, FMainThread.ID) then
|
||||
if DoBreak(CurrentAddr, AThread.ID) then
|
||||
result := deBreakpoint;
|
||||
end
|
||||
end;
|
||||
@ -1128,7 +1139,7 @@ var
|
||||
AnAddr: TDBGPtr;
|
||||
Sym: TFpDbgSymbol;
|
||||
begin
|
||||
AnAddr := FProcess.GetInstructionPointerRegisterValue;
|
||||
AnAddr := GetInstructionPointerRegisterValue;
|
||||
sym := FProcess.FindSymbol(AnAddr);
|
||||
if assigned(sym) then
|
||||
begin
|
||||
@ -1152,7 +1163,7 @@ var
|
||||
CU: TDwarfCompilationUnit;
|
||||
a: TDBGPtrArray;
|
||||
begin
|
||||
AnAddr := FProcess.GetInstructionPointerRegisterValue;
|
||||
AnAddr := GetInstructionPointerRegisterValue;
|
||||
sym := FProcess.FindSymbol(AnAddr);
|
||||
if (sym is TDbgDwarfSymbolBase) then
|
||||
begin
|
||||
@ -1174,8 +1185,8 @@ var
|
||||
AnAddr: TDBGPtr;
|
||||
Sym: TFpDbgSymbol;
|
||||
begin
|
||||
FStoreStepStackFrame := FProcess.GetStackBasePointerRegisterValue;
|
||||
AnAddr := FProcess.GetInstructionPointerRegisterValue;
|
||||
FStoreStepStackFrame := GetStackBasePointerRegisterValue;
|
||||
AnAddr := GetInstructionPointerRegisterValue;
|
||||
sym := FProcess.FindSymbol(AnAddr);
|
||||
if assigned(sym) then
|
||||
begin
|
||||
@ -1240,8 +1251,8 @@ begin
|
||||
// TODO: remove, using AFrameRequired
|
||||
if FCallStackEntryList.Count > 0 then exit; // already done
|
||||
|
||||
Address := Process.GetInstructionPointerRegisterValue;
|
||||
Frame := Process.GetStackBasePointerRegisterValue;
|
||||
Address := GetInstructionPointerRegisterValue;
|
||||
Frame := GetStackBasePointerRegisterValue;
|
||||
Size := sizeof(pointer); // TODO: Context.AddressSize
|
||||
|
||||
FCallStackEntryList.FreeObjects:=true;
|
||||
|
@ -244,13 +244,13 @@ begin
|
||||
if not FInfoStored then
|
||||
begin
|
||||
FInfoStored:=true;
|
||||
FStoredStackFrame:=AProcess.GetStackBasePointerRegisterValue;
|
||||
FStoredStackFrame:=AThread.GetStackBasePointerRegisterValue;
|
||||
AThread.StoreStepInfo;
|
||||
end;
|
||||
|
||||
if not FInto then
|
||||
begin
|
||||
if AProcess.ReadData(aProcess.GetInstructionPointerRegisterValue,sizeof(CodeBin),CodeBin) then
|
||||
if AProcess.ReadData(AThread.GetInstructionPointerRegisterValue,sizeof(CodeBin),CodeBin) then
|
||||
begin
|
||||
p := @CodeBin;
|
||||
Disassemble(p, AProcess.Mode=dm64, ADump, AStatement);
|
||||
@ -259,7 +259,7 @@ begin
|
||||
FInto := true;
|
||||
FInstCount := 0;
|
||||
|
||||
ALocation := AProcess.GetInstructionPointerRegisterValue+(PtrUInt(p)-PtrUInt(@codebin));
|
||||
ALocation := AThread.GetInstructionPointerRegisterValue+(PtrUInt(p)-PtrUInt(@codebin));
|
||||
if not AProcess.HasBreak(ALocation) then
|
||||
FHiddenBreakpoint := AProcess.AddBreak(ALocation);
|
||||
|
||||
@ -301,8 +301,8 @@ begin
|
||||
if (FHiddenWatchpointOutStackbase<>-1) and FController.FCurrentThread.RemoveWatchpoint(FHiddenWatchpointOutStackbase) then
|
||||
FHiddenWatchpointOutStackbase:=-1;
|
||||
|
||||
AStackPointerValue:=FController.CurrentProcess.GetStackPointerRegisterValue;
|
||||
AStackBasePointerValue:=FController.CurrentProcess.GetStackBasePointerRegisterValue;
|
||||
AStackPointerValue:=FController.CurrentThread.GetStackPointerRegisterValue;
|
||||
AStackBasePointerValue:=FController.CurrentThread.GetStackBasePointerRegisterValue;
|
||||
|
||||
Handled := false;
|
||||
Finished := not (AnEvent in [deInternalContinue, deLoadLibrary]);
|
||||
@ -365,7 +365,7 @@ begin
|
||||
begin
|
||||
FInfoStored:=true;
|
||||
AThread.StoreStepInfo;
|
||||
FStoredStackFrame:=AProcess.GetStackBasePointerRegisterValue;
|
||||
FStoredStackFrame:=AThread.GetStackBasePointerRegisterValue;
|
||||
end;
|
||||
|
||||
inherited DoContinue(AProcess, AThread);
|
||||
@ -378,7 +378,7 @@ begin
|
||||
begin
|
||||
if (FController.FCurrentThread.CompareStepInfo<>dcsiNewLine) or
|
||||
(not FController.FCurrentThread.IsAtStartOfLine and
|
||||
(FController.NextOnlyStopOnStartLine or (FStoredStackFrame < FController.CurrentProcess.GetStackBasePointerRegisterValue))) then
|
||||
(FController.NextOnlyStopOnStartLine or (FStoredStackFrame < FController.CurrentThread.GetStackBasePointerRegisterValue))) then
|
||||
begin
|
||||
AnEvent:=deInternalContinue;
|
||||
FHiddenBreakpoint:=nil;
|
||||
@ -407,7 +407,7 @@ begin
|
||||
else
|
||||
begin
|
||||
CallInstr:=false;
|
||||
if AProcess.ReadData(aProcess.GetInstructionPointerRegisterValue,sizeof(CodeBin),CodeBin) then
|
||||
if AProcess.ReadData(AThread.GetInstructionPointerRegisterValue,sizeof(CodeBin),CodeBin) then
|
||||
begin
|
||||
p := @CodeBin;
|
||||
Disassemble(p, AProcess.Mode=dm64, ADump, AStatement);
|
||||
@ -417,7 +417,7 @@ begin
|
||||
|
||||
if CallInstr then
|
||||
begin
|
||||
ALocation := AProcess.GetInstructionPointerRegisterValue+(PtrUInt(p)-PtrUInt(@codebin));
|
||||
ALocation := AThread.GetInstructionPointerRegisterValue+(PtrUInt(p)-PtrUInt(@codebin));
|
||||
if not AProcess.HasBreak(ALocation) then
|
||||
FHiddenBreakpoint := AProcess.AddBreak(ALocation);
|
||||
end;
|
||||
|
@ -117,6 +117,10 @@ type
|
||||
function DetectHardwareWatchpoint: integer; override;
|
||||
procedure BeforeContinue; override;
|
||||
procedure LoadRegisterValues; override;
|
||||
|
||||
function GetInstructionPointerRegisterValue: TDbgPtr; override;
|
||||
function GetStackPointerRegisterValue: TDbgPtr; override;
|
||||
function GetStackBasePointerRegisterValue: TDbgPtr; override;
|
||||
end;
|
||||
|
||||
{ TDbgDarwinProcess }
|
||||
@ -151,9 +155,6 @@ type
|
||||
function GetConsoleOutput: string; override;
|
||||
procedure SendConsoleInput(AString: string); override;
|
||||
|
||||
function GetInstructionPointerRegisterValue: TDbgPtr; override;
|
||||
function GetStackPointerRegisterValue: TDbgPtr; override;
|
||||
function GetStackBasePointerRegisterValue: TDbgPtr; override;
|
||||
procedure TerminateProcess; override;
|
||||
|
||||
function Continue(AProcess: TDbgProcess; AThread: TDbgThread; SingleStep: boolean): boolean; override;
|
||||
@ -601,6 +602,30 @@ begin
|
||||
FRegisterValueListValid:=true;
|
||||
end;
|
||||
|
||||
function TDbgDarwinThread.GetInstructionPointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
if Process.Mode=dm32 then
|
||||
result := FThreadState32.__eip
|
||||
else
|
||||
result := FThreadState64.__rip;
|
||||
end;
|
||||
|
||||
function TDbgDarwinThread.GetStackPointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
if Process.Mode=dm32 then
|
||||
result := FThreadState32.__esp
|
||||
else
|
||||
result := FThreadState64.__rsp;
|
||||
end;
|
||||
|
||||
function TDbgDarwinThread.GetStackBasePointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
if Process.Mode=dm32 then
|
||||
result := FThreadState32.__ebp
|
||||
else
|
||||
result := FThreadState64.__rbp;
|
||||
end;
|
||||
|
||||
{ TDbgDarwinProcess }
|
||||
|
||||
function TDbgDarwinProcess.GetDebugAccessRights: boolean;
|
||||
@ -854,30 +879,6 @@ begin
|
||||
Log('Failed to send input to console.', dllDebug);
|
||||
end;
|
||||
|
||||
function TDbgDarwinProcess.GetInstructionPointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
if Mode=dm32 then
|
||||
result := TDbgDarwinThread(FMainThread).FThreadState32.__eip
|
||||
else
|
||||
result := TDbgDarwinThread(FMainThread).FThreadState64.__rip;
|
||||
end;
|
||||
|
||||
function TDbgDarwinProcess.GetStackPointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
if Mode=dm32 then
|
||||
result := TDbgDarwinThread(FMainThread).FThreadState32.__esp
|
||||
else
|
||||
result := TDbgDarwinThread(FMainThread).FThreadState64.__rsp;
|
||||
end;
|
||||
|
||||
function TDbgDarwinProcess.GetStackBasePointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
if Mode=dm32 then
|
||||
result := TDbgDarwinThread(FMainThread).FThreadState32.__ebp
|
||||
else
|
||||
result := TDbgDarwinThread(FMainThread).FThreadState64.__rbp;
|
||||
end;
|
||||
|
||||
procedure TDbgDarwinProcess.TerminateProcess;
|
||||
begin
|
||||
FIsTerminating:=true;
|
||||
|
@ -239,6 +239,10 @@ type
|
||||
function DetectHardwareWatchpoint: integer; override;
|
||||
procedure BeforeContinue; override;
|
||||
procedure LoadRegisterValues; override;
|
||||
|
||||
function GetInstructionPointerRegisterValue: TDbgPtr; override;
|
||||
function GetStackBasePointerRegisterValue: TDbgPtr; override;
|
||||
function GetStackPointerRegisterValue: TDbgPtr; override;
|
||||
end;
|
||||
|
||||
{ TDbgLinuxProcess }
|
||||
@ -271,9 +275,6 @@ type
|
||||
function GetConsoleOutput: string; override;
|
||||
procedure SendConsoleInput(AString: string); override;
|
||||
|
||||
function GetInstructionPointerRegisterValue: TDbgPtr; override;
|
||||
function GetStackPointerRegisterValue: TDbgPtr; override;
|
||||
function GetStackBasePointerRegisterValue: TDbgPtr; override;
|
||||
procedure TerminateProcess; override;
|
||||
function Pause: boolean; override;
|
||||
|
||||
@ -557,6 +558,30 @@ begin
|
||||
FRegisterValueListValid:=true;
|
||||
end;
|
||||
|
||||
function TDbgLinuxThread.GetInstructionPointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
if Process.Mode=dm32 then
|
||||
result := FUserRegs.regs32[eip]
|
||||
else
|
||||
result := FUserRegs.regs64[rip];
|
||||
end;
|
||||
|
||||
function TDbgLinuxThread.GetStackBasePointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
if Process.Mode=dm32 then
|
||||
result := FUserRegs.regs32[ebp]
|
||||
else
|
||||
result := FUserRegs.regs64[rbp];
|
||||
end;
|
||||
|
||||
function TDbgLinuxThread.GetStackPointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
if Process.Mode=dm32 then
|
||||
result := FUserRegs.regs32[UESP]
|
||||
else
|
||||
result := FUserRegs.regs64[rsp];
|
||||
end;
|
||||
|
||||
{ TDbgLinuxProcess }
|
||||
|
||||
procedure TDbgLinuxProcess.InitializeLoaders;
|
||||
@ -803,30 +828,6 @@ begin
|
||||
Log('Failed to send input to console.', dllDebug);
|
||||
end;
|
||||
|
||||
function TDbgLinuxProcess.GetInstructionPointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
if Mode=dm32 then
|
||||
result := TDbgLinuxThread(FMainThread).FUserRegs.regs32[eip]
|
||||
else
|
||||
result := TDbgLinuxThread(FMainThread).FUserRegs.regs64[rip];
|
||||
end;
|
||||
|
||||
function TDbgLinuxProcess.GetStackPointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
if Mode=dm32 then
|
||||
result := TDbgLinuxThread(FMainThread).FUserRegs.regs32[UESP]
|
||||
else
|
||||
result := TDbgLinuxThread(FMainThread).FUserRegs.regs64[rsp];
|
||||
end;
|
||||
|
||||
function TDbgLinuxProcess.GetStackBasePointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
if Mode=dm32 then
|
||||
result := TDbgLinuxThread(FMainThread).FUserRegs.regs32[ebp]
|
||||
else
|
||||
result := TDbgLinuxThread(FMainThread).FUserRegs.regs64[rbp];
|
||||
end;
|
||||
|
||||
procedure TDbgLinuxProcess.TerminateProcess;
|
||||
begin
|
||||
FIsTerminating:=true;
|
||||
|
@ -66,6 +66,10 @@ type
|
||||
procedure BeforeContinue; override;
|
||||
function ResetInstructionPointerAfterBreakpoint: boolean; override;
|
||||
function ReadThreadState: boolean;
|
||||
|
||||
function GetInstructionPointerRegisterValue: TDbgPtr; override;
|
||||
function GetStackBasePointerRegisterValue: TDbgPtr; override;
|
||||
function GetStackPointerRegisterValue: TDbgPtr; override;
|
||||
end;
|
||||
|
||||
|
||||
@ -113,9 +117,6 @@ type
|
||||
|
||||
procedure StartProcess(const AThreadID: DWORD; const AInfo: TCreateProcessDebugInfo);
|
||||
|
||||
function GetInstructionPointerRegisterValue: TDbgPtr; override;
|
||||
function GetStackBasePointerRegisterValue: TDbgPtr; override;
|
||||
function GetStackPointerRegisterValue: TDbgPtr; override;
|
||||
function Pause: boolean; override;
|
||||
|
||||
procedure TerminateProcess; override;
|
||||
@ -886,33 +887,6 @@ begin
|
||||
then SetFileName(s);
|
||||
end;
|
||||
|
||||
function TDbgWinProcess.GetInstructionPointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
{$ifdef cpui386}
|
||||
Result := GCurrentContext^.Eip;
|
||||
{$else}
|
||||
Result := GCurrentContext^.Rip;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
function TDbgWinProcess.GetStackBasePointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
{$ifdef cpui386}
|
||||
Result := GCurrentContext^.Ebp;
|
||||
{$else}
|
||||
Result := GCurrentContext^.Rbp;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
function TDbgWinProcess.GetStackPointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
{$ifdef cpui386}
|
||||
Result := GCurrentContext^.Esp;
|
||||
{$else}
|
||||
Result := GCurrentContext^.Rsp;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
function DebugBreakProcess(Process:HANDLE): WINBOOL; external 'kernel32' name 'DebugBreakProcess';
|
||||
var
|
||||
DebugBreakAddr: Pointer = nil;
|
||||
@ -1208,5 +1182,32 @@ begin
|
||||
FRegisterValueListValid:=False;
|
||||
end;
|
||||
|
||||
function TDbgWinThread.GetInstructionPointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
{$ifdef cpui386}
|
||||
Result := GCurrentContext^.Eip;
|
||||
{$else}
|
||||
Result := GCurrentContext^.Rip;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
function TDbgWinThread.GetStackBasePointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
{$ifdef cpui386}
|
||||
Result := GCurrentContext^.Ebp;
|
||||
{$else}
|
||||
Result := GCurrentContext^.Rbp;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
function TDbgWinThread.GetStackPointerRegisterValue: TDbgPtr;
|
||||
begin
|
||||
{$ifdef cpui386}
|
||||
Result := GCurrentContext^.Esp;
|
||||
{$else}
|
||||
Result := GCurrentContext^.Rsp;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -296,6 +296,7 @@ type
|
||||
FFpDebugDebugger: TFpDebugDebugger;
|
||||
protected
|
||||
function GetDbgProcess: TDbgProcess; override;
|
||||
function GetDbgThread(AContext: TFpDbgAddressContext): TDbgThread; override;
|
||||
public
|
||||
constructor create(AFpDebugDebuger: TFpDebugDebugger);
|
||||
function ReadMemory(AnAddress: TDbgPtr; ASize: Cardinal; ADest: Pointer): Boolean; override;
|
||||
@ -391,6 +392,15 @@ begin
|
||||
result := FFpDebugDebugger.FDbgController.CurrentProcess;
|
||||
end;
|
||||
|
||||
function TFpDbgMemReader.GetDbgThread(AContext: TFpDbgAddressContext): TDbgThread;
|
||||
var
|
||||
Process: TDbgProcess;
|
||||
begin
|
||||
Process := GetDbgProcess;
|
||||
if not Process.GetThread(AContext.ThreadId, Result) then
|
||||
Result := FFpDebugDebugger.FDbgController.CurrentThread;
|
||||
end;
|
||||
|
||||
constructor TFpDbgMemReader.create(AFpDebugDebuger: TFpDebugDebugger);
|
||||
begin
|
||||
FFpDebugDebugger := AFpDebugDebuger;
|
||||
@ -417,10 +427,9 @@ end;
|
||||
procedure TFPCallStackSupplier.DoStateLeavePause;
|
||||
begin
|
||||
if (TFpDebugDebugger(Debugger).FDbgController <> nil) and
|
||||
(TFpDebugDebugger(Debugger).FDbgController.CurrentProcess <> nil) and
|
||||
(TFpDebugDebugger(Debugger).FDbgController.CurrentProcess.MainThread <> nil)
|
||||
(TFpDebugDebugger(Debugger).FDbgController.CurrentThread <> nil)
|
||||
then
|
||||
TFpDebugDebugger(Debugger).FDbgController.CurrentProcess.MainThread.ClearCallStack;
|
||||
TFpDebugDebugger(Debugger).FDbgController.CurrentThread.ClearCallStack;
|
||||
inherited DoStateLeavePause;
|
||||
end;
|
||||
|
||||
@ -446,7 +455,7 @@ begin
|
||||
exit;
|
||||
end;
|
||||
TFpDebugDebugger(Debugger).PrepareCallStackEntryList;
|
||||
ThreadCallStack := TFpDebugDebugger(Debugger).FDbgController.CurrentProcess.MainThread.CallStackEntryList;
|
||||
ThreadCallStack := TFpDebugDebugger(Debugger).FDbgController.CurrentThread.CallStackEntryList;
|
||||
if ThreadCallStack = nil then
|
||||
exit;
|
||||
|
||||
@ -482,8 +491,8 @@ begin
|
||||
//CurThreadId := FpDebugger.Threads.CurrentThreads.CurrentThreadId;
|
||||
//ThreadCallStack := FpDebugger.Threads.CurrentThreads.Entries[CurThreadId].CallStackEntryList;
|
||||
|
||||
CurThreadId := FpDebugger.FDbgController.CurrentProcess.MainThread.ID;
|
||||
ThreadCallStack := FpDebugger.FDbgController.CurrentProcess.MainThread.CallStackEntryList;
|
||||
CurThreadId := FpDebugger.FDbgController.CurrentThread.ID;
|
||||
ThreadCallStack := FpDebugger.FDbgController.CurrentThread.CallStackEntryList;
|
||||
|
||||
if not It.Locate(ACallstack.LowestUnknown )
|
||||
then if not It.EOM
|
||||
@ -503,7 +512,7 @@ begin
|
||||
params := '';
|
||||
if (ProcVal <> nil) then begin
|
||||
if e.Index = 0 then
|
||||
RegList := AController.CurrentProcess.MainThread.RegisterValueList
|
||||
RegList := AController.CurrentThread.RegisterValueList
|
||||
else
|
||||
RegList := ThreadCallStack[e.Index].RegisterValueList;
|
||||
if AController.CurrentProcess.Mode=dm32 then
|
||||
@ -603,8 +612,8 @@ begin
|
||||
|
||||
if CurStackFrame > 0 then
|
||||
begin
|
||||
AController.CurrentProcess.MainThread.PrepareCallStackEntryList(CurStackFrame);
|
||||
AFrame := AController.CurrentProcess.MainThread.CallStackEntryList[CurStackFrame];
|
||||
AController.CurrentThread.PrepareCallStackEntryList(CurStackFrame);
|
||||
AFrame := AController.CurrentThread.CallStackEntryList[CurStackFrame];
|
||||
if AFrame = nil then
|
||||
begin
|
||||
ALocals.SetDataValidity(ddsInvalid);
|
||||
@ -613,7 +622,7 @@ begin
|
||||
RegList := AFrame.RegisterValueList;
|
||||
end
|
||||
else
|
||||
RegList := AController.CurrentProcess.MainThread.RegisterValueList;
|
||||
RegList := AController.CurrentThread.RegisterValueList;
|
||||
if AController.CurrentProcess.Mode=dm32 then
|
||||
Reg := RegList.FindRegisterByDwarfIndex(8)
|
||||
else
|
||||
@ -922,7 +931,7 @@ begin
|
||||
if (Debugger = nil) or not(Debugger.State in [dsPause, dsStop]) then
|
||||
exit;
|
||||
|
||||
ARegisterList := TFpDebugDebugger(Debugger).FDbgController.CurrentProcess.MainThread.RegisterValueList;
|
||||
ARegisterList := TFpDebugDebugger(Debugger).FDbgController.CurrentThread.RegisterValueList;
|
||||
for i := 0 to ARegisterList.Count-1 do
|
||||
begin
|
||||
ARegisterValue := ARegisters.EntriesByName[ARegisterList[i].Name];
|
||||
@ -1211,8 +1220,8 @@ begin
|
||||
|
||||
if StackFrame > 0 then
|
||||
begin
|
||||
FDbgController.CurrentProcess.MainThread.PrepareCallStackEntryList(StackFrame);
|
||||
AFrame := FDbgController.CurrentProcess.MainThread.CallStackEntryList[StackFrame];
|
||||
FDbgController.CurrentThread.PrepareCallStackEntryList(StackFrame);
|
||||
AFrame := FDbgController.CurrentThread.CallStackEntryList[StackFrame];
|
||||
if AFrame = nil then
|
||||
begin
|
||||
if AWatchValue <> nil then
|
||||
@ -1222,7 +1231,7 @@ begin
|
||||
RegList := AFrame.RegisterValueList;
|
||||
end
|
||||
else
|
||||
RegList := AController.CurrentProcess.MainThread.RegisterValueList;
|
||||
RegList := AController.CurrentThread.RegisterValueList;
|
||||
if AController.CurrentProcess.Mode = dm32 then
|
||||
Reg := RegList.FindRegisterByDwarfIndex(8)
|
||||
else
|
||||
@ -1470,8 +1479,8 @@ begin
|
||||
else
|
||||
RegDxDwarfIndex:=1;
|
||||
|
||||
AnExceptionLocation:=GetLocationRec(FDbgController.CurrentProcess.MainThread.RegisterValueList.FindRegisterByDwarfIndex(RegDxDwarfIndex).NumValue);
|
||||
AnExceptionObjectLocation:=FDbgController.CurrentProcess.MainThread.RegisterValueList.FindRegisterByDwarfIndex(0).NumValue;
|
||||
AnExceptionLocation:=GetLocationRec(FDbgController.CurrentThread.RegisterValueList.FindRegisterByDwarfIndex(RegDxDwarfIndex).NumValue);
|
||||
AnExceptionObjectLocation:=FDbgController.CurrentThread.RegisterValueList.FindRegisterByDwarfIndex(0).NumValue;
|
||||
ExceptionClass := GetClassInstanceName(AnExceptionObjectLocation);
|
||||
ExceptionMessage := ReadAnsiString(AnExceptionObjectLocation+DBGPTRSIZE[FDbgController.CurrentProcess.Mode]);
|
||||
|
||||
@ -1913,7 +1922,7 @@ begin
|
||||
result.SrcLine:=0;
|
||||
|
||||
if AnAddress=0 then
|
||||
result.Address := FDbgController.CurrentProcess.GetInstructionPointerRegisterValue
|
||||
result.Address := FDbgController.CurrentThread.GetInstructionPointerRegisterValue
|
||||
else
|
||||
result.Address := AnAddress;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user