public int Attach(IDebugProgram2[] programs, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason) { var program = programs[0]; IDebugProcess2 process; program.GetProcess(out process); Guid processId; process.GetProcessId(out processId); if (processId != this.processId.guidProcessId) { return(VSConstants.S_FALSE); } EngineUtils.RequireOk(program.GetProgramId(out programId)); Task.Run(() => { waiter.WaitOne(); // connect to the local Mono Debugger or SSH tunnel. var localhost = IPAddress.Parse("127.0.0.1"); Session.Run(new SoftDebuggerStartInfo(new SoftDebuggerConnectArgs("", localhost, MonoDebuggerPort)), new DebuggerSessionOptions { EvaluationOptions = EvaluationOptions.DefaultOptions, ProjectAssembliesOnly = false }); }); MonoEngineCreateEvent.Send(this); MonoProgramCreateEvent.Send(this); return(VSConstants.S_OK); }
public void Attach(IDebugProgram2 program) { IDebugProcess2 process; program.GetProcess(out process); Guid processId; process.GetProcessId(out processId); if (processId != _processId.guidProcessId) { throw new DebuggerInitializeException("Cannot attach to specified program."); } EngineUtils.RequireOk(program.GetProgramId(out _programId)); Task.Run(() => { _waiter.WaitOne(); var ipAddress = new IPAddress(new byte[] { 0x7f, 0x00, 0x00, 0x01 }); Session.Run(new SoftDebuggerStartInfo(new SoftDebuggerConnectArgs("samp-server", ipAddress, DebuggerAddress.Port)), new DebuggerSessionOptions { EvaluationOptions = EvaluationOptions.DefaultOptions, ProjectAssembliesOnly = false }); }); MonoEngineCreateEvent.Send(_engine); SampSharpCreateEvent.Send(_engine); }
public int Attach(IDebugProgram2[] programs, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason) { var program = programs[0]; IDebugProcess2 process; program.GetProcess(out process); Guid processId; process.GetProcessId(out processId); if (processId != this.processId.guidProcessId) { return(VSConstants.S_FALSE); } EngineUtils.RequireOk(program.GetProgramId(out programId)); Task.Run(() => { waiter.WaitOne(); var ipAddress = HostUtils.ResolveHostOrIPAddress(settings.Host); Session.Run(new SoftDebuggerStartInfo(new SoftDebuggerConnectArgs("", ipAddress, 6438)), new DebuggerSessionOptions { EvaluationOptions = EvaluationOptions.DefaultOptions, ProjectAssembliesOnly = false }); }); MonoEngineCreateEvent.Send(this); MonoProgramCreateEvent.Send(this); return(VSConstants.S_OK); }
public void Send(IDebugEvent2 eventObject, string iidEvent, IDebugProgram2 program, IDebugThread2 thread) { uint attributes; Guid riidEvent = new Guid(iidEvent); EngineUtils.RequireOk(eventObject.GetAttributes(out attributes)); EngineUtils.RequireOk(_eventCallback.Event(_engine, null, program, thread, eventObject, ref riidEvent, attributes)); }
// Launches a process by means of the debug engine. // Normally, Visual Studio launches a program using the IDebugPortEx2::LaunchSuspended method and then attaches the debugger // to the suspended program. However, there are circumstances in which the debug engine may need to launch a program // (for example, if the debug engine is part of an interpreter and the program being debugged is an interpreted language), // in which case Visual Studio uses the IDebugEngineLaunch2::LaunchSuspended method // The IDebugEngineLaunch2::ResumeProcess method is called to start the process after the process has been successfully launched in a suspended state. int IDebugEngineLaunch2.LaunchSuspended( string pszServer, IDebugPort2 port, string exe, string args, string dir, string env, string options, enum_LAUNCH_FLAGS launchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 ad7Callback, out IDebugProcess2 process) { Debug.Assert(_pollThread == null); Debug.Assert(_engineCallback == null); Debug.Assert(_debuggedProcess == null); Debug.Assert(_ad7ProgramId == Guid.Empty); process = null; _engineCallback = new EngineCallback(this, ad7Callback); try { // We are being asked to debug a process when we currently aren't debugging anything _pollThread = new WorkerThread(); _pollThread.RunOperation(() => { var endpoint = new IPEndPoint(IPAddress.Parse(args.Split('=')[1]), 8085); _debuggedProcess = new DebuggedProcess(endpoint, _engineCallback, _pollThread, this); _pollThread.PostedOperationErrorEvent += _debuggedProcess.OnPostedOperationError; return(_debuggedProcess.Initialize()); }); EngineUtils.RequireOk(port.GetProcess(_debuggedProcess.Id, out process)); return(VSConstants.S_OK); } catch (Exception e) when(ExceptionHelper.BeforeCatch(e, reportOnlyCorrupting: true)) { // If we just return the exception as an HRESULT, we will loose our message, so we instead send up an error event, and then // return E_ABORT. SendStartDebuggingError(e); } Dispose(); return(VSConstants.E_ABORT); }
public static int GetProcessId(IDebugProcess2 process) { AD_PROCESS_ID[] pid = new AD_PROCESS_ID[1]; EngineUtils.RequireOk(process.GetPhysicalProcessId(pid)); if (pid[0].ProcessIdType != (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM) { return(0); } return((int)pid[0].dwProcessId); }
// Attach the debug engine to a program. int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason) { Debug.Assert(_ad7ProgramId == Guid.Empty); if (celtPrograms != 1) { Debug.Fail("SampleEngine only expects to see one program in a process"); throw new ArgumentException(); } try { AD_PROCESS_ID processId = EngineUtils.GetProcessId(rgpPrograms[0]); EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out _ad7ProgramId)); // Attach can either be called to attach to a new process, or to complete an attach // to a launched process if (_pollThread == null) { // We are being asked to debug a process when we currently aren't debugging anything _pollThread = new WorkerThread(); _engineCallback = new EngineCallback(this, ad7Callback); _pollThread.PostedOperationErrorEvent += _debuggedProcess.OnPostedOperationError; } else { if (!EngineUtils.ProcIdEquals(processId, _debuggedProcess.Id)) { Debug.Fail("Asked to attach to a process while we are debugging"); return(VSConstants.E_FAIL); } } AD7EngineCreateEvent.Send(this); AD7ProgramCreateEvent.Send(this); this.ProgramCreateEventSent = true; return(VSConstants.S_OK); } catch (MIException e) { return(e.HResult); } catch (Exception e) when(ExceptionHelper.BeforeCatch(e, reportOnlyCorrupting: true)) { return(EngineUtils.UnexpectedException(e)); } }
/// <summary> /// Resume a process launched by IDebugEngineLaunch2.LaunchSuspended /// </summary> /// <param name="process"></param> /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns> public int ResumeProcess(IDebugProcess2 process) { IDebugPort2 port; EngineUtils.RequireOk(process.GetPort(out port)); var defaultPort = (IDebugDefaultPort2)port; IDebugPortNotify2 portNotify; EngineUtils.RequireOk(defaultPort.GetPortNotify(out portNotify)); EngineUtils.RequireOk(portNotify.AddProgramNode(Program.Node)); return(S_OK); }
public int ResumeProcess(IDebugProcess2 process) { 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 MonoProgramNode(processId))); return(VSConstants.S_OK); }
// Resume a process launched by IDebugEngineLaunch2.LaunchSuspended int IDebugEngineLaunch2.ResumeProcess(IDebugProcess2 process) { Debug.Assert(_pollThread != null); Debug.Assert(_engineCallback != null); Debug.Assert(_debuggedProcess != null); Debug.Assert(_ad7ProgramId == Guid.Empty); try { AD_PROCESS_ID processId = EngineUtils.GetProcessId(process); if (!EngineUtils.ProcIdEquals(processId, _debuggedProcess.Id)) { 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(_debuggedProcess.Id))); if (_ad7ProgramId == Guid.Empty) { Debug.Fail("Unexpected problem -- IDebugEngine2.Attach wasn't called"); return(VSConstants.E_FAIL); } // NOTE: We wait for the program create event to be continued before we really resume the process return(VSConstants.S_OK); } catch (MIException e) { return(e.HResult); } catch (Exception e) when(ExceptionHelper.BeforeCatch(e, reportOnlyCorrupting: true)) { return(EngineUtils.UnexpectedException(e)); } }
int IDebugEngineLaunch2.ResumeProcess(IDebugProcess2 aProcess) { // Resume a process launched by IDebugEngineLaunch2.LaunchSuspended try { // 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 var xProcess = aProcess as AD7Process; if (xProcess == null) { return(VSConstants.E_INVALIDARG); } IDebugPort2 xPort; EngineUtils.RequireOk(aProcess.GetPort(out xPort)); var xDefPort = (IDebugDefaultPort2)xPort; IDebugPortNotify2 xNotify; EngineUtils.RequireOk(xDefPort.GetPortNotify(out xNotify)); // This triggers Attach EngineUtils.RequireOk(xNotify.AddProgramNode(mProgNode)); Callback.OnModuleLoad(mModule); Callback.OnSymbolSearch(mModule, xProcess.mISO.Replace("iso", "pdb"), enum_MODULE_INFO_FLAGS.MIF_SYMBOLS_LOADED); // Important! // // This call triggers setting of breakpoints that exist before run. // So it must be called before we resume the process. // If not called VS will call it after our 3 startup events, but thats too late. // This line was commented out in earlier Cosmos builds and caused problems with // breakpoints and timing. Callback.OnThreadStart(mThread); // Not sure what this does exactly. It was commented out before // but so was a lot of stuff we actually needed. If its uncommented it // throws: // "Operation is not valid due to the current state of the object." //AD7EntrypointEvent.Send(this); // Now finally release our process to go after breakpoints are set mProcess.ResumeFromLaunch(); } catch (Exception e) { return(EngineUtils.UnexpectedException(e)); } return(VSConstants.S_OK); }
internal void Send(IDebugEvent2 eventObject, string iidEvent, IDebugProgram2 program, IDebugThread2 thread) { uint attributes; var riidEvent = new Guid(iidEvent); EngineUtils.RequireOk(eventObject.GetAttributes(out attributes)); Debug.WriteLine(string.Format("Sending Event: {0} {1}", eventObject.GetType(), iidEvent)); try { EngineUtils.RequireOk(_events.Event(this, null, program, thread, eventObject, ref riidEvent, attributes)); } catch (InvalidCastException) { // COM object has gone away } }
// Resume a process launched by IDebugEngineLaunch2.LaunchSuspended int IDebugEngineLaunch2.ResumeProcess(IDebugProcess2 process) { if (_events == null) { // process failed to start 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)); var 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); } Debug.WriteLine("ResumeProcess return S_OK"); return(VSConstants.S_OK); }
// Launches a process by means of the debug engine. // Normally, Visual Studio launches a program using the IDebugPortEx2::LaunchSuspended method and then attaches the debugger // to the suspended program. However, there are circumstances in which the debug engine may need to launch a program // (for example, if the debug engine is part of an interpreter and the program being debugged is an interpreted language), // in which case Visual Studio uses the IDebugEngineLaunch2::LaunchSuspended method // The IDebugEngineLaunch2::ResumeProcess method is called to start the process after the process has been successfully launched in a suspended state. int IDebugEngineLaunch2.LaunchSuspended(string pszServer, IDebugPort2 port, string exe, string args, string dir, string env, string options, enum_LAUNCH_FLAGS launchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 ad7Callback, out IDebugProcess2 process) { Debug.Assert(_events == null); Debug.Assert(_process == null); Debug.Assert(_ad7ProgramId == Guid.Empty); _events = ad7Callback; List <string[]> dirMapping = null; Guid processId; if (Guid.TryParse(exe, out processId)) { _process = DebugConnectionListener.GetProcess(processId); _attached = true; _pseudoAttach = true; } else { _process = new NodeProcess(exe, args, dir, BreakOnAllExceptions, dirMapping); } _programCreated = false; AttachProcessEvents(_process); _process.Start(); var adProcessId = new AD_PROCESS_ID { ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM, dwProcessId = (uint)_process.Id }; EngineUtils.RequireOk(port.GetProcess(adProcessId, out process)); Debug.WriteLine("NodeEngine LaunchSuspended returning S_OK"); Debug.Assert(process != null); Debug.Assert(!_process.HasExited); return(VSConstants.S_OK); }
public int Attach(IDebugProgram2[] programs, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason) { var program = programs[0]; IDebugProcess2 process; program.GetProcess(out process); Guid processId; process.GetProcessId(out processId); if (processId != this.processId.guidProcessId) { return(VSConstants.S_FALSE); } EngineUtils.RequireOk(program.GetProgramId(out programId)); Session.Run(new SoftDebuggerStartInfo(new SoftDebuggerConnectArgs("", new IPAddress(new byte[] { 192, 168, 137, 3 }), 12345)), new DebuggerSessionOptions { EvaluationOptions = EvaluationOptions.DefaultOptions, ProjectAssembliesOnly = false }); return(VSConstants.S_OK); }
int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint aCeltPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason) { // Attach the debug engine to a program. // // Attach can either be called to attach to a new process, or to complete an attach // to a launched process. // So could we simplify and move code from LaunchSuspended to here and maybe even // eliminate the debughost? Although I supposed DebugHost has some other uses as well. if (aCeltPrograms != 1) { System.Diagnostics.Debug.Fail("Cosmos Debugger only supports one debug target at a time."); throw new ArgumentException(); } try { EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out mProgramID)); mProgram = rgpPrograms[0]; AD7EngineCreateEvent.Send(this); AD7ProgramCreateEvent.Send(this); AD7ModuleLoadEvent.Send(this, mModule, true); // Dummy main thread // We dont support threads yet, but the debugger expects threads. // So we create a dummy object to represente our only "thread". mThread = new AD7Thread(this, mProcess); AD7LoadCompleteEvent.Send(this, mThread); } catch (Exception e) { return(EngineUtils.UnexpectedException(e)); } return(VSConstants.S_OK); }
// Attach the debug engine to a program. int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason) { Debug.Assert(_ad7ProgramId == Guid.Empty); if (celtPrograms != 1) { Debug.Fail("Node debugging only supports one program in a process"); throw new ArgumentException(); } IDebugProgram2 program = rgpPrograms[0]; int processId = EngineUtils.GetProcessId(program); if (processId == 0) { // engine only supports system processes Debug.WriteLine("NodeEngine failed to get process id during attach"); return(VSConstants.E_NOTIMPL); } EngineUtils.RequireOk(program.GetProgramId(out _ad7ProgramId)); // Attach can either be called to attach to a new process, or to complete an attach // to a launched process if (_process == null) { // TODO: Where do we get the language version from? _events = ad7Callback; // Check if we're attaching remotely using the node remote debugging transport if (!NodeProcess.TryAttach(processId, out _process)) { MessageBox.Show("Failed to attach debugger:\n", null, MessageBoxButtons.OK, MessageBoxIcon.Error); return(VSConstants.E_FAIL); } AttachProcessEvents(_process); _attached = true; } else { if (processId != _process.Id) { Debug.Fail("Asked to attach to a process while we are debugging"); return(VSConstants.E_FAIL); } } AD7EngineCreateEvent.Send(this); lock (_syncLock) { _programCreated = true; if (_processLoadedThread != null) { SendLoadComplete(_processLoadedThread); } } Debug.WriteLine("NodeEngine Attach returning S_OK"); return(VSConstants.S_OK); }