// Resume a process launched by IDebugEngineLaunch2.LaunchSuspended int IDebugEngineLaunch2.ResumeProcess(IDebugProcess2 process) { Debug.WriteLine("Python Debugger ResumeProcess Begin"); AssertMainThread(); if (_events == null) { // process failed to start Debug.WriteLine("ResumeProcess fails, no events"); return(VSConstants.E_FAIL); } Debug.Assert(_events != null); Debug.Assert(_process != null); Debug.Assert(_process != null); Debug.Assert(_ad7ProgramId == Guid.Empty); int processId = EngineUtils.GetProcessId(process); if (processId != _process.Id) { Debug.WriteLine("ResumeProcess fails, wrong process"); return(VSConstants.S_FALSE); } // Send a program node to the SDM. This will cause the SDM to turn around and call IDebugEngine2.Attach // which will complete the hookup with AD7 IDebugPort2 port; EngineUtils.RequireOk(process.GetPort(out port)); IDebugDefaultPort2 defaultPort = (IDebugDefaultPort2)port; IDebugPortNotify2 portNotify; EngineUtils.RequireOk(defaultPort.GetPortNotify(out portNotify)); EngineUtils.RequireOk(portNotify.AddProgramNode(new AD7ProgramNode(_process.Id))); if (_ad7ProgramId == Guid.Empty) { Debug.WriteLine("ResumeProcess fails, empty program guid"); Debug.Fail("Unexpected problem -- IDebugEngine2.Attach wasn't called"); return(VSConstants.E_FAIL); } // wait for the load event to complete, and pump messages while (!_process.HasExited && !_loadComplete.WaitOne(100)) { Debug.WriteLine("ResumeProcess waiting for load complete"); } // Resume the threads in the debuggee process if (_process.HasExited) { Debug.WriteLine("ResumeProcess resume all"); _process.Resume(); } else { // return failure? Debug.WriteLine("Process exited"); } Debug.WriteLine("ResumeProcess return S_OK"); return(VSConstants.S_OK); }
public void AttachPtvsd() { var expectedOutput = new[] { "stdout", "stderr" }; string script = TestData.GetPath(@"TestData\DebuggerProject\AttachPtvsd.py"); var psi = new ProcessStartInfo(Version.InterpreterPath, PtvsdInterpreterArguments + " \"" + script + "\"") { WorkingDirectory = TestData.GetPath(), UseShellExecute = false }; var p = Process.Start(psi); try { PythonProcess proc = null; for (int i = 0; ; ++i) { Thread.Sleep(1000); try { proc = PythonRemoteProcess.Attach( new Uri("tcp://secret@localhost?opt=" + PythonDebugOptions.RedirectOutput), warnAboutAuthenticationErrors: false); break; } catch (SocketException) { // Failed to connect - the process might have not started yet, so keep trying a few more times. if (i >= 5) { throw; } } } try { var attached = new AutoResetEvent(false); proc.ProcessLoaded += (sender, e) => { Console.WriteLine("Process loaded"); var bp = proc.AddBreakPoint(script, 10); bp.Add(); proc.Resume(); attached.Set(); }; var actualOutput = new List <string>(); proc.DebuggerOutput += (sender, e) => { actualOutput.Add(e.Output); }; var bpHit = new AutoResetEvent(false); proc.BreakpointHit += (sender, args) => { Console.WriteLine("Breakpoint hit"); bpHit.Set(); proc.Continue(); }; proc.StartListening(); Assert.IsTrue(attached.WaitOne(20000), "Failed to attach within 20s"); Assert.IsTrue(bpHit.WaitOne(20000), "Failed to hit breakpoint within 20s"); p.WaitForExit(DefaultWaitForExitTimeout); AssertUtil.ArrayEquals(expectedOutput, actualOutput); } finally { DetachProcess(proc); } } finally { DisposeProcess(p); } }