/// <summary> /// Executes until the currently executed method's point of return has been reached. /// </summary> public void StepOut(DebugThread th) { var returnPtr = APIIntermediate.Read<IntPtr>(th.OwnerProcess.Handle, new IntPtr( th.Context.lastReadCtxt.ebp + 4)); var tempBreakPoint = Breakpoints.ByAddress(returnPtr); bool keepBpAfterStepComplete = false; if (keepBpAfterStepComplete = tempBreakPoint == null) tempBreakPoint = Breakpoints.CreateBreakpoint(returnPtr); th.ContinueDebugging(); Debuggee.WaitForDebugEvent(); if (!keepBpAfterStepComplete) Breakpoints.Remove(tempBreakPoint); }
/// <summary> /// See <see cref="StepIn"/>. /// If there's a call as next instruction, it'll be skipped. /// </summary> public void StepOver(DebugThread th) { var code = APIIntermediate.ReadArray<byte>(th.OwnerProcess.Handle, th.CurrentInstruction, DisAsm86.MaximumInstructionLength); int instructionLength = 0; var instrType = DisAsm86.GetInstructionType(code, false, out instructionLength); /* * If there's a call, set a breakpoint right after the call to skip the called subroutine */ if (instrType == InstructionType.Call) { var bpAddr = IntPtr.Add(th.CurrentInstruction, instructionLength); var tempBreakPoint = Breakpoints.ByAddress(bpAddr); bool keepBpAfterStepComplete = false; if (keepBpAfterStepComplete = tempBreakPoint == null) tempBreakPoint = Breakpoints.CreateBreakpoint(bpAddr); th.ContinueDebugging(); Debuggee.WaitForDebugEvent(); if (!keepBpAfterStepComplete) Breakpoints.Remove(tempBreakPoint); } else StepIn(th); }
/// <summary> /// Executes the next single code instruction. /// Returns false if the single step could be executed but wasn't completed due to a breakpoint or an other exception/debug event. /// </summary> bool StepToNextInstruction(DebugThread th) { if (!Debuggee.IsAlive) return false; if (lastUnhandledBreakpoint != null) SkipAndRestoreLastBreakpoint(false); bool lastStepState = th.Context.TrapFlagSet; if (!lastStepState) th.Context.TrapFlagSet = true; th.ContinueDebugging(); expectsSingleStep = true; Debuggee.WaitForDebugEvent(); //TODO: What if there's a non-ss exception? // Answer: return false if (!lastStepState) th.Context.TrapFlagSet = false; return !expectsSingleStep; }