diff --git a/components/fpdebug/fpdbgclasses.pp b/components/fpdebug/fpdbgclasses.pp index d57e872bbb..3a1036c151 100644 --- a/components/fpdebug/fpdbgclasses.pp +++ b/components/fpdebug/fpdbgclasses.pp @@ -103,11 +103,17 @@ type FID: Integer; FHandle: THandle; FSingleStepping: Boolean; + FStepping: Boolean; function GetRegisterValueList: TDbgRegisterValueList; protected FRegisterValueListValid: boolean; FRegisterValueList: TDbgRegisterValueList; + FStoreStepSrcFilename: string; + FStoreStepSrcLineNo: integer; + FStoreStepStackFrame: TDBGPtr; + FStoreStepFuncAddr: TDBGPtr; FHiddenBreakpoint: TDbgBreakpoint; + procedure StoreStepInfo; procedure LoadRegisterValues; virtual; public constructor Create(const AProcess: TDbgProcess; const AID: Integer; const AHandle: THandle); virtual; @@ -116,9 +122,12 @@ type destructor Destroy; override; function SingleStep: Boolean; virtual; function StepOver: Boolean; virtual; + function Next: Boolean; virtual; + function CompareStepInfo: boolean; property ID: Integer read FID; property Handle: THandle read FHandle; property SingleStepping: boolean read FSingleStepping write FSingleStepping; + property Stepping: boolean read FStepping write FStepping; property RegisterValueList: TDbgRegisterValueList read GetRegisterValueList; property HiddenBreakpoint: TDbgBreakpoint read FHiddenBreakpoint; end; @@ -743,6 +752,40 @@ begin result := FRegisterValueList; end; +function TDbgThread.CompareStepInfo: boolean; +var + AnAddr: TDBGPtr; + Sym: TFpDbgSymbol; +begin + AnAddr := FProcess.GetInstructionPointerRegisterValue; + sym := FProcess.FindSymbol(AnAddr); + if assigned(sym) then + begin + result := (FStoreStepSrcFilename=sym.FileName) and (FStoreStepSrcLineNo=sym.Line) and + (FStoreStepFuncAddr=sym.Address.Address); + end + else + result := true; +end; + +procedure TDbgThread.StoreStepInfo; +var + AnAddr: TDBGPtr; + Sym: TFpDbgSymbol; +begin + FStoreStepStackFrame := FProcess.GetStackBasePointerRegisterValue; + AnAddr := FProcess.GetInstructionPointerRegisterValue; + sym := FProcess.FindSymbol(AnAddr); + if assigned(sym) then + begin + FStoreStepSrcFilename:=sym.FileName; + FStoreStepSrcLineNo:=sym.Line; + FStoreStepFuncAddr:=sym.Address.Address; + end + else + FStoreStepSrcLineNo:=-1; +end; + procedure TDbgThread.LoadRegisterValues; begin // Do nothing @@ -786,8 +829,6 @@ var CallInstr: boolean; begin - Result := False; - CallInstr:=false; if FProcess.ReadData(FProcess.GetInstructionPointerRegisterValue,sizeof(CodeBin),CodeBin) then begin @@ -803,6 +844,15 @@ begin end else SingleStep; + + Result := True; +end; + +function TDbgThread.Next: Boolean; +begin + result := StepOver; + StoreStepInfo; + FStepping:=result; end; { TDbgBreak } diff --git a/components/fpdebug/fpdbgcontroller.pas b/components/fpdebug/fpdbgcontroller.pas index efd8251143..5f14c00188 100644 --- a/components/fpdebug/fpdbgcontroller.pas +++ b/components/fpdebug/fpdbgcontroller.pas @@ -50,6 +50,7 @@ type procedure Stop; procedure StepIntoInstr; procedure StepOverInstr; + procedure Next; procedure ProcessLoop; procedure SendEvents(out continue: boolean); @@ -141,6 +142,11 @@ begin FCurrentThread.StepOver; end; +procedure TDbgController.Next; +begin + FCurrentThread.Next; +end; + procedure TDbgController.ProcessLoop; var @@ -179,6 +185,8 @@ begin if assigned(FCurrentThread) then begin FCurrentThread.SingleStepping:=false; + if FPDEvent<>deInternalContinue then + FCurrentThread.Stepping := False; if assigned(FCurrentThread.HiddenBreakpoint) then FCurrentThread.ClearHiddenBreakpoint; end; @@ -213,6 +221,11 @@ begin begin debugln('Reached breakpoint at %s.',[FormatAddress(FCurrentProcess.GetInstructionPointerRegisterValue)]); end; + deInternalContinue : + begin + if FCurrentThread.Stepping then + FCurrentThread.Next; + end; end; {case} AExit:=true; until AExit; diff --git a/components/fpdebug/fpdbgwinclasses.pas b/components/fpdebug/fpdbgwinclasses.pas index 7e6894bc93..efcf2b3d81 100644 --- a/components/fpdebug/fpdbgwinclasses.pas +++ b/components/fpdebug/fpdbgwinclasses.pas @@ -748,7 +748,10 @@ begin result := deBreakpoint else if assigned(AThread) and assigned(AThread.HiddenBreakpoint) then begin AThread.HiddenBreakpoint.Hit(AThread.ID); - result := deBreakpoint; + if AThread.Stepping and AThread.CompareStepInfo then + result := deInternalContinue + else + result := deBreakpoint; end else begin // Unknown breakpoint. @@ -775,6 +778,14 @@ begin else result := deBreakpoint; + if AThread.Stepping then + begin + if AThread.CompareStepInfo then + result := deInternalContinue + else + result := deBreakpoint; + end; + // If there is a breakpoint on this location, handle the breakpoint. // Or else the int3-interrupt instruction won't be cleared and the // breakpoint will be triggered again. (Notice that the location of diff --git a/components/lazdebuggers/lazdebuggerfp/fpdebugdebugger.pas b/components/lazdebuggers/lazdebuggerfp/fpdebugdebugger.pas index de1b655d20..b60bd1d9f0 100644 --- a/components/lazdebuggers/lazdebuggerfp/fpdebugdebugger.pas +++ b/components/lazdebuggers/lazdebuggerfp/fpdebugdebugger.pas @@ -600,6 +600,13 @@ begin StartDebugLoop; result := true; end; + dcStepOver: + begin + FDbgController.Next; + SetState(dsRun); + StartDebugLoop; + result := true; + end; end; {case} end; @@ -700,7 +707,7 @@ end; function TFpDebugDebugger.GetSupportedCommands: TDBGCommands; begin - Result:=[dcRun, dcStop, dcStepIntoInstr, dcStepOverInstr]; + Result:=[dcRun, dcStop, dcStepIntoInstr, dcStepOverInstr, dcStepOver]; end; end.