Ejemplo n.º 1
0
        public int AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort)
        {
            ppPort = null;

            string name;
            pRequest.GetPortName(out name);

            Match m = _portNameRegex.Match(name);
            if (!m.Success) {
                return Marshal.GetHRForException(new FormatException());
            }

            string secret = m.Groups["secret"].Value;
            string hostName = m.Groups["hostName"].Value;

            ushort portNum = _defaultPort;
            if (m.Groups["portNum"].Success) {
                if (!ushort.TryParse(m.Groups["portNum"].Value, out portNum)) {
                    return Marshal.GetHRForException(new FormatException());
                }
            }

            var port = new JRemoteDebugPort(this, hostName, portNum, secret, _useSsl);
            ppPort = port;
            return 0;
        }
Ejemplo n.º 2
0
 public ScriptDebugProcess(IDebugPort2 debugPort)
 {
     Log.Debug("Process: Constructor");
     Id = Guid.NewGuid();
     _port = debugPort;
     Node = new ScriptProgramNode(this);
 }
Ejemplo n.º 3
0
        string _sessionName; // has no value assigned because the method that uses it is "[DEPRECATED. SHOULD ALWAYS RETURN E_NOTIMPL.]"

        #endregion Fields

        #region Constructors

        public AD7Process(EngineCallback aCallback, AD7Engine aEngine, IDebugPort2 aPort)
        {
            _callback = aCallback;
            _engine = aEngine;
            _port = aPort;
            m_program = aEngine.m_program;
            //                m_program = new AD7Program(this, _callback, _engine.eDispatcher);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Gets a port by it's guid.
 /// </summary>
 public int GetPort(ref Guid guidPort, out IDebugPort2 ppPort)
 {
     DLog.Debug(DContext.VSDebuggerComCall, "DebugPortSupplier.GetPort");
     var guid = guidPort;
     var port = ports.Values.FirstOrDefault(x => x.Guid == guid);
     ppPort = port;
     return (port != null) ? VSConstants.S_OK : VSConstants.S_FALSE;
 }
Ejemplo n.º 5
0
 /// <summary>
 /// Add a port.
 /// </summary>
 public int AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort)
 {
     DLog.Debug(DContext.VSDebuggerComCall, "DebugPortSupplier.AddPort");
     string name;
     ErrorHandler.ThrowOnFailure(pRequest.GetPortName(out name));
     var port = new DebugPort(this, pRequest);
     ports[name] = port;
     ppPort = port;
     return VSConstants.S_OK;
 }
Ejemplo n.º 6
0
        public int AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort) {
            string name;
            Marshal.ThrowExceptionForHR(pRequest.GetPortName(out name));

            if (name != PortName) {
                ppPort = null;
                return VSConstants.E_INVALIDARG;
            }

            ppPort = new DebugPort(this, pRequest);
            return VSConstants.S_OK;
        }
Ejemplo n.º 7
0
        public int EnumPorts(out IEnumDebugPorts2 ppEnum)
        {
            ConnectionInfoStore store = new ConnectionInfoStore();
            IDebugPort2[] ports = new IDebugPort2[store.Connections.Count];

            for (int i = 0; i < store.Connections.Count; i++)
            {
                ConnectionInfo connectionInfo = (ConnectionInfo)store.Connections[i];
                ports[i] = new AD7Port(this, ConnectionManager.GetFormattedConnectionName(connectionInfo), isInAddPort: false);
            }

            ppEnum = new AD7PortEnum(ports);
            return HR.S_OK;
        }
Ejemplo n.º 8
0
        public int AddPort(IDebugPortRequest2 request, out IDebugPort2 port)
        {
            string name;
            HR.Check(request.GetPortName(out name));

            AD7Port newPort = new AD7Port(this, name, isInAddPort: true);

            if (newPort.IsConnected)
            {
                port = newPort;
                return HR.S_OK;
            }

            port = null;
            return HR.E_REMOTE_CONNECT_USER_CANCELED;
        }
Ejemplo n.º 9
0
        public int AddPort(IDebugPortRequest2 request, out IDebugPort2 port)
        {
            var debugSessionMetrics = new DebugSessionMetrics(_metrics);

            debugSessionMetrics.UseNewDebugSessionId();
            var actionRecorder = new ActionRecorder(debugSessionMetrics);

            port = null;

            if (request.GetPortName(out string gameletIdOrName) != VSConstants.S_OK)
            {
                return(VSConstants.E_FAIL);
            }

            var action        = actionRecorder.CreateToolAction(ActionType.GameletGet);
            var gameletClient = _gameletClientFactory.Create(_cloudRunner.Intercept(action));
            var gameletTask   = _cancelableTaskFactory.Create(
                "Querying instance...",
                async() => await gameletClient.LoadByNameOrIdAsync(gameletIdOrName));

            try
            {
                gameletTask.RunAndRecord(action);
            }
            catch (CloudException e)
            {
                Trace.WriteLine(e.ToString());
                _dialogUtil.ShowError(e.Message);
                return(VSConstants.S_OK);
            }

            var debugPort = _debugPortFactory.Create(gameletTask.Result, this,
                                                     debugSessionMetrics.DebugSessionId);

            _ports.Add(debugPort);
            port = debugPort;
            return(VSConstants.S_OK);
        }
Ejemplo n.º 10
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);
        }
        public void RemoteDeployNotCalledDuringAttachToCore(enum_ATTACH_REASON attachReason)
        {
            var gamelet = new Gamelet {
                IpAddr = _gameletIp
            };
            var expectedTarget = new SshTarget(gamelet);
            IDebugSessionLauncher debugSessionLauncher =
                CreateConfiguredDebugSessionLauncher(expectedTarget, x => {
                var attachedProgram = Substitute.For <ILldbAttachedProgram>();
                return(Task.FromResult(attachedProgram));
            });

            IDebugSessionLauncherFactory debugSessionLauncherFactory =
                CreateDebugSessionLauncherFactory(debugSessionLauncher);
            int calls        = 0;
            var remoteDeploy = Substitute.For <IRemoteDeploy>();

            remoteDeploy.DeployLldbServerAsync(expectedTarget, Arg.Any <IAction>()).Returns(x => {
                calls++;
                return(Task.CompletedTask);
            });
            IGgpDebugEngine debugEngine =
                CreateGgpDebugEngine(debugSessionLauncherFactory, remoteDeploy);
            IDebugPort2 debugPort = CreateDebugPort(gamelet);
            string      options   = null;

            debugEngine.LaunchSuspended("", debugPort, _exePath, null, null, null, options,
                                        enum_LAUNCH_FLAGS.LAUNCH_DEBUG, 0, 0, 0, null,
                                        out IDebugProcess2 _);
            IDebugProgram2 program = CreateDebugProgram(debugPort);

            IDebugProgram2[] rgpPrograms = { program };
            var rgpProgramNodes          = new[] { Substitute.For <IDebugProgramNode2>() };

            debugEngine.Attach(rgpPrograms, rgpProgramNodes, _celtPrograms, null, attachReason);

            Assert.That(calls, Is.EqualTo(0));
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int RemovePort(IDebugPort2 pPort)
        {
            //
            // Removes a port. This method removes the port from the port supplier's internal list of active ports.
            //

            LoggingUtils.PrintFunction();

            try
            {
                LoggingUtils.RequireOk(pPort.GetPortId(out Guid portId));

                m_registeredPorts.Remove(portId);

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

                return(Constants.E_FAIL);
            }
        }
Ejemplo n.º 13
0
        // Qualifier for our transport has one of the following formats:
        //
        //   tcp[s]://[secret@]hostname[:port]
        //   ws[s]://[secret@]hostname[:port][/path]
        //   [secret@]hostname[:port]
        //
        // 'tcp' and 'tcps' are for connecting directly to ptvsd; 'ws' and 'wss' are for connecting through WebSocketProxy.
        // The versions ending with '...s' use SSL to secure the connection. If no scheme is specified, 'tcp' is the default.
        // If port is not specified, it defaults to 5678 for 'tcp' and 'tcps', 80 for 'ws' and 443 for 'wss'.
        public int AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort) {
            ppPort = null;

            string name;
            pRequest.GetPortName(out name);

            // Support old-style 'hostname:port' format, as well.
            if (!name.Contains("://")) {
                name = "tcp://" + name;
            }

            var uri = new Uri(name, UriKind.Absolute);
            var transport = DebuggerTransportFactory.Get(uri);
            if (transport == null) {
                MessageBox.Show(string.Format("Unrecognized remote debugging transport '{0}'.", uri.Scheme), null, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return VSConstants.E_FAIL;
            }

            var validationError = transport.Validate(uri);
            if (validationError != null) {
                return validationError.HResult;
            }

            var port = new PythonRemoteDebugPort(this, pRequest, uri);

            // Validate connection early. Debugger automation (DTE) objects are not consistent in error checking from this
            // point on, so errors reported from EnumProcesses and further calls may be ignored and treated as successes
            // (with empty result). Reporting an error here works around that.
            IEnumDebugProcesses2 processes;
            int hr = port.EnumProcesses(out processes);
            if (hr < 0) {
                return hr;
            }

            ppPort = port;
            return VSConstants.S_OK;
        }
        // Qualifier for our transport is parsed either as a tcp://, ws:// or ws:// URI,
        // or as 'hostname:port', where ':port' is optional.
        public int AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort) {
            ppPort = null;

            string name;
            pRequest.GetPortName(out name);

            // Support old-style 'hostname:port' format, as well.
            if (!name.Contains("://")) {
                name = "tcp://" + name;
            }

            var uri = new Uri(name, UriKind.Absolute);
            switch (uri.Scheme) {
                case "tcp":
                    // tcp:// URI should only specify host and optionally port, path has no meaning and is invalid.
                    if (uri.PathAndQuery != "/") {
                        return new FormatException().HResult;
                    }
                    // Set default port if not specified.
                    if (uri.Port < 0) {
                        uri = new UriBuilder(uri) { Port = NodejsConstants.DefaultDebuggerPort }.Uri;
                    }
                    break;

                case "ws":
                case "wss":
                    // WebSocket URIs are used as is
                    break;

                default:
                    // Anything else is not a valid debugger endpoint
                    return new FormatException().HResult;
            }

            ppPort = new NodeRemoteDebugPort(this, pRequest, uri);
            return VSConstants.S_OK;
        }
Ejemplo n.º 15
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);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int EnumPorts(out IEnumDebugPorts2 ppEnum)
        {
            //
            // Retrieves a list of all the ports supplied by a port supplier.
            //

            LoggingUtils.PrintFunction();

            try
            {
                AndroidAdb.Refresh();

                var connectedDevices = AndroidAdb.GetConnectedDevices();

                foreach (var device in connectedDevices)
                {
                    LoggingUtils.RequireOk(AddPort(new DevicePortRequest(device), out IDebugPort2 ppPort));
                }

                IDebugPort2 [] ports = new IDebugPort2 [m_registeredPorts.Count];

                m_registeredPorts.Values.CopyTo(ports, 0);

                ppEnum = new DebugPortEnumerator(ports);

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

                ppEnum = null;

                return(Constants.E_FAIL);
            }
        }
Ejemplo n.º 17
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);
            }
        }
Ejemplo n.º 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(_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;
        }
Ejemplo n.º 19
0
 public int GetPort(out IDebugPort2 ppPort)
 {
   ppPort = _port;
   return VSConstants.S_OK;
 }
Ejemplo n.º 20
0
 int IDebugPortSupplier2.GetPort(ref Guid guidPort, out IDebugPort2 ppPort)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 21
0
 public int GetPort(out IDebugPort2 ppPort)
 {
     ppPort = this._port;
     return(VSConstants.S_OK);
 }
Ejemplo n.º 22
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);
        }
Ejemplo n.º 23
0
 public int RemovePort(IDebugPort2 pPort)
 {
     return(VSConstants.S_OK);
 }
Ejemplo n.º 24
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #region IDebugPortSupplier2 Members

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort)
        {
            //
            // Attempt to find a port matching the requested name, otherwise one is created.
            //

            LoggingUtils.PrintFunction();

            try
            {
                string requestPortName;

                LoggingUtils.RequireOk(CanAddPort());

                LoggingUtils.RequireOk(pRequest.GetPortName(out requestPortName));

                if (string.IsNullOrWhiteSpace(requestPortName))
                {
                    throw new InvalidOperationException("Invalid/empty port name");
                }

                ppPort = null;

                foreach (KeyValuePair <Guid, IDebugPort2> keyPair in m_registeredPorts)
                {
                    string portName;

                    IDebugPort2 registeredPort = keyPair.Value;

                    LoggingUtils.RequireOk(registeredPort.GetPortName(out portName));

                    if (portName.Equals(requestPortName))
                    {
                        ppPort = registeredPort;

                        break;
                    }
                }

                if (ppPort == null)
                {
                    //
                    // Create and track a new port for this request.
                    //

                    Guid portId;

                    LoggingUtils.RequireOk(CreatePort(pRequest, out ppPort));

                    LoggingUtils.RequireOk(ppPort.GetPortId(out portId));

                    m_registeredPorts.Add(portId, ppPort);
                }

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

                ppPort = null;

                return(Constants.E_FAIL);
            }
        }
Ejemplo n.º 25
0
 public int GetPort(ref Guid guidPort, out IDebugPort2 ppPort)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 26
0
 internal AD7Process(IDebugPort2 port, AD_PROCESS_ID processId)
 {
     _port = port;
     this.PhysicalProcessId = processId;
 }
Ejemplo n.º 27
0
        /// <summary>
        /// Adds a port. (http://msdn.microsoft.com/en-ca/library/bb161980.aspx)
        /// </summary>
        /// <param name="pRequest"> An IDebugPortRequest2 object that describes the port to be added. </param>
        /// <param name="ppPort"> Returns an IDebugPort2 object that represents the port. </param>
        /// <returns> VSConstants.S_OK. </returns>
        public int AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort)
        {
            bool sucess = true;
            AD7PortRequest port_request = null;
            AD7Port port = null;
            try
            {
                port_request = (AD7PortRequest)pRequest;
            }
            catch
            {
                sucess = false;
                string portRequestName;
                AD7Port defaultPort = null;
                pRequest.GetPortName(out portRequestName);
                string search = "";
                if (portRequestName.ToLower().Contains("device"))
                    search = "device";
                else if (portRequestName.ToLower().Contains("simulator"))
                    search = "simulator";
                else
                {
                    search = portRequestName.ToLower();
                }
                foreach (var p in m_ports)
                {
                    AD7Port tempPort = p.Value;
                    if (defaultPort == null)
                        defaultPort = tempPort;

                    string tempPortName = "";
                    tempPort.GetPortName(out tempPortName);
                    if (tempPortName.ToLower().Contains(search))
                    {
                        port = tempPort;
                        break;
                    }
                    else
                    {
                        string IP = search;
                        do
                        {
                            int pos = IP.LastIndexOf('.');
                            if (pos != -1)
                            {
                                IP = IP.Remove(pos);
                                if (tempPortName.Contains(IP))
                                {
                                    port = tempPort;
                                    break;
                                }
                            }
                            else
                                IP = "";
                        } while (IP != "");
                        if (IP != "")
                            break;
                    }
                }
                if (port == null)
                {
                    if (defaultPort != null)
                    {
                        port = defaultPort;
                    }
                    else
                        port = new AD7Port(this, port_request, Guid.NewGuid(), "", "", true, "");
                }
            }
            if (sucess)
            {
                port = CreatePort(port_request);
                Guid portGuid;
                port.GetPortId(out portGuid);
                m_ports.Add(portGuid, port);
            }
            ppPort = port;
            return VSConstants.S_OK;
        }
Ejemplo n.º 28
0
 /// <summary>
 /// Gets a port from a port supplier. (http://msdn.microsoft.com/en-ca/library/bb161812.aspx)
 /// </summary>
 /// <param name="guidPort"> Globally unique identifier (GUID) of the port. </param>
 /// <param name="ppPort"> Returns an IDebugPort2 object that represents the port. </param>
 /// <returns> VSConstants.S_OK. </returns>
 public int GetPort(ref Guid guidPort, out IDebugPort2 ppPort)
 {
     ppPort = m_ports[guidPort];
     return VSConstants.S_OK;
 }
Ejemplo n.º 29
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;
 }
Ejemplo n.º 30
0
 /// <summary>
 /// Removes a port. Not implemented. (http://msdn.microsoft.com/en-ca/library/bb162306.aspx)
 /// </summary>
 /// <param name="pPort"> An IDebugPort2 object that represents the port to be removed. </param>
 /// <returns> Not implemented. It should returns S_OK if successful; or an error code. </returns>
 public int RemovePort(IDebugPort2 pPort)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 31
0
 /// <summary>
 /// Gets a port from a port supplier. (http://msdn.microsoft.com/en-ca/library/bb161812.aspx)
 /// </summary>
 /// <param name="guidPort"> Globally unique identifier (GUID) of the port. </param>
 /// <param name="ppPort"> Returns an IDebugPort2 object that represents the port. </param>
 /// <returns> VSConstants.S_OK. </returns>
 public int GetPort(ref Guid guidPort, out IDebugPort2 ppPort)
 {
     ppPort = m_ports[guidPort];
     return(VSConstants.S_OK);
 }
Ejemplo n.º 32
0
 /// <summary>
 /// Adds a port.
 /// </summary>
 /// <param name="pRequest">An IDebugPortRequest2 object that describes the port to be added.</param>
 /// <param name="ppPort">Returns an IDebugPort2 object that represents the port.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 /// <remarks>
 /// This method actually creates the requested port as well as adding it to the port supplier's internal list of active ports. The IDebugPortSupplier2::CanAddPort method can be called first to avoid possible time-consuming delays.
 /// </remarks>
 public virtual int AddPort( IDebugPortRequest2 pRequest, out IDebugPort2 ppPort )
 {
     Logger.Debug( string.Empty );
     ppPort = null;
     return VSConstants.E_NOTIMPL;
 }
Ejemplo n.º 33
0
 /// <summary>
 /// Gets the port that the process is running on.
 /// </summary>
 /// <param name="ppPort">Returns an IDebugPort2 object that represents the port on which the process was launched.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 public virtual int GetPort( out IDebugPort2 ppPort )
 {
     Logger.Debug( string.Empty );
     ppPort = null;
     return VSConstants.E_NOTIMPL;
 }
Ejemplo n.º 34
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;
        }
Ejemplo 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.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;
        }
Ejemplo n.º 36
0
 public override int AddPort(IDebugPortRequest2 request, out IDebugPort2 port)
 {
     // This should never be called
     Debug.Fail("Why is AddPort called?");
     throw new NotImplementedException();
 }
Ejemplo n.º 37
0
 /// <summary>
 /// Removes a port. Not implemented. (http://msdn.microsoft.com/en-ca/library/bb162306.aspx)
 /// </summary>
 /// <param name="pPort"> An IDebugPort2 object that represents the port to be removed. </param>
 /// <returns> Not implemented. It should returns S_OK if successful; or an error code. </returns>
 public int RemovePort(IDebugPort2 pPort)
 {
     throw new NotImplementedException();
 }
 public int AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort)
 {
     thePort = new SquirrelPort(this, pRequest);
     ppPort  = (IDebugPort2)thePort;
     return(Microsoft.VisualStudio.VSConstants.S_OK);
 }
Ejemplo n.º 39
0
 public int GetPort(out IDebugPort2 port)
 {
     port = _port;
     return(HR.S_OK);
 }
Ejemplo n.º 40
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;
        }
Ejemplo n.º 41
0
 public int RemovePort(IDebugPort2 pPort)
 {
     return(VSConstants.E_NOTIMPL);
 }
Ejemplo n.º 42
0
 public int AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 43
0
 public int RemovePort(IDebugPort2 pPort)
 {
     return 0;
 }
Ejemplo n.º 44
0
 public int GetPort(out IDebugPort2 ppPort)
 {
     ppPort = _port;
     return(0);
 }
Ejemplo n.º 45
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;
        }
Ejemplo n.º 46
0
 // Token: 0x0600018B RID: 395 RVA: 0x00006252 File Offset: 0x00004452
 public int GetPort(out IDebugPort2 outPort)
 {
     outPort = this.Port;
     return(0);
 }
Ejemplo n.º 47
0
 public int GetPort(ref Guid guidPort, out IDebugPort2 ppPort)
 {
     ppPort = null;
     return(VSConstants.E_NOTIMPL);
 }
Ejemplo n.º 48
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="aEngine"> The AD7Engine object that represents the DE. </param>
 /// <param name="aPort"> The IDebugPort2 object that represents the port on which the process was launched. </param>
 public AD7Process(AD7Engine aEngine, IDebugPort2 aPort)
 {
     _engine   = aEngine;
     _port     = aPort;
     m_program = aEngine.m_program;
 }
Ejemplo n.º 49
0
 public int GetPort(ref Guid guidPort, out IDebugPort2 ppPort)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 50
0
 public virtual IDebugProcess2 Create(
     IDebugPort2 port, uint pid, string title, string command)
 {
     return(new DebugProcess(debugProgramFactory, port, pid, title, command));
 }
Ejemplo n.º 51
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;
      }
    }
Ejemplo n.º 52
0
 public MonoProcess(IDebugPort2 pPort)
 {
     Id = Guid.NewGuid();
     _port = pPort;
 }
Ejemplo n.º 53
0
 int IDebugPortSupplier2.AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 54
0
 public int GetPort(out IDebugPort2 ppPort)
 {
     DebugHelper.TraceEnteringMethod();
     ppPort = _port;
     return VSConstants.S_OK;
 }
Ejemplo n.º 55
0
 int IDebugPortSupplier2.RemovePort(IDebugPort2 pPort)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 56
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);
        }
Ejemplo n.º 57
0
 public AD7Process(IDebugPort2 debugPort)
 {
   Id = Guid.NewGuid();
   _port = debugPort;
   Node = new AD7ProgramNode(this);
 }
Ejemplo n.º 58
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;
        }
Ejemplo n.º 59
0
        private LaunchOptions CreateAttachLaunchOptions(uint processId, IDebugPort2 port)
        {
            LaunchOptions launchOptions;

            var unixPort = port as IDebugUnixShellPort;

            if (unixPort != null)
            {
                MIMode miMode;
                if (_engineGuid == EngineConstants.ClrdbgEngine)
                {
                    miMode = MIMode.Clrdbg;
                }
                else if (_engineGuid == EngineConstants.GdbEngine)
                {
                    miMode = MIMode.Gdb;
                }
                else
                {
                    // TODO: LLDB support
                    throw new NotImplementedException();
                }

                if (processId > int.MaxValue)
                {
                    throw new ArgumentOutOfRangeException("processId");
                }

                string getClrDbgUrl = GetMetric("GetClrDbgUrl") as string;
                string remoteDebuggerInstallationDirectory    = GetMetric("RemoteInstallationDirectory") as string;
                string remoteDebuggerInstallationSubDirectory = GetMetric("RemoteInstallationSubDirectory") as string;
                string clrDbgVersion = GetMetric("ClrDbgVersion") as string;

                launchOptions = UnixShellPortLaunchOptions.CreateForAttachRequest(unixPort,
                                                                                  (int)processId,
                                                                                  miMode,
                                                                                  getClrDbgUrl,
                                                                                  remoteDebuggerInstallationDirectory,
                                                                                  remoteDebuggerInstallationSubDirectory,
                                                                                  clrDbgVersion);

                // TODO: Add a tools option page for:
                // AdditionalSOLibSearchPath
                // VisualizerFile?
            }
            else
            {
                // TODO: when we have a tools options page, we can add support for the attach dialog here pretty easily:
                //var defaultPort = port as IDebugDefaultPort2;
                //if (defaultPort != null && defaultPort.QueryIsLocal() == Constants.S_OK)
                //{
                //    launchOptions = new LocalLaunchOptions(...);
                //}
                //else
                //{
                //    // Invalid port
                //    throw new ArgumentException();
                //}

                throw new NotSupportedException();
            }

            return(launchOptions);
        }
Ejemplo n.º 60
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;
        }