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); }
// During startup these methods are called in this order: // -LaunchSuspended // -ResumeProcess // -Attach - Triggered by Attach int IDebugEngineLaunch2.LaunchSuspended(string aPszServer, IDebugPort2 aPort, string aDebugInfo , string aArgs, string aDir, string aEnv, string aOptions, enum_LAUNCH_FLAGS aLaunchFlags , uint aStdInputHandle, uint aStdOutputHandle, uint hStdError, IDebugEventCallback2 aAD7Callback , out IDebugProcess2 oProcess) { // 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. oProcess = null; try { mEngineCallback = new EngineCallback(this, aAD7Callback); var xDebugInfo = new NameValueCollection(); NameValueCollectionHelper.LoadFromString(xDebugInfo, aDebugInfo); //TODO: In the future we might support command line args for kernel etc //string xCmdLine = EngineUtils.BuildCommandLine(exe, args); //var processLaunchInfo = new ProcessLaunchInfo(exe, xCmdLine, dir, env, options, launchFlags, hStdInput, hStdOutput, hStdError); AD7EngineCreateEvent.Send(this); oProcess = mProcess = new AD7Process(xDebugInfo, mEngineCallback, this, aPort); // We only support one process, so just use its ID for the program ID mProgramID = mProcess.ID; //AD7ThreadCreateEvent.Send(this, xProcess.Thread); mModule = new AD7Module(); mProgNode = new AD7ProgramNode(mProcess.PhysID); } catch (NotSupportedException) { return(VSConstants.S_FALSE); } catch (Exception e) { return(EngineUtils.UnexpectedException(e)); } return(VSConstants.S_OK); }