FpDebug: Fix Command.DoContinue. Do not read DbgThread.GetInstrPtr if the event is caused by another thread. On Linux the none-event thread (belonging to the command) may not be paused/readable.

git-svn-id: trunk@62492 -
This commit is contained in:
martin 2020-01-04 19:02:04 +00:00
parent 6cc8e56bdc
commit 2282f707cf

View File

@ -516,10 +516,12 @@ procedure TDbgControllerHiddenBreakStepBaseCmd.DoContinue(AProcess: TDbgProcess;
AThread: TDbgThread); AThread: TDbgThread);
begin begin
InternalContinue(AProcess, AThread); InternalContinue(AProcess, AThread);
if ((FNextInstruction.OpCode = OPret) or (FNextInstruction.OpCode = OPretf)) and if (AThread = FThread) then begin
(FHiddenBreakpoint = nil) if ((FNextInstruction.OpCode = OPret) or (FNextInstruction.OpCode = OPretf)) and
then (FHiddenBreakpoint = nil)
FIsSteppedOut := True; then
FIsSteppedOut := True;
end;
FNextInstruction.OpCode := OPX_InternalUnknown; FNextInstruction.OpCode := OPX_InternalUnknown;
FNextInstructionLen := 0; FNextInstructionLen := 0;
end; end;
@ -530,7 +532,8 @@ procedure TDbgControllerStepOverInstructionCmd.InternalContinue(
AProcess: TDbgProcess; AThread: TDbgThread); AProcess: TDbgProcess; AThread: TDbgThread);
begin begin
assert(FProcess=AProcess, 'TDbgControllerStepOverInstructionCmd.DoContinue: FProcess=AProcess'); assert(FProcess=AProcess, 'TDbgControllerStepOverInstructionCmd.DoContinue: FProcess=AProcess');
CheckForCallAndSetBreak; if (AThread = FThread) then
CheckForCallAndSetBreak;
FProcess.Continue(FProcess, FThread, FHiddenBreakpoint = nil); FProcess.Continue(FProcess, FThread, FHiddenBreakpoint = nil);
end; end;
@ -629,7 +632,7 @@ procedure TDbgControllerStepIntoLineCmd.InternalContinue(AProcess: TDbgProcess;
AThread: TDbgThread); AThread: TDbgThread);
begin begin
assert(FProcess=AProcess, 'TDbgControllerStepIntoLineCmd.DoContinue: FProcess=AProcess'); assert(FProcess=AProcess, 'TDbgControllerStepIntoLineCmd.DoContinue: FProcess=AProcess');
if FState = siSteppingCurrent then if (FState = siSteppingCurrent) and (AThread = FThread) then
begin begin
if CheckForCallAndSetBreak then begin if CheckForCallAndSetBreak then begin
FState := siSteppingIn; FState := siSteppingIn;
@ -704,7 +707,8 @@ procedure TDbgControllerStepOverLineCmd.InternalContinue(AProcess: TDbgProcess;
AThread: TDbgThread); AThread: TDbgThread);
begin begin
assert(FProcess=AProcess, 'TDbgControllerStepOverLineCmd.DoContinue: FProcess=AProcess'); assert(FProcess=AProcess, 'TDbgControllerStepOverLineCmd.DoContinue: FProcess=AProcess');
CheckForCallAndSetBreak; if (AThread = FThread) then
CheckForCallAndSetBreak;
FProcess.Continue(FProcess, FThread, FHiddenBreakpoint = nil); FProcess.Continue(FProcess, FThread, FHiddenBreakpoint = nil);
end; end;
@ -781,38 +785,40 @@ var
begin begin
assert(FProcess=AProcess, 'TDbgControllerStepOutCmd.DoContinue: FProcess=AProcess'); assert(FProcess=AProcess, 'TDbgControllerStepOutCmd.DoContinue: FProcess=AProcess');
if IsSteppedOut then begin if (AThread = FThread) then begin
CheckForCallAndSetBreak; if IsSteppedOut then begin
end CheckForCallAndSetBreak;
else
if not assigned(FHiddenBreakpoint) then begin
if GetOutsideFrame(Outside) then begin
SetReturnAdressBreakpoint(AProcess, Outside);
end end
else else
if FStepCount < 12 then if not assigned(FHiddenBreakpoint) then begin
begin if GetOutsideFrame(Outside) then begin
// During the prologue and epiloge of a procedure the call-stack might not been SetReturnAdressBreakpoint(AProcess, Outside);
// setup already. To avoid problems in these cases, start with a few (max
// 12) single steps.
Inc(FStepCount);
Opc := NextOpCode;
if (Opc = OPcall) or (Opc = OPleave) then // asm "call" // set break before "leave" or the frame becomes unavail
begin
SetReturnAdressBreakpoint(AProcess, False);
end end
else else
if (Opc = OPret) or (Opc = OPretf) then // asm "ret" if FStepCount < 12 then
begin begin
FStepCount := MaxInt; // Do one more single-step, and we're finished. // During the prologue and epiloge of a procedure the call-stack might not been
FProcess.Continue(FProcess, FThread, True); // setup already. To avoid problems in these cases, start with a few (max
exit; // 12) single steps.
Inc(FStepCount);
Opc := NextOpCode;
if (Opc = OPcall) or (Opc = OPleave) then // asm "call" // set break before "leave" or the frame becomes unavail
begin
SetReturnAdressBreakpoint(AProcess, False);
end
else
if (Opc = OPret) or (Opc = OPretf) then // asm "ret"
begin
FStepCount := MaxInt; // Do one more single-step, and we're finished.
FProcess.Continue(FProcess, FThread, True);
exit;
end;
end
else
begin
// Enough with the single-stepping
SetReturnAdressBreakpoint(AProcess, False);
end; end;
end
else
begin
// Enough with the single-stepping
SetReturnAdressBreakpoint(AProcess, False);
end; end;
end; end;