Пример #1
0
        // Called by the SDM to indicate that a synchronous debug event, previously sent by the DE to the SDM,
        // was received and processed. The only event the sample engine sends in this fashion is Program Destroy.
        // It responds to that event by shutting down the engine.
        int IDebugEngine2.ContinueFromSynchronousEvent(IDebugEvent2 eventObject)
        {
            // Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);

            try
            {
                if (eventObject is AD7ProgramDestroyEvent)
                {
                    //WorkerThread pollThread = m_pollThread;
                    SquirrelProcess _debuggedProcess = debuggedProcess;

                    m_engineCallback = null;
                    debuggedProcess  = null;
                    //m_pollThread = null;
                    m_ad7ProgramId = Guid.Empty;

                    _debuggedProcess.Close();
                    //pollThread.Close();
                }
                else if (eventObject is ErrorEvent)
                {
                    ErrorEvent errorEventObject = eventObject as ErrorEvent;
                    if (errorEventObject != null)
                    {
                        Debug.WriteLine("Debugger received errorevent " + errorEventObject.ErrorMessage + "\n");
                    }

                    return(EngineConstants.E_FAIL);
                    // m_engineCallback.Send(new AD7ProgramDestroyEvent(0), AD7ProgramDestroyEvent.IID, null);
                }
                else
                {
                    Debug.Fail("Debug engine received unknown synchronous event");
                }
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }

            return(EngineConstants.S_OK);
        }
Пример #2
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(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();
                string portname;
                port.GetPortName(out portname);
                m_engineCallback = new EngineCallback(this, ad7Callback);

                XmlDocument doc = new XmlDocument();
                doc.LoadXml(options);
                XmlElement root                      = (XmlElement)doc.ChildNodes[0];
                string     ipaddress                 = root.GetAttribute("targetaddress");
                int        ipport                    = Int32.Parse(root.GetAttribute("port"));
                int        connectiontries           = Int32.Parse(root.GetAttribute("connectiontries"));
                int        connectiondelay           = Int32.Parse(root.GetAttribute("connectiondelay"));
                bool       autoruninterpreter        = Boolean.Parse(root.GetAttribute("autoruninterpreter"));
                bool       suspendonstartup          = Boolean.Parse(root.GetAttribute("suspendonstartup"));
                List <SquirrelDebugFileContext> ctxs = new List <SquirrelDebugFileContext>();
                foreach (XmlElement e in doc.GetElementsByTagName("context"))
                {
                    string rootpath  = e.GetAttribute("rootpath");
                    string pathfixup = e.GetAttribute("pathfixup");
                    SquirrelDebugFileContext sdfc = new SquirrelDebugFileContext(rootpath, pathfixup);
                    ctxs.Add(sdfc);
                }

                // Complete the win32 attach on the poll thread
                //THIS IS A MASSIVE HACK
                //the 'options' parameter is formatted this way "targetaddress,port,autorunintepreter,suspendonstartup,projectfolder,pathfixup"
                //I should find a better way to pass this params

                //fix working dir)
                dir = dir.Replace('/', '\\');
                Process proc = null;
                if (autoruninterpreter)
                {
                    proc = new Process();
                    proc.EnableRaisingEvents       = false;
                    proc.StartInfo.UseShellExecute = false;
                    baseDir = proc.StartInfo.WorkingDirectory = dir;
                    proc.StartInfo.FileName = exe;

                    proc.StartInfo.Arguments = args;
                    proc.StartInfo.RedirectStandardOutput = false;
                    proc.StartInfo.RedirectStandardError  = false;

                    proc.Start();
                }

                AD_PROCESS_ID adProcessId = new AD_PROCESS_ID();

                if (proc != null)
                {
                    adProcessId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM;
                    adProcessId.dwProcessId   = (uint)proc.Id;
                }
                else
                {
                    adProcessId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
                    adProcessId.guidProcessId = Guid.NewGuid();
                }


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

                debuggedProcess                  = (SquirrelProcess)process;
                debuggedProcess.Engine           = this;
                debuggedProcess.Process          = proc;
                debuggedProcess.Name             = proc != null? proc.StartInfo.FileName : "remoteprocess";
                debuggedProcess.EngineCallback   = m_engineCallback;
                debuggedProcess.IpAddress        = ipaddress;
                debuggedProcess.IpPort           = ipport;
                debuggedProcess.SuspendOnStartup = suspendonstartup;
                debuggedProcess.FileContexts     = ctxs.ToArray();
                //debuggedProcess.ConnectionTries = connectiontries;
                //debuggedProcess.ConnectionDelay = connectiondelay;
                //debuggedProcess.PathFixup = pathfixup;
                //debuggedProcess.ProjectFolder = projectfolder;

                /*DebuggedThread thread = new DebuggedThread(1);
                 * DebuggedModule module = new DebuggedModule("the module");
                 *
                 * m_engineCallback.OnModuleLoad(module);
                 * m_engineCallback.OnSymbolSearch(module, "nothing", 0);
                 * m_engineCallback.OnThreadStart(thread);
                 * m_engineCallback.OnLoadComplete(thread);*/

                return(EngineConstants.S_OK);
            }
            catch (ComponentException e)
            {
                return(e.HRESULT);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }