int IDebugRemoteCorDebug.DebugActiveProcessEx(IDebugPort2 pPort, uint id, int win32Attach, out object ppProcess)
        {
            ppProcess = null;
            try
            {
                MessageCentre.DebugMessage(Resources.ResourceStrings.Attach);
                AD_PROCESS_ID pid = new AD_PROCESS_ID();

                pid.ProcessIdType = (uint)AD_PROCESS_ID_TYPE.AD_PROCESS_ID_SYSTEM;

                pid.dwProcessId = id;

                IDebugProcess2 iDebugProcess;
                pPort.GetProcess(pid, out iDebugProcess);

                CorDebugProcess process = (CorDebugProcess)iDebugProcess;

                // StartDebugging() will either get a connected device into a debuggable state and start the dispatch thread, or throw.
                process.StartDebugging(this, false);
                ppProcess = process;

                return(COM_HResults.S_OK);
            }
            catch (ProcessExitException)
            {
                MessageCentre.DebugMessage(Resources.ResourceStrings.AttachFailedProcessDied);
                return(COM_HResults.S_FALSE);
            }
            catch (Exception ex)
            {
                MessageCentre.DebugMessage(Resources.ResourceStrings.AttachFailed);
                MessageCentre.InternalErrorMessage(false, ex.Message);
                return(COM_HResults.S_FALSE);
            }
        }
        private IDebugProcess2 GetProcess(IDebugPort2 port)
        {
            IDebugProcess2 process;

            EngineUtils.CheckOk(port.GetProcess(_processId, out process));

            return(process);
        }
예제 #3
0
        public static IDebugProcess2 GetProcess(this IDebugPort2 port, AD_PROCESS_ID processId)
        {
            Contract.Requires <ArgumentNullException>(port != null, "port");

            IDebugProcess2 process;

            ErrorHandler.ThrowOnFailure(port.GetProcess(processId, out process));
            return(process);
        }
예제 #4
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;

            if (string.IsNullOrEmpty(pszOptions))
            {
                return(VSConstants.E_FAIL);
            }

            uint procId;

            if (!uint.TryParse(pszOptions, out procId))
            {
                return(VSConstants.E_FAIL);
            }

            var env = bstrEnv.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
                      .Select(x => x.Split(new[] { '=' }))
                      .Where(x => x.Length >= 2)
                      .ToDictionary(x => x[0], x => x[1].Split(new[] { ';' }));

            if (env.ContainsKey("QTRCC"))
            {
                foreach (var rccFile in env["QTRCC"])
                {
                    FileSystem.RegisterRccFile(rccFile);
                }
            }

            IDebugProcess2 nativeProc;
            var            nativeProcId = new AD_PROCESS_ID
            {
                ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM,
                dwProcessId   = procId
            };

            if (pPort.GetProcess(nativeProcId, out nativeProc) != VSConstants.S_OK)
            {
                return(VSConstants.E_FAIL);
            }

            var program = Program.Create(this, nativeProc, pszExe, pszArgs);

            if (program == null)
            {
                return(VSConstants.E_FAIL);
            }

            programs.Add(program.ProcessId, program);
            ppProcess = program;
            return(VSConstants.S_OK);
        }
예제 #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(_pollThread == null);
            Debug.Assert(_engineCallback == null);
            Debug.Assert(_debuggedProcess == null);
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            process = null;

            _engineCallback = new EngineCallback(this, ad7Callback);

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

                _pollThread.RunOperation(() =>
                {
                    var endpoint     = new IPEndPoint(IPAddress.Parse(args.Split('=')[1]), 8085);
                    _debuggedProcess = new DebuggedProcess(endpoint, _engineCallback, _pollThread, this);

                    _pollThread.PostedOperationErrorEvent += _debuggedProcess.OnPostedOperationError;

                    return(_debuggedProcess.Initialize());
                });

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

                return(VSConstants.S_OK);
            }
            catch (Exception e) when(ExceptionHelper.BeforeCatch(e, reportOnlyCorrupting: true))
            {
                // 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.
                SendStartDebuggingError(e);
            }

            Dispose();

            return(VSConstants.E_ABORT);
        }
예제 #6
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);
        }
예제 #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
            {
                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));
            }
        }
예제 #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(_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);
        }
예제 #9
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);
        }
예제 #10
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);
        }
예제 #11
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;
        }
예제 #12
0
파일: AD7Engine.cs 프로젝트: borota/JTVS
        // 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;
        }
예제 #13
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;
        }
예제 #14
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...");
//                        Debugger.Launch();
                        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);
        }
예제 #15
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);
        }
예제 #16
0
파일: AD7Engine.cs 프로젝트: e42s/VSLua
        // 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;
        }
예제 #17
0
파일: AD7Engine.cs 프로젝트: xiexin36/VSLua
        // 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);
        }
예제 #18
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);
            }
        }
예제 #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) {
            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;
        }
예제 #20
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));
            }
        }
예제 #21
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);
        }
예제 #22
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;
        }
예제 #23
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);
            }
        }
예제 #24
0
        int IDebugRemoteCorDebug.DebugActiveProcessEx( IDebugPort2 pPort, uint id, int win32Attach, out object ppProcess )
        {
            ppProcess = null;
            try
            {
                VsPackage.MessageCentre.DeploymentMsg(DiagnosticStrings.Attach);
                AD_PROCESS_ID pid = new AD_PROCESS_ID();

                pid.ProcessIdType = (uint) AD_PROCESS_ID_TYPE.AD_PROCESS_ID_SYSTEM;

                pid.dwProcessId = id;

                IDebugProcess2 iDebugProcess;
                pPort.GetProcess(pid, out iDebugProcess);

                CorDebugProcess process = (CorDebugProcess) iDebugProcess;

                // StartDebugging() will either get a connected device into a debuggable state and start the dispatch thread, or throw.
                process.StartDebugging(this, false);
                ppProcess = process;

                return Utility.COM_HResults.S_OK;
            }
            catch (ProcessExitException)
            {
                VsPackage.MessageCentre.DeploymentMsg(DiagnosticStrings.AttachFailedProcessDied);
                return Utility.COM_HResults.S_FALSE;
            }
            catch (Exception ex)
            {
                VsPackage.MessageCentre.DeploymentMsg(DiagnosticStrings.AttachFailed);
                VsPackage.MessageCentre.InternalErrorMsg(false, ex.Message);
                return Utility.COM_HResults.S_FALSE;
            }
       }
예제 #25
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);
        }