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);
            }
        }
Exemple #2
0
        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;
            }
        }
Exemple #3
0
        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);
        }
Exemple #4
0
 public void Step(StepType stepType, DebuggerAction nextAction)
 {
     if (_isPaused)
     {
         _executionController.SignalStep(_currentThread, stepType, nextAction);
     }
 }
Exemple #5
0
 public void Continue(DebuggerAction nextAction)
 {
     if (_isPaused)
     {
         _executionController.Continue(_currentThread, nextAction);
     }
 }
Exemple #6
0
        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);
        }
Exemple #7
0
        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);
        }
Exemple #8
0
        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);
            }
        }
Exemple #10
0
        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;
            }
        }
Exemple #11
0
        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);
        }
Exemple #12
0
        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));
            }
        }
Exemple #13
0
        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;
            }
        }
Exemple #14
0
        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);
            }
        }
Exemple #15
0
        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);
        }
Exemple #16
0
        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);
            }
        }
Exemple #17
0
        private void ResetBreakPoints(DebuggerAction action)
        {
            SourceCode src = m_Script.GetSourceCode(action.SourceID);

            ResetBreakPoints(src, new HashSet <int>(action.Lines));
        }
Exemple #18
0
 public void QueueAction(DebuggerAction action)
 {
     m_QueuedActions.Enqueue(action);
 }
Exemple #19
0
        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;
            }
        }
Exemple #20
0
 internal void SignalDebuggerLoop(DebuggerAction nextAction)
 {
     _nextContinueStatus = nextAction.ToContinueStatus();
     _continueEvent.Set();
 }
Exemple #21
0
 private static void SignalStepOut(IDebuggeeThread thread, DebuggerAction nextAction)
 {
     throw new NotSupportedException();
 }