mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 16:42:06 +02:00
FpDebug: Stepping commands, refactor HiddenBreakpoint:
- Move to base-class - No need to check for other breakpoints (fpdebug can now handle several brk at same address) - Stop step-out, if break failed to set git-svn-id: trunk@61880 -
This commit is contained in:
parent
1c5491c441
commit
48f15f849d
@ -56,12 +56,19 @@ type
|
|||||||
procedure DoContinue(AProcess: TDbgProcess; AThread: TDbgThread); override;
|
procedure DoContinue(AProcess: TDbgProcess; AThread: TDbgThread); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TDbgControllerHiddenBreakStepCmd }
|
||||||
|
|
||||||
|
TDbgControllerHiddenBreakStepCmd = class(TDbgControllerCmd)
|
||||||
|
protected
|
||||||
|
FHiddenBreakpoint: TFpInternalBreakpoint;
|
||||||
|
procedure RemoveHiddenBreak;
|
||||||
|
public
|
||||||
|
destructor Destroy; override;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TDbgControllerStepOverInstructionCmd }
|
{ TDbgControllerStepOverInstructionCmd }
|
||||||
|
|
||||||
TDbgControllerStepOverInstructionCmd = class(TDbgControllerCmd)
|
TDbgControllerStepOverInstructionCmd = class(TDbgControllerHiddenBreakStepCmd)
|
||||||
private
|
|
||||||
FHiddenBreakpoint: TFpInternalBreakpoint;
|
|
||||||
FIsSet: boolean;
|
|
||||||
protected
|
protected
|
||||||
procedure DoResolveEvent(var AnEvent: TFPDEvent; AnEventThread: TDbgThread; out Handled, Finished: boolean); override;
|
procedure DoResolveEvent(var AnEvent: TFPDEvent; AnEventThread: TDbgThread; out Handled, Finished: boolean); override;
|
||||||
public
|
public
|
||||||
@ -70,7 +77,7 @@ type
|
|||||||
|
|
||||||
{ TDbgControllerStepIntoLineCmd }
|
{ TDbgControllerStepIntoLineCmd }
|
||||||
|
|
||||||
TDbgControllerStepIntoLineCmd = class(TDbgControllerCmd)
|
TDbgControllerStepIntoLineCmd = class(TDbgControllerHiddenBreakStepCmd)
|
||||||
private
|
private
|
||||||
FStoredStackFrame: TDBGPtr;
|
FStoredStackFrame: TDBGPtr;
|
||||||
FInto: boolean;
|
FInto: boolean;
|
||||||
@ -80,14 +87,12 @@ type
|
|||||||
FLastStackPointerValue: TDBGPtr;
|
FLastStackPointerValue: TDBGPtr;
|
||||||
FLastStackBaseValue: TDBGPtr;
|
FLastStackBaseValue: TDBGPtr;
|
||||||
FAssumedProcStartStackPointer: TDBGPtr;
|
FAssumedProcStartStackPointer: TDBGPtr;
|
||||||
FHiddenBreakpoint: TFpInternalBreakpoint;
|
|
||||||
FInstCount: integer;
|
FInstCount: integer;
|
||||||
protected
|
protected
|
||||||
procedure Init; override;
|
procedure Init; override;
|
||||||
procedure DoResolveEvent(var AnEvent: TFPDEvent; AnEventThread: TDbgThread; out Handled, Finished: boolean); override;
|
procedure DoResolveEvent(var AnEvent: TFPDEvent; AnEventThread: TDbgThread; out Handled, Finished: boolean); override;
|
||||||
public
|
public
|
||||||
constructor Create(AController: TDbgController); override;
|
constructor Create(AController: TDbgController); override;
|
||||||
destructor Destroy; override;
|
|
||||||
procedure DoContinue(AProcess: TDbgProcess; AThread: TDbgThread); override;
|
procedure DoContinue(AProcess: TDbgProcess; AThread: TDbgThread); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -105,9 +110,8 @@ type
|
|||||||
|
|
||||||
{ TDbgControllerStepOutCmd }
|
{ TDbgControllerStepOutCmd }
|
||||||
|
|
||||||
TDbgControllerStepOutCmd = class(TDbgControllerCmd)
|
TDbgControllerStepOutCmd = class(TDbgControllerHiddenBreakStepCmd)
|
||||||
private
|
private
|
||||||
FHiddenBreakpoint: TFpInternalBreakpoint;
|
|
||||||
FIsSet: boolean;
|
FIsSet: boolean;
|
||||||
FStepCount: Integer;
|
FStepCount: Integer;
|
||||||
FStepOut: Boolean;
|
FStepOut: Boolean;
|
||||||
@ -120,11 +124,11 @@ type
|
|||||||
|
|
||||||
{ TDbgControllerRunToCmd }
|
{ TDbgControllerRunToCmd }
|
||||||
|
|
||||||
TDbgControllerRunToCmd = class(TDbgControllerCmd)
|
TDbgControllerRunToCmd = class(TDbgControllerHiddenBreakStepCmd)
|
||||||
private
|
private
|
||||||
FHiddenBreakpoint: TFpInternalBreakpoint;
|
|
||||||
FLocation: TDBGPtrArray;
|
FLocation: TDBGPtrArray;
|
||||||
protected
|
protected
|
||||||
|
procedure Init; override;
|
||||||
procedure DoResolveEvent(var AnEvent: TFPDEvent; AnEventThread: TDbgThread; out Handled, Finished: boolean); override;
|
procedure DoResolveEvent(var AnEvent: TFPDEvent; AnEventThread: TDbgThread; out Handled, Finished: boolean); override;
|
||||||
public
|
public
|
||||||
constructor Create(AController: TDbgController; ALocation: TDBGPtrArray);
|
constructor Create(AController: TDbgController; ALocation: TDBGPtrArray);
|
||||||
@ -282,6 +286,20 @@ begin
|
|||||||
AnEvent := deFinishedStep;
|
AnEvent := deFinishedStep;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TDbgControllerHiddenBreakStepCmd }
|
||||||
|
|
||||||
|
procedure TDbgControllerHiddenBreakStepCmd.RemoveHiddenBreak;
|
||||||
|
begin
|
||||||
|
if assigned(FHiddenBreakpoint) then
|
||||||
|
FreeAndNil(FHiddenBreakpoint);
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TDbgControllerHiddenBreakStepCmd.Destroy;
|
||||||
|
begin
|
||||||
|
RemoveHiddenBreak;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TDbgControllerStepOverInstructionCmd }
|
{ TDbgControllerStepOverInstructionCmd }
|
||||||
|
|
||||||
procedure TDbgControllerStepOverInstructionCmd.DoContinue(AProcess: TDbgProcess; AThread: TDbgThread);
|
procedure TDbgControllerStepOverInstructionCmd.DoContinue(AProcess: TDbgProcess; AThread: TDbgThread);
|
||||||
@ -296,7 +314,7 @@ var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
assert(FProcess=AProcess, 'TDbgControllerStepOverInstructionCmd.DoContinue: FProcess=AProcess');
|
assert(FProcess=AProcess, 'TDbgControllerStepOverInstructionCmd.DoContinue: FProcess=AProcess');
|
||||||
if FIsSet then
|
if FHiddenBreakpoint <> nil then
|
||||||
FProcess.Continue(FProcess, FThread, false)
|
FProcess.Continue(FProcess, FThread, false)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -312,9 +330,7 @@ begin
|
|||||||
if CallInstr then
|
if CallInstr then
|
||||||
begin
|
begin
|
||||||
ALocation := AThread.GetInstructionPointerRegisterValue+(PtrUInt(p)-PtrUInt(@codebin));
|
ALocation := AThread.GetInstructionPointerRegisterValue+(PtrUInt(p)-PtrUInt(@codebin));
|
||||||
if not AProcess.HasBreak(ALocation) then
|
FHiddenBreakpoint := AProcess.AddInternalBreak(ALocation);
|
||||||
FHiddenBreakpoint := AProcess.AddInternalBreak(ALocation);
|
|
||||||
FIsSet:=true;
|
|
||||||
end;
|
end;
|
||||||
FProcess.Continue(FProcess, FThread, not CallInstr);
|
FProcess.Continue(FProcess, FThread, not CallInstr);
|
||||||
end;
|
end;
|
||||||
@ -329,11 +345,7 @@ begin
|
|||||||
if Finished then
|
if Finished then
|
||||||
begin
|
begin
|
||||||
AnEvent := deFinishedStep;
|
AnEvent := deFinishedStep;
|
||||||
if assigned(FHiddenBreakpoint) then
|
RemoveHiddenBreak;
|
||||||
begin
|
|
||||||
FController.FCurrentProcess.RemoveBreak(FHiddenBreakpoint);
|
|
||||||
FHiddenBreakpoint.Free;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -354,16 +366,6 @@ begin
|
|||||||
inherited Create(AController);
|
inherited Create(AController);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TDbgControllerStepIntoLineCmd.Destroy;
|
|
||||||
begin
|
|
||||||
if assigned(FHiddenBreakpoint) then
|
|
||||||
begin
|
|
||||||
FController.CurrentProcess.RemoveBreak(FHiddenBreakpoint);
|
|
||||||
FreeAndNil(FHiddenBreakpoint);
|
|
||||||
end;
|
|
||||||
inherited Destroy;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TDbgControllerStepIntoLineCmd.DoContinue(AProcess: TDbgProcess; AThread: TDbgThread);
|
procedure TDbgControllerStepIntoLineCmd.DoContinue(AProcess: TDbgProcess; AThread: TDbgThread);
|
||||||
|
|
||||||
var
|
var
|
||||||
@ -387,8 +389,7 @@ begin
|
|||||||
FInstCount := 0;
|
FInstCount := 0;
|
||||||
|
|
||||||
ALocation := AThread.GetInstructionPointerRegisterValue+(PtrUInt(p)-PtrUInt(@codebin));
|
ALocation := AThread.GetInstructionPointerRegisterValue+(PtrUInt(p)-PtrUInt(@codebin));
|
||||||
if not AProcess.HasBreak(ALocation) then
|
FHiddenBreakpoint := AProcess.AddInternalBreak(ALocation);
|
||||||
FHiddenBreakpoint := AProcess.AddInternalBreak(ALocation);
|
|
||||||
|
|
||||||
FProcess.Continue(FProcess, FThread, true);
|
FProcess.Continue(FProcess, FThread, true);
|
||||||
exit;
|
exit;
|
||||||
@ -447,8 +448,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
FInto:=false;
|
FInto:=false;
|
||||||
FInstCount:=0;
|
FInstCount:=0;
|
||||||
FController.CurrentProcess.RemoveBreak(FHiddenBreakpoint);
|
RemoveHiddenBreak;
|
||||||
FreeAndNil(FHiddenBreakpoint);
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -518,8 +518,7 @@ begin
|
|||||||
(FController.NextOnlyStopOnStartLine or (FStoredStackFrame < FController.CurrentThread.GetStackBasePointerRegisterValue))) then
|
(FController.NextOnlyStopOnStartLine or (FStoredStackFrame < FController.CurrentThread.GetStackBasePointerRegisterValue))) then
|
||||||
begin
|
begin
|
||||||
AnEvent:=deInternalContinue;
|
AnEvent:=deInternalContinue;
|
||||||
FHiddenBreakpoint:=nil;
|
RemoveHiddenBreak;
|
||||||
FIsSet:=false;
|
|
||||||
Finished:=false;
|
Finished:=false;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -539,8 +538,7 @@ begin
|
|||||||
|
|
||||||
if AProcess.ReadAddress(StepOutStackPos, ReturnAddress) then
|
if AProcess.ReadAddress(StepOutStackPos, ReturnAddress) then
|
||||||
begin
|
begin
|
||||||
if not AProcess.HasBreak(ReturnAddress) then
|
FHiddenBreakpoint := AProcess.AddInternalBreak(ReturnAddress)
|
||||||
FHiddenBreakpoint := AProcess.AddInternalBreak(ReturnAddress)
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -609,7 +607,7 @@ begin
|
|||||||
// finished.
|
// finished.
|
||||||
Finished := true
|
Finished := true
|
||||||
else if FIsSet then
|
else if FIsSet then
|
||||||
Finished := not (AnEvent in [deInternalContinue, deLoadLibrary])
|
Finished := (not (AnEvent in [deInternalContinue, deLoadLibrary])) or (FHiddenBreakpoint = nil)
|
||||||
else if (AnEvent in [deBreakpoint]) and not FProcess.HasBreak(FThread.GetInstructionPointerRegisterValue) then
|
else if (AnEvent in [deBreakpoint]) and not FProcess.HasBreak(FThread.GetInstructionPointerRegisterValue) then
|
||||||
// Single-stepping, so continue silently.
|
// Single-stepping, so continue silently.
|
||||||
AnEvent := deInternalContinue;
|
AnEvent := deInternalContinue;
|
||||||
@ -617,10 +615,7 @@ begin
|
|||||||
if Finished then
|
if Finished then
|
||||||
begin
|
begin
|
||||||
AnEvent := deFinishedStep;
|
AnEvent := deFinishedStep;
|
||||||
if Assigned(FHiddenBreakpoint) then begin
|
RemoveHiddenBreak;
|
||||||
FProcess.RemoveBreak(FHiddenBreakpoint);
|
|
||||||
FHiddenBreakpoint.Free;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
Handled := Finished;
|
Handled := Finished;
|
||||||
end;
|
end;
|
||||||
@ -629,30 +624,29 @@ end;
|
|||||||
|
|
||||||
constructor TDbgControllerRunToCmd.Create(AController: TDbgController; ALocation: TDBGPtrArray);
|
constructor TDbgControllerRunToCmd.Create(AController: TDbgController; ALocation: TDBGPtrArray);
|
||||||
begin
|
begin
|
||||||
inherited create(AController);
|
|
||||||
FLocation:=ALocation;
|
FLocation:=ALocation;
|
||||||
|
inherited create(AController);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDbgControllerRunToCmd.DoContinue(AProcess: TDbgProcess; AThread: TDbgThread);
|
procedure TDbgControllerRunToCmd.DoContinue(AProcess: TDbgProcess; AThread: TDbgThread);
|
||||||
begin
|
begin
|
||||||
assert(FProcess=AProcess, 'TDbgControllerRunToCmd.DoContinue: FProcess=AProcess');
|
assert(FProcess=AProcess, 'TDbgControllerRunToCmd.DoContinue: FProcess=AProcess');
|
||||||
if not assigned(FHiddenBreakpoint) then // and not AProcess.HasBreak(FLocation)
|
|
||||||
FHiddenBreakpoint := AProcess.AddInternalBreak(FLocation)
|
|
||||||
else
|
|
||||||
debugln(DBG_WARNINGS, 'TDbgControllerRunToCmd.DoContinue: Breakpoint already used');
|
|
||||||
|
|
||||||
FProcess.Continue(FProcess, FThread, False);
|
FProcess.Continue(FProcess, FThread, False);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TDbgControllerRunToCmd.Init;
|
||||||
|
begin
|
||||||
|
inherited Init;
|
||||||
|
FHiddenBreakpoint := FProcess.AddInternalBreak(FLocation);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TDbgControllerRunToCmd.DoResolveEvent(var AnEvent: TFPDEvent;
|
procedure TDbgControllerRunToCmd.DoResolveEvent(var AnEvent: TFPDEvent;
|
||||||
AnEventThread: TDbgThread; out Handled, Finished: boolean);
|
AnEventThread: TDbgThread; out Handled, Finished: boolean);
|
||||||
begin
|
begin
|
||||||
Finished := (AnEvent<>deInternalContinue);
|
Finished := (AnEvent<>deInternalContinue);
|
||||||
Handled := Finished;
|
Handled := Finished;
|
||||||
if Finished and assigned(FHiddenBreakpoint) then
|
if Finished then begin
|
||||||
begin
|
RemoveHiddenBreak;
|
||||||
FProcess.RemoveBreak(FHiddenBreakpoint);
|
|
||||||
FHiddenBreakpoint.Free;
|
|
||||||
AnEvent := deFinishedStep;
|
AnEvent := deFinishedStep;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user