DebuggerAction IDebugger.GetAction(int ip, SourceRef sourceref) { PauseRequested = false; lock (m_Lock) if (Client != null) { Client.SendStopEvent(); } while (true) { lock (m_Lock) { if (Client == null) { return(new DebuggerAction() { Action = DebuggerAction.ActionType.Run }); } if (m_PendingAction != null) { var action = m_PendingAction; m_PendingAction = null; return(action); } } Sleep(10); } }
private void SignalStepOver(DebuggeeThread thread, DebuggerAction nextAction) { // Stepping over means step one instruction, but skip call instructions. // Therefore, if the current instruction is a call, we set a temporary breakpoint // to the next instruction and continue execution, otherwise we perform a normal step. var threadContext = thread.GetThreadContext(); var eip = (uint)threadContext.GetRegisterByName("eip").Value; var info = _disassemblers[thread.Process]; info.Reader.Position = eip; var instruction = info.Disassembler.ReadNextInstruction(); switch (instruction.Mnemonic) { case X86Mnemonic.Call: case X86Mnemonic.Call_Far: _stepOverBreakpoint = new Int3Breakpoint(thread.Process, (IntPtr)info.Reader.Position, true); _session.SignalDebuggerLoop(nextAction); break; default: SignalStepIn(thread, nextAction); break; } }
private void SignalStepIn(DebuggeeThread thread, DebuggerAction nextAction) { // Set trap flag to signal an EXCEPTION_SINGLE_STEP event after next instruction. PrepareContextForSingleStep(thread); _session.SignalDebuggerLoop(nextAction); }
public void Step(StepType stepType, DebuggerAction nextAction) { if (_isPaused) { _executionController.SignalStep(_currentThread, stepType, nextAction); } }
public void Continue(DebuggerAction nextAction) { if (_isPaused) { _executionController.Continue(_currentThread, nextAction); } }
public bool HandleStepEvent(DEBUG_EVENT debugEvent, out DebuggerAction nextAction) { var thread = _session.GetProcessById((int)debugEvent.dwProcessId) .GetThreadById((int)debugEvent.dwThreadId); nextAction = FinalizeStep(thread); return(true); }
public bool HandlePageGuardViolationEvent(DEBUG_EVENT debugEvent, out DebuggerAction nextAction) { // Memory breakpoints are implemented using page guards. We need to check if the page guard // violation originated from a breakpoint or not, and pause or continue execution when appropriate. const int ExceptionInformationReadWrite = 0; const int ExceptionInformationAddress = 1; var info = debugEvent.InterpretDebugInfoAs <EXCEPTION_DEBUG_INFO>(); var process = _session.GetProcessById((int)debugEvent.dwProcessId); var thread = process.GetThreadById((int)debugEvent.dwThreadId); if (info.ExceptionRecord.NumberParameters >= 2) { bool isWrite = info.ExceptionRecord.ExceptionInformation[ExceptionInformationReadWrite] == 1; IntPtr address = (IntPtr)info.ExceptionRecord.ExceptionInformation[ExceptionInformationAddress]; var pageGuard = process.GetContainingPageGuard(address); if (pageGuard != null) { // Restore page guard after continuing. _pageGuardsToRestore.Add(pageGuard); if (pageGuard.Breakpoints.TryGetValue(address, out var breakpoint) && (breakpoint.BreakOnRead == !isWrite || breakpoint.BreakOnWrite == isWrite)) { // Violation originated from a breakpoint. var eventArgs = new BreakpointEventArgs(thread, breakpoint) { NextAction = DebuggerAction.Stop }; breakpoint.HandleBreakpointEvent(eventArgs); OnBreakpointHit(eventArgs); nextAction = eventArgs.NextAction; } else { // Violation did not originate from a breakpoint. _isRestoringFromGuard = true; PrepareContextForSingleStep(thread); nextAction = DebuggerAction.Continue; } return(true); } } nextAction = DebuggerAction.ContinueWithException; return(false); }
public void Continue(DebuggeeThread thread, DebuggerAction nextAction) { _isContinuing = true; _continueAction = nextAction; if (HasBreakpointsToRestore) { SignalStep(thread, StepType.StepIn, nextAction); } else { _session.SignalDebuggerLoop(FinalizeContinue(thread)); } }
public void QueueAction(DebuggerAction action) { while (true) { lock (m_Lock) if (m_PendingAction == null) { m_PendingAction = action; break; } Sleep(10); } }
void DebugAction(DebuggerAction action) { bool savedState = timerFollow.Enabled; timerFollow.Enabled = false; m_NextAction = action; m_WaitLock.Set(); if (!m_WaitBack.WaitOne(1000)) { MessageBox.Show(this, "Operation timed out", "Timeout"); } else { timerFollow.Enabled = savedState; } }
DebuggerAction IDebugger.GetAction(int ip, SourceRef sourceCodeRef) { m_Ctx.Post(o => { codeView.ActiveLine = ip; RefreshCodeView(sourceCodeRef); }, null); m_WaitLock.WaitOne(); DebuggerAction action = m_NextAction; m_NextAction = null; m_WaitBack.Set(); return(action); }
public static ContinueStatus ToContinueStatus(this DebuggerAction nextAction) { switch (nextAction) { case DebuggerAction.Continue: return(ContinueStatus.DBG_CONTINUE); break; case DebuggerAction.ContinueWithException: return(ContinueStatus.DBG_EXCEPTION_NOT_HANDLED); break; default: throw new ArgumentOutOfRangeException(nameof(nextAction)); } }
private void HandleNextAction(DebuggerAction nextAction, DEBUG_EVENT nextEvent) { switch (nextAction) { case DebuggerAction.Continue: _nextContinueStatus = ContinueStatus.DBG_CONTINUE; break; case DebuggerAction.ContinueWithException: _nextContinueStatus = ContinueStatus.DBG_EXCEPTION_NOT_HANDLED; break; case DebuggerAction.Stop: var process = GetProcessById((int)nextEvent.dwProcessId); var thread = process.GetThreadById((int)nextEvent.dwThreadId) ?? new DebuggeeThread(process, IntPtr.Zero, (int)nextEvent.dwThreadId, IntPtr.Zero); var eventArgs = new DebuggeeThreadEventArgs(thread); eventArgs.NextAction = DebuggerAction.Stop; OnPaused(eventArgs); switch (eventArgs.NextAction) { case DebuggerAction.Continue: _nextContinueStatus = ContinueStatus.DBG_CONTINUE; break; case DebuggerAction.ContinueWithException: _nextContinueStatus = ContinueStatus.DBG_EXCEPTION_NOT_HANDLED; break; case DebuggerAction.Stop: _continueEvent.WaitOne(); break; default: throw new ArgumentOutOfRangeException(); } break; } }
public void SignalStep(DebuggeeThread thread, StepType stepType, DebuggerAction nextAction) { _isStepping = true; switch (stepType) { case StepType.StepIn: SignalStepIn(thread, nextAction); break; case StepType.StepOver: SignalStepOver(thread, nextAction); break; case StepType.StepOut: SignalStepOut(thread, nextAction); break; default: throw new ArgumentOutOfRangeException(nameof(stepType), stepType, null); } }
public bool HandleBreakpointEvent(DEBUG_EVENT debugEvent, out DebuggerAction nextAction) { // If signalled by an int3, the exception was thrown after the execution of int3. // Find corresponding breakpoint and restore the instruction pointer so that it seems // it has paused execution before the int3. var process = _session.GetProcessById((int)debugEvent.dwProcessId); var thread = process.GetThreadById((int)debugEvent.dwThreadId); uint eip = (uint)thread.GetThreadContext().GetRegisterByName("eip").Value - 1; var breakpoint = process.GetSoftwareBreakpointByAddress((IntPtr)eip); // Check if breakpoint originated from a step-over action. if (breakpoint == null && _stepOverBreakpoint?.Address == (IntPtr)eip) { _stepOverBreakpoint.HandleBreakpointEvent(new BreakpointEventArgs(thread, _stepOverBreakpoint)); _stepOverBreakpoint = null; nextAction = FinalizeStep(thread); return(true); } if (breakpoint != null) { _breakpointsToRestore.Add(breakpoint); var eventArgs = new BreakpointEventArgs(thread, breakpoint) { NextAction = DebuggerAction.Stop }; breakpoint.HandleBreakpointEvent(eventArgs); OnBreakpointHit(eventArgs); nextAction = eventArgs.NextAction; return(true); } nextAction = DebuggerAction.ContinueWithException; return(false); }
private bool ToggleBreakPoint(DebuggerAction action, bool?state) { SourceCode src = m_Script.GetSourceCode(action.SourceID); bool found = false; foreach (SourceRef srf in src.Refs) { if (srf.CannotBreakpoint) { continue; } if (srf.IncludesLocation(action.SourceID, action.SourceLine, action.SourceCol)) { found = true; //System.Diagnostics.Debug.WriteLine(string.Format("BRK: found {0} for {1} on contains", srf, srf.Type)); if (state == null) { srf.Breakpoint = !srf.Breakpoint; } else { srf.Breakpoint = state.Value; } if (srf.Breakpoint) { m_Debug.BreakPoints.Add(srf); } else { m_Debug.BreakPoints.Remove(srf); } } } if (!found) { int minDistance = int.MaxValue; SourceRef nearest = null; foreach (SourceRef srf in src.Refs) { if (srf.CannotBreakpoint) { continue; } int dist = srf.GetLocationDistance(action.SourceID, action.SourceLine, action.SourceCol); if (dist < minDistance) { minDistance = dist; nearest = srf; } } if (nearest != null) { //System.Diagnostics.Debug.WriteLine(string.Format("BRK: found {0} for {1} on distance {2}", nearest, nearest.Type, minDistance)); if (state == null) { nearest.Breakpoint = !nearest.Breakpoint; } else { nearest.Breakpoint = state.Value; } if (nearest.Breakpoint) { m_Debug.BreakPoints.Add(nearest); } else { m_Debug.BreakPoints.Remove(nearest); } return(true); } else { return(false); } } else { return(true); } }
private void ResetBreakPoints(DebuggerAction action) { SourceCode src = m_Script.GetSourceCode(action.SourceID); ResetBreakPoints(src, new HashSet <int>(action.Lines)); }
public void QueueAction(DebuggerAction action) { m_QueuedActions.Enqueue(action); }
public DebuggerAction GetAction(int ip, SourceRef sourceref) { try { if (m_FreeRunAfterAttach) { m_FreeRunAfterAttach = false; return(new DebuggerAction() { Action = DebuggerAction.ActionType.Run }); } m_InGetActionLoop = true; m_RequestPause = false; if (m_HostBusySent) { m_HostBusySent = false; SendMessage("Host ready!"); } if (sourceref != m_LastSentSourceRef) { Send(xw => { SendSourceRef(xw, sourceref); }); } while (true) { DebuggerAction da = m_QueuedActions.Dequeue(); if (da.Action == DebuggerAction.ActionType.Refresh || da.Action == DebuggerAction.ActionType.HardRefresh) { lock (m_Lock) { HashSet <string> existing = new HashSet <string>(); // remove all not present anymore m_Watches.RemoveAll(de => !m_WatchesChanging.Contains(de.ExpressionCode)); // add all missing existing.UnionWith(m_Watches.Select(de => de.ExpressionCode)); m_Watches.AddRange(m_WatchesChanging .Where(code => !existing.Contains(code)) .Select(code => CreateDynExpr(code))); } return(da); } if (da.Action == DebuggerAction.ActionType.ToggleBreakpoint || da.Action == DebuggerAction.ActionType.SetBreakpoint || da.Action == DebuggerAction.ActionType.ClearBreakpoint) { return(da); } if (da.Age < TimeSpan.FromMilliseconds(100)) { return(da); } } } finally { m_InGetActionLoop = false; } }
internal void SignalDebuggerLoop(DebuggerAction nextAction) { _nextContinueStatus = nextAction.ToContinueStatus(); _continueEvent.Set(); }
private static void SignalStepOut(IDebuggeeThread thread, DebuggerAction nextAction) { throw new NotSupportedException(); }