mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-09 15:16:04 +02:00
FpDebug: More refactor internal breakpoints. Improve stopping other threads on Linux
git-svn-id: trunk@60214 -
This commit is contained in:
parent
6f10746551
commit
cfed0db10f
@ -234,6 +234,7 @@ type
|
|||||||
FHasExceptionSignal: Boolean;
|
FHasExceptionSignal: Boolean;
|
||||||
FIsPaused, FInternalPauseRequested, FIsInInternalPause: boolean;
|
FIsPaused, FInternalPauseRequested, FIsInInternalPause: boolean;
|
||||||
FIsSteppingBreakPoint: boolean;
|
FIsSteppingBreakPoint: boolean;
|
||||||
|
FHasThreadState: boolean;
|
||||||
function GetDebugRegOffset(ind: byte): pointer;
|
function GetDebugRegOffset(ind: byte): pointer;
|
||||||
function ReadDebugReg(ind: byte; out AVal: PtrUInt): boolean;
|
function ReadDebugReg(ind: byte; out AVal: PtrUInt): boolean;
|
||||||
function WriteDebugReg(ind: byte; AVal: PtrUInt): boolean;
|
function WriteDebugReg(ind: byte; AVal: PtrUInt): boolean;
|
||||||
@ -403,7 +404,10 @@ function TDbgLinuxThread.ReadThreadState: boolean;
|
|||||||
var
|
var
|
||||||
io: iovec;
|
io: iovec;
|
||||||
begin
|
begin
|
||||||
|
assert(FIsPaused, 'TDbgLinuxThread.ReadThreadState: FIsPaused');
|
||||||
result := true;
|
result := true;
|
||||||
|
if FHasThreadState then
|
||||||
|
exit;
|
||||||
io.iov_base:=@(FUserRegs.regs32[0]);
|
io.iov_base:=@(FUserRegs.regs32[0]);
|
||||||
io.iov_len:= sizeof(FUserRegs);
|
io.iov_len:= sizeof(FUserRegs);
|
||||||
if fpPTrace(PTRACE_GETREGSET, ID, pointer(PtrUInt(NT_PRSTATUS)), @io) <> 0 then
|
if fpPTrace(PTRACE_GETREGSET, ID, pointer(PtrUInt(NT_PRSTATUS)), @io) <> 0 then
|
||||||
@ -413,6 +417,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
FUserRegsChanged:=false;
|
FUserRegsChanged:=false;
|
||||||
FRegisterValueListValid:=false;
|
FRegisterValueListValid:=false;
|
||||||
|
FHasThreadState := Result;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgLinuxThread.RequestInternalPause: Boolean;
|
function TDbgLinuxThread.RequestInternalPause: Boolean;
|
||||||
@ -476,6 +481,7 @@ begin
|
|||||||
|
|
||||||
else
|
else
|
||||||
if wstopsig(AWaitedStatus) = SIGTRAP then begin
|
if wstopsig(AWaitedStatus) = SIGTRAP then begin
|
||||||
|
ReadThreadState;
|
||||||
CheckAndResetInstructionPointerAfterBreakpoint;
|
CheckAndResetInstructionPointerAfterBreakpoint;
|
||||||
FHasExceptionSignal := False; // TODO: main loop should search all threads for breakpoints
|
FHasExceptionSignal := False; // TODO: main loop should search all threads for breakpoints
|
||||||
end
|
end
|
||||||
@ -498,10 +504,12 @@ begin
|
|||||||
FIsInInternalPause := False;
|
FIsInInternalPause := False;
|
||||||
FIsPaused := False;
|
FIsPaused := False;
|
||||||
FExceptionSignal := 0;
|
FExceptionSignal := 0;
|
||||||
|
FHasThreadState := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDbgLinuxThread.ResetInstructionPointerAfterBreakpoint: boolean;
|
function TDbgLinuxThread.ResetInstructionPointerAfterBreakpoint: boolean;
|
||||||
begin
|
begin
|
||||||
|
ReadThreadState;
|
||||||
result := true;
|
result := true;
|
||||||
|
|
||||||
if Process.Mode=dm32 then
|
if Process.Mode=dm32 then
|
||||||
@ -609,6 +617,7 @@ end;
|
|||||||
|
|
||||||
procedure TDbgLinuxThread.LoadRegisterValues;
|
procedure TDbgLinuxThread.LoadRegisterValues;
|
||||||
begin
|
begin
|
||||||
|
ReadThreadState;
|
||||||
if Process.Mode=dm32 then
|
if Process.Mode=dm32 then
|
||||||
begin
|
begin
|
||||||
FRegisterValueList.DbgRegisterAutoCreate['eax'].SetValue(FUserRegs.regs32[eax], IntToStr(FUserRegs.regs32[eax]),4,0);
|
FRegisterValueList.DbgRegisterAutoCreate['eax'].SetValue(FUserRegs.regs32[eax], IntToStr(FUserRegs.regs32[eax]),4,0);
|
||||||
@ -661,6 +670,7 @@ end;
|
|||||||
|
|
||||||
function TDbgLinuxThread.GetInstructionPointerRegisterValue: TDbgPtr;
|
function TDbgLinuxThread.GetInstructionPointerRegisterValue: TDbgPtr;
|
||||||
begin
|
begin
|
||||||
|
ReadThreadState;
|
||||||
if Process.Mode=dm32 then
|
if Process.Mode=dm32 then
|
||||||
result := FUserRegs.regs32[eip]
|
result := FUserRegs.regs32[eip]
|
||||||
else
|
else
|
||||||
@ -669,6 +679,7 @@ end;
|
|||||||
|
|
||||||
function TDbgLinuxThread.GetStackBasePointerRegisterValue: TDbgPtr;
|
function TDbgLinuxThread.GetStackBasePointerRegisterValue: TDbgPtr;
|
||||||
begin
|
begin
|
||||||
|
ReadThreadState;
|
||||||
if Process.Mode=dm32 then
|
if Process.Mode=dm32 then
|
||||||
result := FUserRegs.regs32[ebp]
|
result := FUserRegs.regs32[ebp]
|
||||||
else
|
else
|
||||||
@ -677,6 +688,7 @@ end;
|
|||||||
|
|
||||||
function TDbgLinuxThread.GetStackPointerRegisterValue: TDbgPtr;
|
function TDbgLinuxThread.GetStackPointerRegisterValue: TDbgPtr;
|
||||||
begin
|
begin
|
||||||
|
ReadThreadState;
|
||||||
if Process.Mode=dm32 then
|
if Process.Mode=dm32 then
|
||||||
result := FUserRegs.regs32[UESP]
|
result := FUserRegs.regs32[UESP]
|
||||||
else
|
else
|
||||||
@ -985,17 +997,18 @@ begin
|
|||||||
|
|
||||||
// check other threads if they need a singlestep
|
// check other threads if they need a singlestep
|
||||||
for TDbgThread(ThreadToContinue) in FThreadMap do
|
for TDbgThread(ThreadToContinue) in FThreadMap do
|
||||||
if (ThreadToContinue <> AThread) then begin
|
if (ThreadToContinue <> AThread) and ThreadToContinue.FIsPaused then begin
|
||||||
IP := ThreadToContinue.GetInstructionPointerRegisterValue;
|
IP := ThreadToContinue.GetInstructionPointerRegisterValue;
|
||||||
if HasInsertedBreakInstructionAtLocation(IP) then begin
|
if HasInsertedBreakInstructionAtLocation(IP) then begin
|
||||||
TempRemoveBreakInstructionCode(IP);
|
TempRemoveBreakInstructionCode(IP);
|
||||||
ThreadToContinue.BeforeContinue;
|
ThreadToContinue.BeforeContinue;
|
||||||
|
|
||||||
while ThreadToContinue.GetInstructionPointerRegisterValue = IP do begin
|
while (ThreadToContinue.GetInstructionPointerRegisterValue = IP) do begin
|
||||||
fpseterrno(0);
|
fpseterrno(0);
|
||||||
fpPTrace(PTRACE_SINGLESTEP, ThreadToContinue.ID, pointer(1), pointer(wstopsig(TDbgLinuxThread(ThreadToContinue).FExceptionSignal)));
|
fpPTrace(PTRACE_SINGLESTEP, ThreadToContinue.ID, pointer(1), pointer(wstopsig(TDbgLinuxThread(ThreadToContinue).FExceptionSignal)));
|
||||||
TDbgLinuxThread(ThreadToContinue).ResetPauseStates; // So BeforeContinue will not run again
|
TDbgLinuxThread(ThreadToContinue).ResetPauseStates; // So BeforeContinue will not run again
|
||||||
|
|
||||||
|
ThreadToContinue.FIsPaused := True;
|
||||||
if CheckNoError then begin
|
if CheckNoError then begin
|
||||||
PID := fpWaitPid(ThreadToContinue.ID, WaitStatus, __WALL);
|
PID := fpWaitPid(ThreadToContinue.ID, WaitStatus, __WALL);
|
||||||
if PID <> ThreadToContinue.ID then begin
|
if PID <> ThreadToContinue.ID then begin
|
||||||
@ -1269,7 +1282,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user