// Continue is called from the SDM when it wants execution to continue in the debugee // but have stepping state remain. An example is when a tracepoint is executed, // and the debugger does not want to actually enter break mode. public int Continue(IDebugThread2 pThread) { // VS Code currently isn't providing a thread Id in certain cases. Work around this by handling null values. AD7Thread thread = pThread as AD7Thread; try { if (_pollThread.IsPollThread()) { _debuggedProcess.Continue(thread?.GetDebuggedThread()); } else { _pollThread.RunOperation(() => _debuggedProcess.Continue(thread?.GetDebuggedThread())); } } catch (InvalidCoreDumpOperationException) { return(AD7_HRESULT.E_CRASHDUMP_UNSUPPORTED); } catch (Exception e) { _engineCallback.OnError(EngineUtils.GetExceptionDescription(e)); return(Constants.E_ABORT); } return(Constants.S_OK); }
// Continue is called from the SDM when it wants execution to continue in the debugee // but have stepping state remain. An example is when a tracepoint is executed, // and the debugger does not want to actually enter break mode. public int Continue(IDebugThread2 pThread) { // VS Code currently isn't providing a thread Id in certain cases. Work around this by handling null values. AD7Thread thread = pThread as AD7Thread; if (_pollThread.IsPollThread()) { _debuggedProcess.Continue(thread?.GetDebuggedThread()); } else { _pollThread.RunOperation(() => _debuggedProcess.Continue(thread?.GetDebuggedThread())); } return(Constants.S_OK); }
// Continue is called from the SDM when it wants execution to continue in the debugee // but have stepping state remain. An example is when a tracepoint is executed, // and the debugger does not want to actually enter break mode. public int Continue(IDebugThread2 pThread) { AD7Thread thread = (AD7Thread)pThread; _pollThread.RunOperation(() => _debuggedProcess.Continue(thread.GetDebuggedThread())); return(Constants.S_OK); }
public async Task <bool> Stopped(Results results, int tid) { string reason = results.TryFindString("reason"); ThreadProgress s = StateFromTid(tid); if (reason == "fork") { s = new ThreadProgress(); s.State = State.AtFork; s.Newpid = results.FindInt("newpid"); _threadStates[tid] = s; await _process.Step(tid, VisualStudio.Debugger.Interop.enum_STEPKIND.STEP_OUT, VisualStudio.Debugger.Interop.enum_STEPUNIT.STEP_LINE); return(true); } else if (reason == "vfork") { s = new ThreadProgress(); s.State = State.AtVfork; s.Newpid = results.FindInt("newpid"); _threadStates[tid] = s; await _process.MICommandFactory.SetOption("schedule-multiple", "on"); await _process.MICommandFactory.Catch("exec", onlyOnce : true); var thread = await _process.ThreadCache.GetThread(tid); await _process.Continue(thread); return(true); } if (s == null) { return(false); // no activity being tracked on this thread } switch (s.State) { case State.AtFork: await ProcessChild(s); break; case State.AtVfork: await _process.MICommandFactory.SetOption("schedule-multiple", "off"); if ("exec" == results.TryFindString("reason")) { // The process doesn't handle the SIGSTOP correctly (just ignores it) when the process is at the start of program // (after exec). Let it run some code so that it will correctly respond to the SIGSTOP. s.Exe = results.TryFindString("new-exec"); await RunChildToMain(s); } else { // sometimes gdb misses the breakpoint at exec and execution will proceed to a breakpoint in the child _process.Logger.WriteLine("Missed catching the exec after vfork. Spawning the child's debugger."); s.State = State.AtExec; goto missedExec; } break; case State.AtSignal: // both child and parent are stopped s.State = State.Complete; return(await DetachAndContinue(s)); case State.AtExec: missedExec: if (tid == s.Newtid) // stopped in the child { await ProcessChild(s); } else // sometime the parent will get a spurious signal before the child hits main { await ContinueTheChild(s); } break; case State.Complete: _threadStates.Remove(tid); if (reason == "signal-received" && results.TryFindString("signal-name") == "SIGSTOP") { // SIGSTOP was propagated to the parent await _process.MICommandFactory.Signal("SIGCONT"); return(true); } return(false); default: return(false); } return(true); }