示例#1
0
        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(m_ad7Callback.Event(m_engine, null, program, thread, eventObject, ref riidEvent, attributes));
        }
示例#2
0
        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);
        }
示例#3
0
        // Resume a process launched by IDebugEngineLaunch2.LaunchSuspended
        int IDebugEngineLaunch2.ResumeProcess(IDebugProcess2 process)
        {
            Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
            Debug.Assert(m_pollThread != null);
            Debug.Assert(m_engineCallback != null);
            Debug.Assert(m_debuggedProcess != null);
            Debug.Assert(m_ad7ProgramId == Guid.Empty);

            try
            {
                int processId = EngineUtils.GetProcessId(process);

                if (processId != m_debuggedProcess.Id)
                {
                    return(Constants.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(m_debuggedProcess.Id)));

                if (m_ad7ProgramId == Guid.Empty)
                {
                    Debug.Fail("Unexpected problem -- IDebugEngine2.Attach wasn't called");
                    return(Constants.E_FAIL);
                }

                // Resume the threads in the debuggee process
                m_pollThread.RunOperation(new Operation(delegate
                {
                    m_debuggedProcess.ResumeFromLaunch();
                }));

                return(Constants.S_OK);
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#4
0
        // 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(Worker.MainThreadId == Worker.CurrentThreadId);
            Debug.Assert(m_pollThread == null);
            Debug.Assert(m_engineCallback == null);
            Debug.Assert(m_debuggedProcess == null);
            Debug.Assert(m_ad7ProgramId == Guid.Empty);

            process = null;

            try
            {
                string commandLine = EngineUtils.BuildCommandLine(exe, args);

                ProcessLaunchInfo processLaunchInfo = new ProcessLaunchInfo(exe, commandLine, dir, env, options, (uint)launchFlags, hStdInput, hStdOutput, hStdError);

                // We are being asked to debug a process when we currently aren't debugging anything
                m_pollThread = new WorkerThread();

                m_engineCallback = new EngineCallback(this, ad7Callback);

                // Complete the win32 attach on the poll thread
                m_pollThread.RunOperation(new Operation(delegate
                {
                    m_debuggedProcess = Worker.LaunchProcess(m_engineCallback, processLaunchInfo);
                }));

                AD_PROCESS_ID adProcessId = new AD_PROCESS_ID();
                adProcessId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM;
                adProcessId.dwProcessId   = (uint)m_debuggedProcess.Id;

                EngineUtils.RequireOk(port.GetProcess(adProcessId, out process));

                return(Constants.S_OK);
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#5
0
        // Attach the debug engine to a program.
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
            Debug.Assert(m_ad7ProgramId == Guid.Empty);

            if (celtPrograms != 1)
            {
                Debug.Fail("SampleEngine only expects to see one program in a process");
                throw new ArgumentException();
            }

            try
            {
                int processId = EngineUtils.GetProcessId(rgpPrograms[0]);
                if (processId == 0)
                {
                    return(Constants.E_NOTIMPL); // sample engine only supports system processes
                }

                EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out m_ad7ProgramId));

                // Attach can either be called to attach to a new process, or to complete an attach
                // to a launched process
                if (m_pollThread == null)
                {
                    // We are being asked to debug a process when we currently aren't debugging anything
                    m_pollThread = new WorkerThread();

                    m_engineCallback = new EngineCallback(this, ad7Callback);

                    // Complete the win32 attach on the poll thread
                    m_pollThread.RunOperation(new Operation(delegate
                    {
                        m_debuggedProcess = Worker.AttachToProcess(m_engineCallback, processId);
                    }));

                    m_pollThread.SetDebugProcess(m_debuggedProcess);
                }
                else
                {
                    if (processId != m_debuggedProcess.Id)
                    {
                        Debug.Fail("Asked to attach to a process while we are debugging");
                        return(Constants.E_FAIL);
                    }

                    m_pollThread.SetDebugProcess(m_debuggedProcess);
                }

                AD7EngineCreateEvent.Send(this);
                AD7ProgramCreateEvent.Send(this);

                // start polling for debug events on the poll thread
                m_pollThread.RunOperationAsync(new Operation(delegate
                {
                    m_debuggedProcess.ResumeEventPump();
                }));

                return(Constants.S_OK);
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }