Exemplo n.º 1
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) {
            LiveLogger.WriteLine("AD7Engine LaunchSuspended Called with flags '{0}' ({1})", launchFlags, GetHashCode());
            AssertMainThread();

            Debug.Assert(_events == null);
            Debug.Assert(_process == null);
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            _events = ad7Callback;

            var debugOptions = NodeDebugOptions.None;
            List<string[]> dirMapping = null;
            string interpreterOptions = null;
            ushort? debugPort = null;
            if (options != null) {
                var splitOptions = SplitOptions(options);

                foreach (var optionSetting in splitOptions) {
                    var setting = optionSetting.Split(new[] { '=' }, 2);

                    if (setting.Length == 2) {
                        setting[1] = HttpUtility.UrlDecode(setting[1]);

                        switch (setting[0]) {
                            case WaitOnAbnormalExitSetting:
                                bool value;
                                if (Boolean.TryParse(setting[1], out value) && value) {
                                    debugOptions |= NodeDebugOptions.WaitOnAbnormalExit;
                                }
                                break;
                            case WaitOnNormalExitSetting:
                                if (Boolean.TryParse(setting[1], out value) && value) {
                                    debugOptions |= NodeDebugOptions.WaitOnNormalExit;
                                }
                                break;
                            case RedirectOutputSetting:
                                if (Boolean.TryParse(setting[1], out value) && value) {
                                    debugOptions |= NodeDebugOptions.RedirectOutput;
                                }
                                break;
                            case DirMappingSetting:
                                string[] dirs = setting[1].Split('|');
                                if (dirs.Length == 2) {
                                    if (dirMapping == null) {
                                        dirMapping = new List<string[]>();
                                    }
                                    LiveLogger.WriteLine(String.Format("Mapping dir {0} to {1}", dirs[0], dirs[1]));
                                    dirMapping.Add(dirs);
                                }
                                break;
                            case InterpreterOptions:
                                interpreterOptions = setting[1];
                                break;
                            case WebBrowserUrl:
                                _webBrowserUrl = setting[1];
                                break;
                            case DebuggerPort:
                                ushort dbgPortTmp;
                                if (ushort.TryParse(setting[1], out dbgPortTmp)) {
                                    debugPort = dbgPortTmp;
                                }
                                break;
                        }
                    }
                }
            }

            _process =
                new NodeDebugger(
                    exe,
                    args,
                    dir,
                    env,
                    interpreterOptions,
                    debugOptions,
                    debugPort
                );

            _process.Start(false);

            AttachEvents(_process);

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

            EngineUtils.RequireOk(port.GetProcess(adProcessId, out process));
            LiveLogger.WriteLine("AD7Engine LaunchSuspended returning S_OK");
            Debug.Assert(process != null);
            Debug.Assert(!_process.HasExited);

            return VSConstants.S_OK;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Launch the actual debug process.
        /// </summary>
        public int LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir, string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 pCallback, out IDebugProcess2 ppProcess)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "IDebugEngine2.LaunchSuspended");

            ppProcess = null;
            var port = pPort as DebugPort;
            if (pPort == null)
                return VSConstants.E_INVALIDARG;

            // Create event callback
            eventCallback = new EngineEventCallback(this, pCallback);

            // Notify creation
            eventCallback.Send(new EngineCreateEvent(this));

            // Get debugger
            var guid = new Guid(pszOptions);
            var debugger = Launcher.GetAndRemoveDebugger(guid, out stateUpdate);

            // Load map file
            var mapFilePath = Path.ChangeExtension(pszExe, ".d42map");
            var mapFile = File.Exists(mapFilePath) ? new MapFile(mapFilePath) : new MapFile();
            
            // Create new process
            var process = new DebugProcess(this, port, debugger, Environment.TickCount, guid, pszExe, mapFile, eventCallback);
            var program = process.Program;
            process.Terminated += (s, x) => ((IDebugEngine2)this).DestroyProgram(program);

            // Record process
            ((DebugPort)pPort).RecordProcess(process);
            // Return result
            ppProcess = process;
            return VSConstants.S_OK;
        }
Exemplo n.º 3
0
 int IDebugEngineLaunch2.LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir, string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 pCallback, out IDebugProcess2 ppProcess)
 {
     ppProcess = null;
     return(VSConstants.E_NOTIMPL);
 }
Exemplo n.º 4
0
        // 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);
        }
Exemplo n.º 5
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);
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Launches a process by means of the debug engine. (http://msdn.microsoft.com/en-us/library/bb146223.aspx)
        /// </summary>
        /// <param name="pszServer"> The name of the machine in which to launch the process. Use a null value to specify the local 
        /// machine. Or it should be the name of the server? </param>
        /// <param name="port"> The IDebugPort2 interface representing the port that the program will run in. </param>
        /// <param name="exe"> The name of the executable to be launched. </param>
        /// <param name="args"> The arguments to pass to the executable. May be a null value if there are no arguments. </param>
        /// <param name="dir"> The name of the working directory used by the executable. May be a null value if no working directory is 
        /// required. </param>
        /// <param name="env"> Environment block of NULL-terminated strings, followed by an additional NULL terminator. </param>
        /// <param name="options"> The options for the executable. </param>
        /// <param name="launchFlags"> Specifies the LAUNCH_FLAGS for a session. </param>
        /// <param name="hStdInput"> Handle to an alternate input stream. May be 0 if redirection is not required. </param>
        /// <param name="hStdOutput"> Handle to an alternate output stream. May be 0 if redirection is not required. </param>
        /// <param name="hStdError"> Handle to an alternate error output stream. May be 0 if redirection is not required. </param>
        /// <param name="ad7Callback"> The IDebugEventCallback2 object that receives debugger events. </param>
        /// <param name="process"> Returns the resulting IDebugProcess2 object that represents the launched process. </param>
        /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns>
        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(m_programGUID == Guid.Empty);

            process = null;

            try
            {
                VSNDK.Package.ControlDebugEngine.isDebugEngineRunning = true;
                m_engineCallback = new EngineCallback(this, ad7Callback);

                // Read arguments back from the args string
                var nvc = new NameValueCollection();
                NameValueCollectionHelper.LoadFromString(nvc, args);

                string pid = nvc.GetValues("pid")[0];
                string exePath = exe;
                string targetIP = nvc.GetValues("targetIP")[0];
                bool isSimulator = Convert.ToBoolean(nvc.GetValues("isSimulator")[0]);
                string toolsPath = nvc.GetValues("ToolsPath")[0];
                string publicKeyPath = nvc.GetValues("PublicKeyPath")[0];

                string password = null;
                string[] passwordArray = nvc.GetValues("Password");
                if (passwordArray != null)
                    password = passwordArray[0];

                if (GDBParser.LaunchProcess(pid, exePath, targetIP, isSimulator, toolsPath, publicKeyPath, password))
                {
                    process = m_process = new AD7Process(this, port);
                    m_eventDispatcher = new EventDispatcher(this);
                    m_programGUID = m_process._processGUID;
                    m_module = new AD7Module();
            //                    m_progNode = new AD7ProgramNode(m_process.PhysID, pid, exePath, new Guid(AD7Engine.Id));
                    m_progNode = new AD7ProgramNode(m_process._processGUID, pid, exePath, new Guid(AD7Engine.Id));
                    AddThreadsToProgram();

                    AD7EngineCreateEvent.Send(this);

                    return VSConstants.S_OK;
                }
                else
                {
                    GDBParser.exitGDB();
                    VSNDK.Package.ControlDebugEngine.isDebugEngineRunning = false;
                    return VSConstants.E_FAIL;
                }
            }
            catch (Exception e)
            {
                return EngineUtils.UnexpectedException(e);
            }
        }
Exemplo n.º 7
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 {
                // 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(() => m_debuggedProcess = new DebuggedProcess(exe, args, m_pollThread, Callback));

                var adProcessId = new AD_PROCESS_ID {
                    ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM,
                    dwProcessId = (uint)m_debuggedProcess.Id
                };

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

                return Constants.S_OK;
            } catch (Exception e) {
                return EngineUtils.UnexpectedException(e);
            }
        }
Exemplo n.º 8
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(m_ad7ProgramId == Guid.Empty);
            
            m_ad7ProgramId = Guid.NewGuid();

            STARTUPINFO si = new STARTUPINFO();
            pi = new PROCESS_INFORMATION();

            // try/finally free
            bool procOK = NativeMethods.CreateProcess(exe, 
                                                      args,
                                                      IntPtr.Zero,
                                                      IntPtr.Zero,
                                                      false,
                                                      ProcessCreationFlags.CREATE_SUSPENDED,
                                                      IntPtr.Zero,
                                                      null,
                                                      ref si,
                                                      out pi);

            pID = pi.dwProcessId;
            Task writepipeOK = WriteNamedPipeAsync();
            Task readpipeOK = ReadNamedPipeAsync();
            
            threadHandle = pi.hThread;
            IntPtr processHandle = pi.hProcess;

            // Inject LuaDebug into host
            IntPtr loadLibAddr = DLLInjector.GetProcAddress(DLLInjector.GetModuleHandle("kernel32.dll"), "LoadLibraryA");

            string VS140ExtensionPath = Path.Combine(Path.GetDirectoryName(typeof(EngineConstants).Assembly.Location), "LuaDetour");
            string luaDetoursDllName = Path.Combine(VS140ExtensionPath, "LuaDetours.dll");
            if(!File.Exists(luaDetoursDllName))
            {
                process = null;
                return VSConstants.E_FAIL;
            }
            IntPtr allocMemAddress1 = DLLInjector.VirtualAllocEx(processHandle, IntPtr.Zero,
                (uint)((luaDetoursDllName.Length + 1) * Marshal.SizeOf(typeof(char))),
                DLLInjector.MEM_COMMIT | DLLInjector.MEM_RESERVE, DLLInjector.PAGE_READWRITE);

            UIntPtr bytesWritten1;
            DLLInjector.WriteProcessMemory(processHandle, allocMemAddress1,
                Encoding.Default.GetBytes(luaDetoursDllName),
                (uint)((luaDetoursDllName.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten1);
            IntPtr hRemoteThread1 = DLLInjector.CreateRemoteThread(processHandle, IntPtr.Zero, 0, loadLibAddr, allocMemAddress1, 0, IntPtr.Zero);

            IntPtr[] handles1 = new IntPtr[] { hRemoteThread1 };
            uint index1;
            NativeMethods.CoWaitForMultipleHandles(0, -1, handles1.Length, handles1, out index1);

            string debugDllName = Path.Combine(VS140ExtensionPath, "LuaDebug32.dll");

            IntPtr allocMemAddress2 = DLLInjector.VirtualAllocEx(processHandle, IntPtr.Zero,
                (uint)((debugDllName.Length + 1) * Marshal.SizeOf(typeof(char))),
                DLLInjector.MEM_COMMIT | DLLInjector.MEM_RESERVE, DLLInjector.PAGE_READWRITE);

            UIntPtr bytesWritten2;
            DLLInjector.WriteProcessMemory(processHandle, allocMemAddress2,
                Encoding.Default.GetBytes(debugDllName), (uint)((debugDllName.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten2);

            IntPtr hRemoteThread2 = DLLInjector.CreateRemoteThread(processHandle, IntPtr.Zero, 0, loadLibAddr, allocMemAddress2, 0, IntPtr.Zero);
            IntPtr[] handles = new IntPtr[] { hRemoteThread2 };
            uint index2;
            NativeMethods.CoWaitForMultipleHandles(0, -1, handles.Length, handles, out index2);


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

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

            return VSConstants.S_OK;
        }
Exemplo n.º 9
0
        /// <summary>
        /// Launch the actual debug process.
        /// </summary>
        public int LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir, string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 pCallback, out IDebugProcess2 ppProcess)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "IDebugEngine2.LaunchSuspended");

            ppProcess = null;
            var port = pPort as DebugPort;

            if (pPort == null)
            {
                return(VSConstants.E_INVALIDARG);
            }

            // Create event callback
            eventCallback = new EngineEventCallback(this, pCallback);

            // Notify creation
            eventCallback.Send(new EngineCreateEvent(this));

            // Get debugger
            var guid     = new Guid(pszOptions);
            var debugger = Launcher.GetAndRemoveDebugger(guid, out stateUpdate);

            // Load map file
            var mapFilePath = Path.ChangeExtension(pszExe, ".d42map");
            var mapFile     = File.Exists(mapFilePath) ? new MapFile(mapFilePath) : new MapFile();

            // Create new process
            var process = new DebugProcess(this, port, debugger, Environment.TickCount, guid, pszExe, mapFile, eventCallback);
            var program = process.Program;

            process.Terminated += (s, x) => ((IDebugEngine2)this).DestroyProgram(program);

            // Record process
            ((DebugPort)pPort).RecordProcess(process);
            // Return result
            ppProcess = process;
            return(VSConstants.S_OK);
        }
Exemplo n.º 10
0
        public int LaunchSuspended(string server, IDebugPort2 port, string exe, string args, string directory, string environment, string options, enum_LAUNCH_FLAGS launchFlags, uint standardInput, uint standardOutput, uint standardError, IDebugEventCallback2 callback, out IDebugProcess2 process)
        {
            waiter   = new AutoResetEvent(false);
            settings = MonoDebuggerSettings.Load(options);

            Task.Run(() => {
                var outputWindow    = (IVsOutputWindow)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsOutputWindow));
                var generalPaneGuid = VSConstants.GUID_OutWindowDebugPane;
                outputWindow.GetPane(ref generalPaneGuid, out this.outputWindow);

                settings.Launcher.Launch();

                // Trigger that the app is now running for whomever might be waiting for that signal
                waiter.Set();
            });

            Session              = new SoftDebuggerSession();
            Session.TargetReady += (sender, eventArgs) => {
                var activeThread = Session.ActiveThread;
                ThreadManager.Add(activeThread, new MonoThread(this, activeThread));
                //                Session.Stop();
            };
            Session.ExceptionHandler = exception => true;
            Session.TargetExited    += (sender, x) => {
                //                runCommand.EndExecute(runCommandAsyncResult);
                Send(new MonoProgramDestroyEvent((uint?)x.ExitCode ?? 0), MonoProgramDestroyEvent.IID, null);
            };
            Session.TargetUnhandledException += (sender, x) => {
                Send(new MonoExceptionEvent(x.Backtrace.GetFrame(0))
                {
                    IsUnhandled = true
                }, MonoExceptionEvent.IID, ThreadManager[x.Thread]);
            };
            Session.LogWriter            = (stderr, text) => Console.WriteLine(text);
            Session.OutputWriter         = (stderr, text) => Console.WriteLine(text);
            Session.TargetThreadStarted += (sender, x) => ThreadManager.Add(x.Thread, new MonoThread(this, x.Thread));
            Session.TargetThreadStopped += (sender, x) => {
                ThreadManager.Remove(x.Thread);
            };
            Session.TargetStopped         += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetStarted         += (sender, x) => Console.WriteLine();
            Session.TargetSignaled        += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetInterrupted     += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetExceptionThrown += (sender, x) => {
                Send(new MonoExceptionEvent(x.Backtrace.GetFrame(0)), MonoExceptionEvent.IID, ThreadManager[x.Thread]);
            };
            Session.TargetHitBreakpoint += (sender, x) => {
                var breakpoint        = x.BreakEvent as Breakpoint;
                var pendingBreakpoint = breakpointManager[breakpoint];
                Send(new MonoBreakpointEvent(new MonoBoundBreakpointsEnum(pendingBreakpoint.BoundBreakpoints)), MonoBreakpointEvent.IID, ThreadManager[x.Thread]);
            };

            processId = new AD_PROCESS_ID();
            processId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
            processId.guidProcessId = Guid.NewGuid();

            EngineUtils.CheckOk(port.GetProcess(processId, out process));
            Callback = callback;

            return(VSConstants.S_OK);
        }
Exemplo n.º 11
0
        int IDebugEngineLaunch2.LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir, string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 pCallback, out IDebugProcess2 ppProcess)
        {
            string[] p = pszExe.Split(':');
            callback = new AD7.EngineCallback(this, pCallback);
            debugged = new AD7.DebuggedProcessVS(this, p[0], int.Parse(p[1]));
            while (debugged.Connecting)
            {
                System.Threading.Thread.Sleep(10);
            }

            if (debugged.Connected)
            {
                if (debugged.CheckDebugServerVersion())
                {
                    ppProcess               = new AD7Process(pPort);
                    this.process            = ppProcess;
                    debugged.OnDisconnected = OnDisconnected;
                    return(Constants.S_OK);
                }
                else
                {
                    debugged.Close();
                    MessageBox.Show(String.Format("ILRuntime Debugger version mismatch\n Expected version:{0}\n Actual version:{1}", DebuggerServer.Version, DebuggedProcess.RemoteDebugVersion), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    debugged  = null;
                    ppProcess = null;
                    return(Constants.S_FALSE);
                }
            }
            else
            {
                MessageBox.Show("Cannot connect to ILRuntime", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                debugged  = null;
                ppProcess = null;
                return(Constants.S_FALSE);
            }
        }
Exemplo n.º 12
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));
            }
        }
Exemplo n.º 13
0
    int IDebugEngineLaunch2.LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir, string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 pCallback, out IDebugProcess2 ppProcess)
    {
      Debug.WriteLine("AD7Engine LaunchSuspended");
      ppProcess = new AD7Process(pPort);
      _node = (ppProcess as AD7Process).Node;
      _node.FileName = pszExe;
      _node.ConnectionString = pszArgs;
      _events = new AD7Events(this, pCallback);

      // Gets active window handler to use in modals
      IntPtr handler = GetForegroundWindow();
      _node.ParentWindow = new System.Windows.Forms.NativeWindow();
      _node.ParentWindow.AssignHandle(handler);

      return VSConstants.S_OK;
    }
Exemplo n.º 14
0
        public /*override*/ int LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir, string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 pCallback, out IDebugProcess2 ppProcess)
        {
            DebugHelper.TraceEnteringMethod();
            var base64Options = SerializeDebuggerOptions(pszOptions);
            var result        = _engine.LaunchSuspended(pszServer, pPort, pszExe, pszArgs, pszDir, bstrEnv, base64Options, dwLaunchFlags, hStdInput, hStdOutput, hStdError, pCallback, out ppProcess);

            return(result);
        }
Exemplo n.º 15
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(m_ad7ProgramId == Guid.Empty);

            m_ad7ProgramId = Guid.NewGuid();

            STARTUPINFO si = new STARTUPINFO();

            pi = new PROCESS_INFORMATION();

            // try/finally free
            bool procOK = NativeMethods.CreateProcess(exe,
                                                      args,
                                                      IntPtr.Zero,
                                                      IntPtr.Zero,
                                                      false,
                                                      ProcessCreationFlags.CREATE_SUSPENDED,
                                                      IntPtr.Zero,
                                                      null,
                                                      ref si,
                                                      out pi);

            pID = pi.dwProcessId;
            Task writepipeOK = WriteNamedPipeAsync();
            Task readpipeOK  = ReadNamedPipeAsync();

            threadHandle = pi.hThread;
            IntPtr processHandle = pi.hProcess;

            // Inject LuaDebug into host
            IntPtr loadLibAddr = DLLInjector.GetProcAddress(DLLInjector.GetModuleHandle("kernel32.dll"), "LoadLibraryA");

            string VS140ExtensionPath = Path.Combine(Path.GetDirectoryName(typeof(EngineConstants).Assembly.Location), "LuaDetour");
            string luaDetoursDllName  = Path.Combine(VS140ExtensionPath, "LuaDetours.dll");

            if (!File.Exists(luaDetoursDllName))
            {
                process = null;
                return(VSConstants.E_FAIL);
            }
            IntPtr allocMemAddress1 = DLLInjector.VirtualAllocEx(processHandle, IntPtr.Zero,
                                                                 (uint)((luaDetoursDllName.Length + 1) * Marshal.SizeOf(typeof(char))),
                                                                 DLLInjector.MEM_COMMIT | DLLInjector.MEM_RESERVE, DLLInjector.PAGE_READWRITE);

            UIntPtr bytesWritten1;

            DLLInjector.WriteProcessMemory(processHandle, allocMemAddress1,
                                           Encoding.Default.GetBytes(luaDetoursDllName),
                                           (uint)((luaDetoursDllName.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten1);
            IntPtr hRemoteThread1 = DLLInjector.CreateRemoteThread(processHandle, IntPtr.Zero, 0, loadLibAddr, allocMemAddress1, 0, IntPtr.Zero);

            IntPtr[] handles1 = new IntPtr[] { hRemoteThread1 };
            uint     index1;

            NativeMethods.CoWaitForMultipleHandles(0, -1, handles1.Length, handles1, out index1);

            string debugDllName = Path.Combine(VS140ExtensionPath, "LuaDebug32.dll");

            IntPtr allocMemAddress2 = DLLInjector.VirtualAllocEx(processHandle, IntPtr.Zero,
                                                                 (uint)((debugDllName.Length + 1) * Marshal.SizeOf(typeof(char))),
                                                                 DLLInjector.MEM_COMMIT | DLLInjector.MEM_RESERVE, DLLInjector.PAGE_READWRITE);

            UIntPtr bytesWritten2;

            DLLInjector.WriteProcessMemory(processHandle, allocMemAddress2,
                                           Encoding.Default.GetBytes(debugDllName), (uint)((debugDllName.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten2);

            IntPtr hRemoteThread2 = DLLInjector.CreateRemoteThread(processHandle, IntPtr.Zero, 0, loadLibAddr, allocMemAddress2, 0, IntPtr.Zero);

            IntPtr[] handles = new IntPtr[] { hRemoteThread2 };
            uint     index2;

            NativeMethods.CoWaitForMultipleHandles(0, -1, handles.Length, handles, out index2);


            AD_PROCESS_ID adProcessId = new AD_PROCESS_ID();

            adProcessId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM;
            adProcessId.dwProcessId   = pi.dwProcessId;

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

            return(VSConstants.S_OK);
        }
Exemplo n.º 16
0
        public int 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)
        {
            DebugHelper.TraceEnteringMethod();

            Callback = new EngineCallback(this, ad7Callback);
            DebuggedProcess = new DebuggedProcess(this, IPAddress.Parse(args), Callback);
            DebuggedProcess.ApplicationClosed += _debuggedProcess_ApplicationClosed;
            DebuggedProcess.StartDebugging();

            process = RemoteProcess = new MonoProcess(port);
            return VSConstants.S_OK;
        }
Exemplo n.º 17
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(_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;
        }
Exemplo n.º 18
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int 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)
    {
      // 
      // Normally, VS launches a program using the IDebugPortEx2::LaunchSuspended method, and the attaches the debugger to the suspended program.
      // However, there are circumstances in which the DebugEngine may need to launch a program or other dependencies (e.g. tools or interpreters) in which case this method is used.
      // IDebugEngineLaunch2::ResumeProcess method is called to start the process after the program has been launched in a suspended state.
      // 

      LoggingUtils.PrintFunction ();

      try
      {
        if (port == null)
        {
          throw new ArgumentNullException ("port");
        }

        if (string.IsNullOrEmpty (exe))
        {
          throw new ArgumentNullException ("exe");
        }

        if (!File.Exists (exe))
        {
          throw new FileNotFoundException ("Failed to find target application: " + exe);
        }

        m_sdmCallback = new DebugEngineCallback (this, ad7Callback);

        DebuggeePort debuggeePort = port as DebuggeePort;

        DebuggeeProcess debugProcess = null;

        // 
        // Evaluate options; including current debugger target application.
        // 

        if (m_launchConfiguration == null)
        {
          throw new InvalidOperationException ("No launch configuration found.");
        }

        m_launchConfiguration.FromString (options);

        string packageName = m_launchConfiguration ["PackageName"];

        string launchActivity = m_launchConfiguration ["LaunchActivity"];

        bool debugMode = m_launchConfiguration ["DebugMode"].Equals ("true");

        bool openGlTrace = m_launchConfiguration ["OpenGlTrace"].Equals ("true");

        bool appIsRunning = false;

        // 
        // Cache any LaunchSuspended specific parameters.
        // 

        m_launchConfiguration ["LaunchSuspendedExe"] = exe;

        m_launchConfiguration ["LaunchSuspendedDir"] = dir;

        m_launchConfiguration ["LaunchSuspendedEnv"] = env;

        // 
        // Prevent blocking the main VS thread when launching a suspended application.
        // 

        Broadcast (new DebugEngineEvent.DebuggerConnectionEvent (DebugEngineEvent.DebuggerConnectionEvent.EventType.ShowDialog, string.Empty), null, null);

        ManualResetEvent launchSuspendedMutex = new ManualResetEvent (false);

        Thread asyncLaunchSuspendedThread = new Thread (delegate ()
        {
          try
          {
            // 
            // Launch application on device in a 'suspended' state.
            // 

            Broadcast (new DebugEngineEvent.DebuggerConnectionEvent (DebugEngineEvent.DebuggerConnectionEvent.EventType.LogStatus, string.Format ("Starting '{0}'...", packageName)), null, null);

            if (!appIsRunning)
            {
              StringBuilder launchArgumentsBuilder = new StringBuilder ();

              launchArgumentsBuilder.Append ("start ");

              if (debugMode)
              {
                launchArgumentsBuilder.Append ("-D "); // debug
              }
              else
              {
                launchArgumentsBuilder.Append ("-W "); // wait
              }

              launchArgumentsBuilder.Append ("-S "); // force stop the target app before starting the activity

              if (openGlTrace)
              {
                launchArgumentsBuilder.Append ("--opengl-trace ");
              }

              launchArgumentsBuilder.Append (packageName + "/" + launchActivity);

              Broadcast (new DebugEngineEvent.DebuggerConnectionEvent (DebugEngineEvent.DebuggerConnectionEvent.EventType.LogStatus, string.Format ("[adb:shell:am] {0}", launchArgumentsBuilder)), null, null);

              string launchResponse = debuggeePort.PortDevice.Shell ("am", launchArgumentsBuilder.ToString ());

              if (string.IsNullOrEmpty (launchResponse) || launchResponse.Contains ("Error:"))
              {
                throw new InvalidOperationException ("Launch intent failed:\n" + launchResponse);
              }
            }

            // 
            // Query whether the target application is already running. (Double-check)
            // 

            int launchAttempt = 1;

            int maxLaunchAttempts = 20;

            while (!appIsRunning)
            {
              Broadcast(new DebugEngineEvent.DebuggerConnectionEvent(DebugEngineEvent.DebuggerConnectionEvent.EventType.LogStatus, string.Format("Waiting for '{0}' to launch (Attempt {1} of {2})...", packageName, launchAttempt, maxLaunchAttempts)), null, null);

              LoggingUtils.RequireOk (debuggeePort.RefreshProcesses ());

              // 
              // Validate that the process is running and was spawned by one of the zygote processes.
              // 

              uint [] zygotePids = debuggeePort.PortDevice.GetPidsFromName ("zygote");

              uint [] zygote64Pids = debuggeePort.PortDevice.GetPidsFromName ("zygote64");

              uint [] packagePids = debuggeePort.PortDevice.GetPidsFromName (packageName);

              for (int i = packagePids.Length - 1; i >= 0; --i)
              {
                uint pid = packagePids [i];

                AndroidProcess packageProcess = debuggeePort.PortDevice.GetProcessFromPid (pid);

                bool spawnedByZygote = false;

                if ((zygotePids.Length > 0) && (packageProcess.ParentPid == zygotePids [0]))
                {
                  spawnedByZygote = true;
                }
                else if ((zygote64Pids.Length > 0) && (packageProcess.ParentPid == zygote64Pids [0]))
                {
                  spawnedByZygote = true;
                }

                if (spawnedByZygote)
                {
                  debugProcess = debuggeePort.GetProcessForPid (pid);

                  appIsRunning = (debugProcess != null);

                  break;
                }
              }

              if (!appIsRunning)
              {
                if (++launchAttempt > maxLaunchAttempts)
                {
                  throw new TimeoutException (string.Format ("'{0}' failed to launch. Please ensure device is unlocked.", packageName));
                }

                Application.DoEvents ();

                Thread.Sleep (100);
              }
            }

            launchSuspendedMutex.Set ();
          }
          catch (Exception e)
          {
            LoggingUtils.HandleException (e);

            string error = string.Format ("[Exception] {0}\n{1}", e.Message, e.StackTrace);

            Broadcast (ad7Callback, new DebugEngineEvent.Error (error, true), null, null);

            launchSuspendedMutex.Set ();
          }
        });

        asyncLaunchSuspendedThread.Start ();

        while (!launchSuspendedMutex.WaitOne (0))
        {
          Application.DoEvents ();

          Thread.Sleep (100);
        }

        // 
        // Attach to launched process.
        // 

        if (debugProcess == null)
        {
          throw new InvalidOperationException (string.Format ("'{0}' failed to launch. Could not continue.", packageName));
        }

        process = debugProcess;

        return Constants.S_OK;
      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);

        process = null;

        try
        {
          string error = string.Format ("[Exception] {0}\n{1}", e.Message, e.StackTrace);

          Broadcast (ad7Callback, new DebugEngineEvent.Error (error, true), null, null);
        }
        catch
        {
          LoggingUtils.HandleException (e);
        }

        return Constants.E_FAIL;
      }
    }
Exemplo n.º 19
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(_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);
        }
Exemplo n.º 20
0
        // Token: 0x0600005A RID: 90 RVA: 0x000033EC File Offset: 0x000015EC
        public int LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir, string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 pCallback, out IDebugProcess2 ppProcess)
        {
            StartInfo startInfo;

            using (MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(pszOptions)))
            {
                BinaryFormatter    binaryFormatter    = new BinaryFormatter();
                SessionMarshalling sessionMarshalling = (SessionMarshalling)binaryFormatter.Deserialize(memoryStream);
                this.session = sessionMarshalling.Session;
                startInfo    = sessionMarshalling.StartInfo;
            }

            this.eventSender = new EventSender(pCallback, this);
            Process process = new Process((Port)pPort, this, this.eventSender, this.session, startInfo, pszExe);

            ppProcess = process;
            this.processes.Add(process);
            this.eventSender.SendEvent(new ProcessCreateEvent(process));
            return(0);
        }
Exemplo n.º 21
0
        int IDebugEngineLaunch2.LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir, string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 pCallback, out IDebugProcess2 ppProcess)
        {
            Debug.WriteLine("AD7Engine LaunchSuspended");
            ppProcess              = new AD7Process(pPort);
            _node                  = (ppProcess as AD7Process).Node;
            _node.FileName         = pszExe;
            _node.ConnectionString = pszArgs;
            _events                = new AD7Events(this, pCallback);

            // Gets active window handler to use in modals
            IntPtr handler = GetForegroundWindow();

            _node.ParentWindow = new System.Windows.Forms.NativeWindow();
            _node.ParentWindow.AssignHandle(handler);

            return(VSConstants.S_OK);
        }
        /// <summary>
        /// This method launches a process by means of the debug DebugEngine (DE).
        /// </summary>
        /// <param name="pszServer">The name of the machine in which to launch the process. Use a null value to specify the local machine.</param>
        /// <param name="pPort">The IDebugPort2 interface representing the port that the program will run in.</param>
        /// <param name="pszExe">The name of the executable to be launched.</param>
        /// <param name="pszArgs">The arguments to pass to the executable. May be a null value if there are no arguments.</param>
        /// <param name="pszDir">The name of the working directory used by the executable. May be a null value if no working directory is required.</param>
        /// <param name="bstrEnv">Environment block of NULL-terminated strings, followed by an additional NULL terminator.</param>
        /// <param name="pszOptions">The options for the executable.</param>
        /// <param name="dwLaunchFlags">Specifies the LAUNCH_FLAGS for a session.</param>
        /// <param name="hStdInput">Handle to an alternate input stream. May be 0 if redirection is not required.</param>
        /// <param name="hStdOutput">Handle to an alternate output stream. May be 0 if redirection is not required.</param>
        /// <param name="hStdError">Handle to an alternate error output stream. May be 0 if redirection is not required.</param>
        /// <param name="pCallback">The IDebugEventCallback2 object that receives debugger events.</param>
        /// <param name="ppProcess">Returns the resulting IDebugProcess2 object that represents the launched process.</param>
        /// <returns>
        /// If successful, returns S_OK; otherwise, returns an error code.
        /// </returns>
        public override int LaunchSuspended( string pszServer,
            IDebugPort2 pPort,
            string pszExe,
            string pszArgs,
            string pszDir,
            string bstrEnv,
            string pszOptions,
            enum_LAUNCH_FLAGS dwLaunchFlags,
            uint hStdInput,
            uint hStdOutput,
            uint hStdError,
            IDebugEventCallback2 pCallback,
            out IDebugProcess2 ppProcess)
        {
            Logger.Debug( string.Empty );
            Process = new PowerShellProcess( pPort );

            ppProcess = Process;
            CreateOrInitializeEventSource( pCallback );
            return VSConstants.E_NOTIMPL;
        }
Exemplo n.º 23
0
 public int LaunchSuspended(string pszServer, IDebugPort2 port, string serverExe, string serverArgs, string dir, string env, string opts, enum_LAUNCH_FLAGS launchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 ad7Callback, out IDebugProcess2 process) =>
 throw new NotImplementedException("Launching a local process is not supported. The engine must be launched with DebugLaunchOperation.AlreadyRunning");
Exemplo n.º 24
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(_pollThread == null);
            Debug.Assert(_engineCallback == null);
            Debug.Assert(_debuggedProcess == null);
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            process = null;

            _engineCallback = new EngineCallback(this, ad7Callback);

            Exception exception;

            try
            {
                // Note: LaunchOptions.GetInstance can be an expensive operation and may push a wait message loop
                LaunchOptions launchOptions = LaunchOptions.GetInstance(_registryRoot, exe, args, dir, options, _engineCallback);

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

                using (cancellationTokenSource)
                {
                    _pollThread.RunOperation(ResourceStrings.InitializingDebugger, cancellationTokenSource, (MICore.WaitLoop waitLoop) =>
                    {
                        try
                        {
                            _debuggedProcess = new DebuggedProcess(true, launchOptions, _engineCallback, _pollThread, _breakpointManager, this);
                        }
                        finally
                        {
                            // If there is an exception from the DebuggeedProcess constructor, it is our responsibility to dispose the DeviceAppLauncher,
                            // otherwise the DebuggedProcess object takes ownership.
                            if (_debuggedProcess == null && launchOptions.DeviceAppLauncher != null)
                            {
                                launchOptions.DeviceAppLauncher.Dispose();
                            }
                        }

                        _pollThread.PostedOperationErrorEvent += _debuggedProcess.OnPostedOperationError;

                        return(_debuggedProcess.Initialize(waitLoop, cancellationTokenSource.Token));
                    });
                }

                EngineUtils.RequireOk(port.GetProcess(_debuggedProcess.Id, out process));

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                exception = e;
                // Return from the catch block so that we can let the exception unwind - the stack can get kind of big
            }

            // 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.
            Logger.Flush();
            SendStartDebuggingError(exception);

            Dispose();

            return(Constants.E_ABORT);
        }
Exemplo n.º 25
0
        public int LaunchSuspended(string server, IDebugPort2 port, string exe, string args, string directory, string environment, string options, enum_LAUNCH_FLAGS launchFlags, uint standardInput, uint standardOutput, uint standardError, IDebugEventCallback2 callback, out IDebugProcess2 process)
        {
            waiter   = new AutoResetEvent(false);
            settings = MonoDebuggerSettings.Parse(options);

            Task.Run(() =>
            {
                var outputWindow    = (IVsOutputWindow)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsOutputWindow));
                var generalPaneGuid = VSConstants.GUID_OutWindowDebugPane;
                outputWindow.GetPane(ref generalPaneGuid, out this.outputWindow);

                // Upload the contents of the output folder to the target directory
                if (connection == null)
                {
                    connection = ConnectionManager.Get(settings);
                    if (!connection.IsConnected)
                    {
                        Log("Connecting SSH and SFTP...");
                        connection.Connect();
                        Log("Connected");
                    }
                }

                Log("Uploading program...");

                // Ensure target directory exists:
                var targetDirectories = directory.Split('/');
                foreach (var part in targetDirectories)
                {
                    if (!connection.Sftp.Exists(part))
                    {
                        connection.Sftp.CreateDirectory(part);
                    }
                    connection.Sftp.ChangeDirectory(part);
                }
                foreach (var _ in targetDirectories)
                {
                    connection.Sftp.ChangeDirectory("..");
                }

                var outputDirectory = new DirectoryInfo(Path.GetDirectoryName(exe));
                foreach (var file in outputDirectory.EnumerateFiles().Where(x => x.Extension == ".dll" || x.Extension == ".mdb" || x.Extension == ".exe"))
                {
                    using (var stream = file.OpenRead())
                    {
                        connection.Sftp.UploadFile(stream, $"{directory}/{file.Name}", true);
                    }
                    Log($"Uploaded {file.FullName}");
                }
                Log("Done");

                var targetExe = directory + "/" + Path.GetFileName(exe);
                connection.Ssh.RunCommand("cd ~");
                Log("Launching application");
                var commandText = $"mono --debug=mdb-optimizations --debugger-agent=transport=dt_socket,address=0.0.0.0:6438,server=y {targetExe}";
                connection.Ssh.RunCommand("kill $(ps auxww | grep '" + commandText + "' | awk '{print $2}')", this.outputWindow, null);
                runCommand = connection.Ssh.BeginCommand(commandText, this.outputWindow, out runCommandAsyncResult);

                // Trigger that the app is now running for whomever might be waiting for that signal
                waiter.Set();
            });

            Session              = new SoftDebuggerSession();
            Session.TargetReady += (sender, eventArgs) =>
            {
                var activeThread = Session.ActiveThread;
                ThreadManager.Add(activeThread, new MonoThread(this, activeThread));
//                Session.Stop();
            };
            Session.ExceptionHandler = exception => true;
            Session.TargetExited    += (sender, x) =>
            {
//                runCommand.EndExecute(runCommandAsyncResult);
                Send(new MonoProgramDestroyEvent((uint?)x.ExitCode ?? 0), MonoProgramDestroyEvent.IID, null);
            };
            Session.TargetUnhandledException += (sender, x) =>
            {
                Send(new MonoExceptionEvent(x.Backtrace.GetFrame(0))
                {
                    IsUnhandled = true
                }, MonoExceptionEvent.IID, ThreadManager[x.Thread]);
            };
            Session.LogWriter            = (stderr, text) => Console.WriteLine(text);
            Session.OutputWriter         = (stderr, text) => Console.WriteLine(text);
            Session.TargetThreadStarted += (sender, x) => ThreadManager.Add(x.Thread, new MonoThread(this, x.Thread));
            Session.TargetThreadStopped += (sender, x) =>
            {
                ThreadManager.Remove(x.Thread);
            };
            Session.TargetStopped         += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetStarted         += (sender, x) => Console.WriteLine();
            Session.TargetSignaled        += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetInterrupted     += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetExceptionThrown += (sender, x) =>
            {
                Send(new MonoExceptionEvent(x.Backtrace.GetFrame(0)), MonoExceptionEvent.IID, ThreadManager[x.Thread]);
            };
            Session.TargetHitBreakpoint += (sender, x) =>
            {
                var breakpoint        = x.BreakEvent as Breakpoint;
                var pendingBreakpoint = breakpointManager[breakpoint];
                Send(new MonoBreakpointEvent(new MonoBoundBreakpointsEnum(pendingBreakpoint.BoundBreakpoints)), MonoBreakpointEvent.IID, ThreadManager[x.Thread]);
            };

            processId = new AD_PROCESS_ID();
            processId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
            processId.guidProcessId = Guid.NewGuid();

            EngineUtils.CheckOk(port.GetProcess(processId, out process));
            Callback = callback;

            return(VSConstants.S_OK);
        }
Exemplo n.º 26
0
        public int LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir,
                                   string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput,
                                   uint hStdOutput, uint hStdError, IDebugEventCallback2 pCallback,
                                   out IDebugProcess2 ppProcess)
        {
            _runspaceSet.Reset();

            if (dwLaunchFlags.HasFlag(enum_LAUNCH_FLAGS.LAUNCH_DEBUG))
            {
                ppProcess = new ScriptDebugProcess(pPort);
            }
            else
            {
                ppProcess = new ScriptDebugProcess(pPort);
            }

            _node = (ppProcess as ScriptDebugProcess).Node;

            if (pszExe == "Selection")
            {
                _node.IsFile = false;
                _node.FileName = pszOptions;
            }
            else
            {
                _node.IsFile = true;
                _node.FileName = pszExe;
                _node.Arguments = pszArgs;
            }
            

            _events = new EngineEvents(this, pCallback);

            return VSConstants.S_OK;
        }
Exemplo n.º 27
0
 public int LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir, string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 pCallback, out IDebugProcess2 ppProcess)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 28
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));
            }
        }
Exemplo n.º 29
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.WriteLine("PythonEngine LaunchSuspended Begin " + launchFlags + " " + GetHashCode());
            AssertMainThread();
            Debug.Assert(_events == null);
            Debug.Assert(_process == null);
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            process = null;

            _events = ad7Callback;

            PythonLanguageVersion version      = DefaultVersion;
            bool            waitOnAbnormalExit = false;
            bool            redirectOutput     = false;
            List <string[]> dirMapping         = null;

            if (options != null)
            {
                var splitOptions = options.Split(new[] { ';' }, 2);
                foreach (var optionSetting in splitOptions)
                {
                    var setting = optionSetting.Split(new[] { '=' }, 2);

                    if (setting.Length == 2)
                    {
                        switch (setting[0])
                        {
                        case VersionSetting: version = GetLanguageVersion(setting[1]); break;

                        case WaitOnAbnormalExitSetting:
                            bool value;
                            if (Boolean.TryParse(setting[1], out value))
                            {
                                waitOnAbnormalExit = value;
                            }
                            break;

                        case RedirectOutputSetting:
                            if (Boolean.TryParse(setting[1], out value))
                            {
                                redirectOutput = value;
                            }
                            break;

                        case DirMappingSetting:
                            string[] dirs = setting[1].Split('|');
                            if (dirs.Length == 2)
                            {
                                if (dirMapping == null)
                                {
                                    dirMapping = new List <string[]>();
                                }
                                Debug.WriteLine(String.Format("Mapping dir {0} to {1}", dirs[0], dirs[1]));
                                dirMapping.Add(dirs);
                            }
                            break;
                        }
                    }
                }
            }

            _process = new PythonProcess(version, exe, args, dir, env, waitOnAbnormalExit, redirectOutput, dirMapping);

            AttachEvents(_process);

            _programCreated = false;
            _loadComplete.Reset();

            _process.Start();

            AD_PROCESS_ID adProcessId = new AD_PROCESS_ID();

            adProcessId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM;
            adProcessId.dwProcessId   = (uint)_process.Id;

            EngineUtils.RequireOk(port.GetProcess(adProcessId, out process));
            Debug.WriteLine("PythonEngine LaunchSuspended returning S_OK");
            Debug.Assert(process != null);
            Debug.Assert(!_process.HasExited);

            return(VSConstants.S_OK);
        }
Exemplo n.º 30
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(_pollThread == null);
            Debug.Assert(_engineCallback == null);
            Debug.Assert(_debuggedProcess == null);
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            // Check if the logger was enabled late.
            Logger.LoadMIDebugLogger(_configStore);

            process = null;

            _engineCallback = new EngineCallback(this, ad7Callback);

            Exception exception;

            try
            {
                bool noDebug = launchFlags.HasFlag(enum_LAUNCH_FLAGS.LAUNCH_NODEBUG);

                // Note: LaunchOptions.GetInstance can be an expensive operation and may push a wait message loop
                LaunchOptions launchOptions = LaunchOptions.GetInstance(_configStore, exe, args, dir, options, noDebug, _engineCallback, TargetEngine.Native, Logger);

                StartDebugging(launchOptions);

                EngineUtils.RequireOk(port.GetProcess(_debuggedProcess.Id, out process));
                return(Constants.S_OK);
            }
            catch (Exception e) when(ExceptionHelper.BeforeCatch(e, Logger, reportOnlyCorrupting: true))
            {
                exception = e;
                // Return from the catch block so that we can let the exception unwind - the stack can get kind of big
            }

            // If we just return the exception as an HRESULT, we will lose our message, so we instead send up an error event, and then
            // return E_ABORT.
            OnStartDebuggingFailed(exception);

            return(Constants.E_ABORT);
        }
Exemplo n.º 31
0
        // After engine initialization, SDM calls LaunchSuspended to start the debuggee in a suspended state.
        // ResumeProcess and Attach are invoked next.

        public int 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(_program == null);

            var sourceFile = new SourceFile(Path.Combine(dir, exe));
            var runner     = new BasmRunner(sourceFile, OnProgramStop);
            var bpBackend  = new BasmBreakpointBackend(runner, OnProgramStepComplete, OnProgramBreakComplete);

            _program = new Program(runner, bpBackend, sourceFile);

            var processId = _program.StartBasmProcess();

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

            _callbacks         = new EngineCallbacks(this, _program, process, ad7Callback);
            _breakpointManager = new BreakpointManager(_program, bpBackend, sourceFile, _callbacks);

            Debug.WriteLine("IDebugEngineLaunch2.LaunchSuspended: returning S_OK");
            return(VSConstants.S_OK);
        }
Exemplo n.º 32
0
        public int LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir,
            string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput, uint hStdOutput,
            uint hStdError, IDebugEventCallback2 pCallback, out IDebugProcess2 ppProcess)
        {
            DebugHelper.TraceEnteringMethod();

            Events = new MonoDebuggerEvents(this, pCallback);
            DebuggedProcess = new DebuggedMonoProcess(this, IPAddress.Parse(pszArgs));
            DebuggedProcess.ApplicationClosed += _debuggedProcess_ApplicationClosed;

            ppProcess = RemoteProcess = new MonoProcess(pPort);
            return VSConstants.S_OK;
        }
Exemplo n.º 33
0
 public int LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir, string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 pCallback, out IDebugProcess2 ppProcess)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 34
0
 /// <summary>
 /// This method launches a process by means of the debug DebugEngine (DE).
 /// </summary>
 /// <param name="pszServer">The name of the machine in which to launch the process. Use a null value to specify the local machine.</param>
 /// <param name="pPort">The IDebugPort2 interface representing the port that the program will run in.</param>
 /// <param name="pszExe">The name of the executable to be launched.</param>
 /// <param name="pszArgs">The arguments to pass to the executable. May be a null value if there are no arguments.</param>
 /// <param name="pszDir">The name of the working directory used by the executable. May be a null value if no working directory is required.</param>
 /// <param name="bstrEnv">Environment block of NULL-terminated strings, followed by an additional NULL terminator.</param>
 /// <param name="pszOptions">The options for the executable.</param>
 /// <param name="dwLaunchFlags">Specifies the LAUNCH_FLAGS for a session.</param>
 /// <param name="hStdInput">Handle to an alternate input stream. May be 0 if redirection is not required.</param>
 /// <param name="hStdOutput">Handle to an alternate output stream. May be 0 if redirection is not required.</param>
 /// <param name="hStdError">Handle to an alternate error output stream. May be 0 if redirection is not required.</param>
 /// <param name="pCallback">The IDebugEventCallback2 object that receives debugger events.</param>
 /// <param name="ppProcess">Returns the resulting IDebugProcess2 object that represents the launched process.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 /// <remarks>
 /// 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 DebugEngine may need to launch a program (for example, if the debug DebugEngine 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.
 /// </remarks>
 public virtual int LaunchSuspended( string pszServer,
     IDebugPort2 pPort,
     string pszExe,
     string pszArgs,
     string pszDir,
     string bstrEnv,
     string pszOptions,
     enum_LAUNCH_FLAGS dwLaunchFlags,
     uint hStdInput,
     uint hStdOutput,
     uint hStdError,
     IDebugEventCallback2 pCallback,
     out IDebugProcess2 ppProcess)
 {
     Logger.Debug( string.Empty );
     ppProcess = null;
     return VSConstants.E_NOTIMPL;
 }
Exemplo n.º 35
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.WriteLine("--------------------------------------------------------------------------------");
            Debug.WriteLine("JEngine LaunchSuspended Begin " + launchFlags + " " + GetHashCode());
            AssertMainThread();
            Debug.Assert(_events == null);
            Debug.Assert(_process == null);
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            process = null;

            _events = ad7Callback;

            JLanguageVersion version = DefaultVersion;
            JDebugOptions debugOptions = JDebugOptions.None;
            bool attachRunning = false;
            List<string[]> dirMapping = null;
            string interpreterOptions = null;
            if (options != null) {
                var splitOptions = SplitOptions(options);

                foreach (var optionSetting in splitOptions) {
                    var setting = optionSetting.Split(new[] { '=' }, 2);

                    if (setting.Length == 2) {
                        switch (setting[0]) {
                            case VersionSetting: version = GetLanguageVersion(setting[1]); break;
                            case WaitOnAbnormalExitSetting:
                                bool value;
                                if (Boolean.TryParse(setting[1], out value) && value) {
                                    debugOptions |= JDebugOptions.WaitOnAbnormalExit;
                                }
                                break;
                            case WaitOnNormalExitSetting:
                                if (Boolean.TryParse(setting[1], out value) && value) {
                                    debugOptions |= JDebugOptions.WaitOnNormalExit;
                                }
                                break;
                            case RedirectOutputSetting:
                                if (Boolean.TryParse(setting[1], out value) && value) {
                                    debugOptions |= JDebugOptions.RedirectOutput;
                                }
                                break;
                            case BreakSystemExitZero:
                                if (Boolean.TryParse(setting[1], out value) && value) {
                                    debugOptions |= JDebugOptions.BreakOnSystemExitZero;
                                }
                                break;
                            case DebugStdLib:
                                if (Boolean.TryParse(setting[1], out value) && value) {
                                    debugOptions |= JDebugOptions.DebugStdLib;
                                }
                                break;
                            case DirMappingSetting:
                                string[] dirs = setting[1].Split('|');
                                if (dirs.Length == 2) {
                                    if (dirMapping == null) {
                                        dirMapping = new List<string[]>();
                                    }
                                    Debug.WriteLine(String.Format("Mapping dir {0} to {1}", dirs[0], dirs[1]));
                                    dirMapping.Add(dirs);
                                }
                                break;
                            case InterpreterOptions:
                                interpreterOptions = setting[1];
                                break;
                            case AttachRunning:
                                attachRunning = Convert.ToBoolean(setting[1]);
                                break;
                            case EnableDjangoDebugging:
                                if (Boolean.TryParse(setting[1], out value) && value) {
                                    debugOptions |= JDebugOptions.DjangoDebugging;
                                }
                                break;
                        }
                    }
                }
            }

            Guid processId;
            if (attachRunning && Guid.TryParse(exe, out processId)) {
                _process = DebugConnectionListener.GetProcess(processId);
                _attached = true;
                _pseudoAttach = true;
            } else {
                _process = new JProcess(version, exe, args, dir, env, interpreterOptions, debugOptions, dirMapping);
            }

            _programCreated = false;
            _loadComplete.Reset();

            if (!attachRunning) {
                _process.Start(false);
            }

            AttachEvents(_process);

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

            EngineUtils.RequireOk(port.GetProcess(adProcessId, out process));
            Debug.WriteLine("JEngine LaunchSuspended returning S_OK");
            Debug.Assert(process != null);
            Debug.Assert(!_process.HasExited);

            return VSConstants.S_OK;
        }
Exemplo n.º 36
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)
        {
            process = null;
            if (_mixedMode) {
                return VSConstants.E_NOTIMPL;
            }

            Debug.WriteLine("--------------------------------------------------------------------------------");
            Debug.WriteLine("PythonEngine LaunchSuspended Begin " + launchFlags + " " + GetHashCode());
            AssertMainThread();
            Debug.Assert(_events == null);
            Debug.Assert(_process == null);
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            _events = ad7Callback;
            _engineCreated = _programCreated = false;
            _loadComplete.Reset();

            if (options != null) {
                ParseOptions(options);
            }

            Send(new AD7CustomEvent(VsPackageMessage.SetDebugOptions, this), AD7CustomEvent.IID, null, null);

            // If this is a windowed application, there's no console to wait on, so disable those flags if they were set.
            if (_debugOptions.HasFlag(PythonDebugOptions.IsWindowsApplication)) {
                _debugOptions &= ~(PythonDebugOptions.WaitOnNormalExit | PythonDebugOptions.WaitOnAbnormalExit);
            }

            Guid processId;
            if (_debugOptions.HasFlag(PythonDebugOptions.AttachRunning)) {
                if (!Guid.TryParse(exe, out processId)) {
                    Debug.Fail("When PythonDebugOptions.AttachRunning is used, the 'exe' parameter must be a debug session GUID.");
                    return VSConstants.E_INVALIDARG;
                }

                _process = DebugConnectionListener.GetProcess(processId);
                _attached = true;
                _pseudoAttach = true;
            } else {
                _process = new PythonProcess(_languageVersion, exe, args, dir, env, _interpreterOptions, _debugOptions, _dirMapping);
            }

            if (!_debugOptions.HasFlag(PythonDebugOptions.AttachRunning)) {
                _process.Start(false);
            }

            AttachEvents(_process);

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

            EngineUtils.RequireOk(port.GetProcess(adProcessId, out process));
            Debug.WriteLine("PythonEngine LaunchSuspended returning S_OK");
            Debug.Assert(process != null);
            Debug.Assert(!_process.HasExited);

            return VSConstants.S_OK;
        }
Exemplo n.º 37
0
 int IDebugEngineLaunch2.LaunchSuspended(string pszServer, IDebugPort2 pPort, string pszExe, string pszArgs, string pszDir, string bstrEnv, string pszOptions, enum_LAUNCH_FLAGS dwLaunchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 pCallback, out IDebugProcess2 ppProcess)
 {
     ppProcess    = new AD7Process(pPort);
     this.process = ppProcess;
     callback     = new AD7.EngineCallback(this, pCallback);
     return(0);
 }
Exemplo n.º 38
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(_pollThread == null);
            Debug.Assert(_engineCallback == null);
            Debug.Assert(_debuggedProcess == null);
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            // Check if the logger was enabled late.
            Logger.LoadMIDebugLogger(_configStore);

            process = null;

            _engineCallback = new EngineCallback(this, ad7Callback);

            Exception exception;

            try
            {
                // Note: LaunchOptions.GetInstance can be an expensive operation and may push a wait message loop
                LaunchOptions launchOptions = LaunchOptions.GetInstance(_configStore, exe, args, dir, options, _engineCallback, TargetEngine.Native, Logger);

                // We are being asked to debug a process when we currently aren't debugging anything
                _pollThread = new WorkerThread(Logger);
                var cancellationTokenSource = new CancellationTokenSource();

                using (cancellationTokenSource)
                {
                    _pollThread.RunOperation(ResourceStrings.InitializingDebugger, cancellationTokenSource, (HostWaitLoop waitLoop) =>
                    {
                        try
                        {
                            _debuggedProcess = new DebuggedProcess(true, launchOptions, _engineCallback, _pollThread, _breakpointManager, this, _configStore);
                        }
                        finally
                        {
                            // If there is an exception from the DebuggeedProcess constructor, it is our responsibility to dispose the DeviceAppLauncher,
                            // otherwise the DebuggedProcess object takes ownership.
                            if (_debuggedProcess == null && launchOptions.DeviceAppLauncher != null)
                            {
                                launchOptions.DeviceAppLauncher.Dispose();
                            }
                        }

                        _pollThread.PostedOperationErrorEvent += _debuggedProcess.OnPostedOperationError;

                        return _debuggedProcess.Initialize(waitLoop, cancellationTokenSource.Token);
                    });
                }

                EngineUtils.RequireOk(port.GetProcess(_debuggedProcess.Id, out process));

                return Constants.S_OK;
            }
            catch (Exception e) when (ExceptionHelper.BeforeCatch(e, Logger, reportOnlyCorrupting: true))
            {
                exception = e;
                // Return from the catch block so that we can let the exception unwind - the stack can get kind of big
            }

            // 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.
            Logger.Flush();
            SendStartDebuggingError(exception);

            Dispose();

            return Constants.E_ABORT;
        }
Exemplo n.º 39
0
        public int LaunchSuspended(string server, IDebugPort2 port, string exe, string args, string directory, string environment, string options, enum_LAUNCH_FLAGS launchFlags, uint standardInput, uint standardOutput, uint standardError, IDebugEventCallback2 callback, out IDebugProcess2 process)
        {
            processId = new AD_PROCESS_ID();
            processId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
            processId.guidProcessId = Guid.NewGuid();

            EngineUtils.CheckOk(port.GetProcess(processId, out process));
            this.Callback = callback;

            Session              = new SoftDebuggerSession();
            Session.TargetReady += (sender, eventArgs) =>
            {
                var activeThread = Session.ActiveThread;
                threadManager.Add(activeThread, new MonoThread(this, activeThread));

/*
 *              Session.Stop();
 *              var location = activeThread.Location;
 *              var backtrace = activeThread.Backtrace;
 *              var locations = Session.VirtualMachine.RootDomain.GetAssemblies().Select(x => x.Location).ToArray();
 *              Session.Continue();
 */

                MonoEngineCreateEvent.Send(this);
                MonoProgramCreateEvent.Send(this);
            };
            Session.ExceptionHandler          = exception => true;
            Session.TargetExceptionThrown    += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetExited             += (sender, x) => Send(new MonoProgramDestroyEvent((uint?)x.ExitCode ?? 0), MonoProgramDestroyEvent.IID, null);
            Session.TargetUnhandledException += (sender, x) => Console.WriteLine(x.Type);
            Session.LogWriter            = (stderr, text) => Console.WriteLine(text);
            Session.OutputWriter         = (stderr, text) => Console.WriteLine(text);
            Session.TargetThreadStarted += (sender, x) => threadManager.Add(x.Thread, new MonoThread(this, x.Thread));
            Session.TargetThreadStopped += (sender, x) => threadManager.Remove(x.Thread);
            Session.TargetStopped       += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetStarted       += (sender, x) => Console.WriteLine();
            Session.TargetSignaled      += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetInterrupted   += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetHitBreakpoint += (sender, x) =>
            {
                var breakpoint        = x.BreakEvent as Breakpoint;
                var pendingBreakpoint = breakpointManager[breakpoint];
                Send(new MonoBreakpointEvent(new MonoBoundBreakpointsEnum(pendingBreakpoint.BoundBreakpoints)), MonoBreakpointEvent.IID, threadManager[x.Thread]);
            };

            return(VSConstants.S_OK);
        }