mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 05:19:14 +02:00
FpDebug, Linux: Improve stepping over breakpoint.
When the signal for a newly launched thread was received while the single-step was still in progress, then "RestoreTempBreakInstructionCodes" failed (as the thread was still running), and the breakpoint (int3) ended up missing (no longer stopping at the breakpoint).
This commit is contained in:
parent
4650dfa54a
commit
ad9a460928
@ -315,6 +315,7 @@ type
|
|||||||
FIsTerminating: boolean;
|
FIsTerminating: boolean;
|
||||||
FMasterPtyFd: cint;
|
FMasterPtyFd: cint;
|
||||||
FCurrentThreadId: THandle;
|
FCurrentThreadId: THandle;
|
||||||
|
FSingleSteppingThreadID: THandle;
|
||||||
// This breakpoint is triggered after dynamic libraries have been (un)loaded
|
// This breakpoint is triggered after dynamic libraries have been (un)loaded
|
||||||
FSOLibEventBreakpoint: TFpDbgBreakpoint;
|
FSOLibEventBreakpoint: TFpDbgBreakpoint;
|
||||||
{$ifndef VER2_6}
|
{$ifndef VER2_6}
|
||||||
@ -1140,6 +1141,7 @@ constructor TDbgLinuxProcess.Create(const AFileName: string;
|
|||||||
AProcessConfig: TDbgProcessConfig);
|
AProcessConfig: TDbgProcessConfig);
|
||||||
begin
|
begin
|
||||||
FMasterPtyFd:=-1;
|
FMasterPtyFd:=-1;
|
||||||
|
FSingleSteppingThreadID := -1;
|
||||||
FPostponedSignals := TFpDbgLinuxSignalQueue.Create;
|
FPostponedSignals := TFpDbgLinuxSignalQueue.Create;
|
||||||
inherited Create(AFileName, AnOsClasses, AMemManager, AProcessConfig);
|
inherited Create(AFileName, AnOsClasses, AMemManager, AProcessConfig);
|
||||||
end;
|
end;
|
||||||
@ -1525,6 +1527,7 @@ begin
|
|||||||
{$IFDEF DebuglnLinuxDebugEvents}
|
{$IFDEF DebuglnLinuxDebugEvents}
|
||||||
debuglnEnter(['>>>>> TDbgLinuxProcess.Continue TID:', AThread.ID, ' SingleStep:', SingleStep ]); try
|
debuglnEnter(['>>>>> TDbgLinuxProcess.Continue TID:', AThread.ID, ' SingleStep:', SingleStep ]); try
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
FSingleSteppingThreadID := -1;
|
||||||
|
|
||||||
// Terminating process and all threads
|
// Terminating process and all threads
|
||||||
if FIsTerminating then begin
|
if FIsTerminating then begin
|
||||||
@ -1558,10 +1561,10 @@ begin
|
|||||||
ThreadToContinue.BeforeContinue;
|
ThreadToContinue.BeforeContinue;
|
||||||
|
|
||||||
while (ThreadToContinue.GetInstructionPointerRegisterValue = IP) do begin
|
while (ThreadToContinue.GetInstructionPointerRegisterValue = IP) do begin
|
||||||
fpseterrno(0);
|
|
||||||
{$IFDEF DebuglnLinuxDebugEvents}
|
{$IFDEF DebuglnLinuxDebugEvents}
|
||||||
Debugln(FPDBG_LINUX, ['Single-stepping other TID: ', ThreadToContinue.ID]);
|
Debugln(FPDBG_LINUX, ['Single-stepping other TID: ', ThreadToContinue.ID]);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
fpseterrno(0);
|
||||||
fpPTrace(PTRACE_SINGLESTEP, ThreadToContinue.ID, pointer(1), pointer(TDbgLinuxThread(ThreadToContinue).FExceptionSignal));
|
fpPTrace(PTRACE_SINGLESTEP, ThreadToContinue.ID, pointer(1), pointer(TDbgLinuxThread(ThreadToContinue).FExceptionSignal));
|
||||||
|
|
||||||
TDbgLinuxThread(ThreadToContinue).ResetPauseStates;
|
TDbgLinuxThread(ThreadToContinue).ResetPauseStates;
|
||||||
@ -1569,7 +1572,7 @@ begin
|
|||||||
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
|
||||||
DebugLn(DBG_WARNINGS, ['Error single stepping other thread ', ThreadToContinue.ID, ' waitpid got ', PID, ', ',WaitStatus, ' err ', Errno]);
|
DebugLn(DBG_WARNINGS, ['XXXXX Error single stepping other thread ', ThreadToContinue.ID, ' waitpid got ', PID, ', ',WaitStatus, ' err ', Errno]);
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
if ThreadToContinue.NextIsSingleStep then begin
|
if ThreadToContinue.NextIsSingleStep then begin
|
||||||
@ -1604,6 +1607,7 @@ begin
|
|||||||
{$IFDEF DebuglnLinuxDebugEvents}
|
{$IFDEF DebuglnLinuxDebugEvents}
|
||||||
Debugln(FPDBG_LINUX, ['Single-stepping current']);
|
Debugln(FPDBG_LINUX, ['Single-stepping current']);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
FSingleSteppingThreadID := AThread.ID;
|
||||||
fpPTrace(PTRACE_SINGLESTEP, AThread.ID, pointer(1), pointer(TDbgLinuxThread(AThread).FExceptionSignal));
|
fpPTrace(PTRACE_SINGLESTEP, AThread.ID, pointer(1), pointer(TDbgLinuxThread(AThread).FExceptionSignal));
|
||||||
TDbgLinuxThread(AThread).ResetPauseStates;
|
TDbgLinuxThread(AThread).ResetPauseStates;
|
||||||
Result := CheckNoError;
|
Result := CheckNoError;
|
||||||
@ -1656,10 +1660,16 @@ begin
|
|||||||
ThreadIdentifier:=-1;
|
ThreadIdentifier:=-1;
|
||||||
ProcessIdentifier:=-1;
|
ProcessIdentifier:=-1;
|
||||||
|
|
||||||
|
if FSingleSteppingThreadID <> -1 then begin
|
||||||
|
PID:=FpWaitPid(FSingleSteppingThreadID, FStatus, __WALL);
|
||||||
|
if PID <> FSingleSteppingThreadID then
|
||||||
|
DebugLn(DBG_WARNINGS, ['XXXXX Error: single stepping current thread ', FSingleSteppingThreadID, ' waitpid got ', PID, ', ',FStatus, ' err ', Errno]);
|
||||||
|
end
|
||||||
|
else
|
||||||
If not FPostponedSignals.GetNextSignal(PID, FStatus) then
|
If not FPostponedSignals.GetNextSignal(PID, FStatus) then
|
||||||
PID:=FpWaitPid(-1, FStatus, __WALL);
|
PID:=FpWaitPid(-1, FStatus, __WALL);
|
||||||
|
|
||||||
RestoreTempBreakInstructionCodes;
|
RestoreTempBreakInstructionCodes; // should only happen after single step, so all threads should be paused
|
||||||
|
|
||||||
result := PID<>-1;
|
result := PID<>-1;
|
||||||
if not result then
|
if not result then
|
||||||
|
Loading…
Reference in New Issue
Block a user