// 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); // Complete the win32 attach on the poll thread _pollThread.RunOperation(new Operation(delegate { throw new NotImplementedException(); })); _pollThread.PostedOperationErrorEvent += _debuggedProcess.OnPostedOperationError; } else { if (!EngineUtils.ProcIdEquals(processId, _debuggedProcess.Id)) { Debug.Fail("Asked to attach to a process while we are debugging"); return(Constants.E_FAIL); } } AD7EngineCreateEvent.Send(this); AD7ProgramCreateEvent.Send(this); this.ProgramCreateEventSent = true; return(Constants.S_OK); } catch (MIException e) { return(e.HResult); } catch (Exception e) { return(EngineUtils.UnexpectedException(e)); } }
// Attach the debug engine to a program. public int Attach(IDebugProgram2[] portProgramArray, IDebugProgramNode2[] programNodeArray, 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(); } IDebugProgram2 portProgram = portProgramArray[0]; Exception exception = null; try { IDebugProcess2 process; EngineUtils.RequireOk(portProgram.GetProcess(out process)); AD_PROCESS_ID processId = EngineUtils.GetProcessId(process); EngineUtils.RequireOk(portProgram.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) { if (processId.ProcessIdType != (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM) { Debug.Fail("Invalid process to attach to"); throw new ArgumentException(); } IDebugPort2 port; EngineUtils.RequireOk(process.GetPort(out port)); Debug.Assert(_engineCallback == null); Debug.Assert(_debuggedProcess == null); _engineCallback = new EngineCallback(this, ad7Callback); LaunchOptions launchOptions = CreateAttachLaunchOptions(processId.dwProcessId, port); StartDebugging(launchOptions); } else { if (!EngineUtils.ProcIdEquals(processId, _debuggedProcess.Id)) { Debug.Fail("Asked to attach to a process while we are debugging"); return(Constants.E_FAIL); } } AD7EngineCreateEvent.Send(this); AD7ProgramCreateEvent.Send(this); this.ProgramCreateEventSent = true; return(Constants.S_OK); } catch (Exception e) when(ExceptionHelper.BeforeCatch(e, Logger, reportOnlyCorrupting: true)) { exception = e; } // If we just return the exception as an HRESULT, we will lose our message, so we instead send up an error event, and // return that the attach was canceled OnStartDebuggingFailed(exception); return(AD7_HRESULT.E_ATTACH_USER_CANCELED); }
internal static void Send(AD7Engine engine) { AD7ProgramCreateEvent eventObject = new AD7ProgramCreateEvent(); engine.Callback.Send(eventObject, IID, engine, null); }