示例#1
0
        protected override async Task <CommandProcessorThread> ConnectAsync(CancellationToken ct)
        {
            var remoteProcess = _process as PythonRemoteProcess;

            try {
                _serviceProvider.GetPythonToolsService().Logger.LogEvent(Logging.PythonLogEvent.DebugRepl, new Logging.DebugReplInfo {
                    RemoteProcess = remoteProcess != null,
                    Version       = _process.LanguageVersion.ToVersion().ToString()
                });
            } catch (Exception ex) {
                Debug.Fail(ex.ToUnhandledExceptionMessage(GetType()));
            }

            if (remoteProcess == null)
            {
                var conn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                conn.Bind(new IPEndPoint(IPAddress.Loopback, 0));
                conn.Listen(0);
                var portNum = ((IPEndPoint)conn.LocalEndPoint).Port;
                var proc    = System.Diagnostics.Process.GetProcessById(_process.Id);

                var thread = CommandProcessorThread.Create(this, conn, proc);
                await _process.ConnectReplAsync(portNum);

                return(thread);
            }

            // Ignore SSL errors, since user was already prompted about them and chose to ignore them when he attached to this process.
            using (var debugConn = await remoteProcess.ConnectAsync(false, ct)) {
                // After the REPL attach response is received, we go from
                // using the debugger protocol to the REPL protocol.
                // It's important to have a clean break between the 2, and at the right time.
                // The server will send the debugger protocol response for attach
                // before sending anything else and as soon as we read that
                // response, we stop reading any more messages.
                // Then we give the stream to the REPL protocol handler.
                try {
                    var response = await debugConn.SendRequestAsync(new LDP.RemoteReplAttachRequest(), ct, resp => {
                        Debug.WriteLine("Stopping debug connection message processing. Switching from debugger protocol to REPL protocol.");

                        // This causes the message handling loop to exit
                        throw new OperationCanceledException();
                    });

                    if (!response.accepted)
                    {
                        WriteError(Strings.ConnErrorMessages_RemoteAttachRejected);
                        return(null);
                    }

                    // Get the stream out of the connection before Dispose is called,
                    // so that the stream doesn't get closed.
                    var stream = debugConn.DetachStream();
                    return(CommandProcessorThread.Create(this, stream));
                } catch (FailedRequestException ex) {
                    WriteError(ex.Message);
                    return(null);
                }
            }
        }
示例#2
0
            public static CommandProcessorThread Create(
                PythonInteractiveEvaluator evaluator,
                Stream stream
                )
            {
                var thread = new CommandProcessorThread(evaluator, null);

                thread._stream = stream;
                thread.StartOutputThread(false);
                return(thread);
            }
示例#3
0
            public static CommandProcessorThread Create(
                PythonInteractiveEvaluator evaluator,
                Socket listenerSocket,
                Process process
                )
            {
                var thread = new CommandProcessorThread(evaluator, process);

                thread._listenerSocket = listenerSocket;
                thread.StartOutputThread(process.StartInfo.RedirectStandardOutput);
                return(thread);
            }
            public static CommandProcessorThread Create(
                PythonInteractiveEvaluator evaluator,
                Stream stream
                )
            {
                var thread = new CommandProcessorThread(evaluator, null);

                thread._stream = stream;
                // Should be quickly replaced, but it's the best guess we have
                thread._currentWorkingDirectory = Environment.CurrentDirectory;
                thread.StartOutputThread(false);
                return(thread);
            }
 public StreamLock(CommandProcessorThread evaluator, bool throwIfDisconnected)
 {
     Monitor.Enter(evaluator._streamLock);
     try {
         if (throwIfDisconnected)
         {
             evaluator.ThrowIfDisconnected();
         }
         _evaluator = evaluator;
     } catch {
         // If any exceptions are thrown in the constructor, we
         // must exit the lock to avoid a deadlock.
         Monitor.Exit(evaluator._streamLock);
         throw;
     }
 }
        protected override CommandProcessorThread Connect()
        {
            var remoteProcess = _process as PythonRemoteProcess;

            if (remoteProcess == null)
            {
                var conn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                conn.Bind(new IPEndPoint(IPAddress.Loopback, 0));
                conn.Listen(0);
                var portNum = ((IPEndPoint)conn.LocalEndPoint).Port;
                var proc    = System.Diagnostics.Process.GetProcessById(_process.Id);

                var thread = CommandProcessorThread.Create(this, conn, proc);
                _process.ConnectRepl(portNum);
                return(thread);
            }

            // Ignore SSL errors, since user was already prompted about them and chose to ignore them when he attached to this process.
            var  stream    = remoteProcess.Connect(false);
            bool connected = false;

            try {
                stream.Write(PythonRemoteProcess.ReplCommandBytes);

                string attachResp = stream.ReadAsciiString(PythonRemoteProcess.Accepted.Length);
                if (attachResp != PythonRemoteProcess.Accepted)
                {
                    throw new ConnectionException(ConnErrorMessages.RemoteAttachRejected);
                }

                connected = true;
            } finally {
                if (!connected)
                {
                    if (stream != null)
                    {
                        stream.Close();
                    }
                    stream = null;
                }
            }

            return(CommandProcessorThread.Create(this, stream));
        }
 public StreamUnlock(CommandProcessorThread evaluator)
 {
     Debug.Assert(Monitor.IsEntered(evaluator._streamLock));
     _evaluator = evaluator;
     Monitor.Exit(evaluator._streamLock);
 }
示例#8
0
 // Creates a command processor that will use the provided stream as the REPL connection (used for remote debugging REPL).
 protected void CreateCommandProcessor(Stream stream, bool redirectStdOutput, Process process) {
     _curListener = new CommandProcessorThread(this, stream, redirectStdOutput, process);
 }
示例#9
0
 // Creates a command processor that will listen for incoming connections on the socket (used for regular REPL and for local debugging REPL).
 protected void CreateCommandProcessor(Socket listenerSocket, bool redirectStdOutput, Process process) {
     _curListener = new CommandProcessorThread(this, listenerSocket, redirectStdOutput, process);
 }
示例#10
0
 public SocketLock(CommandProcessorThread evaluator)
 {
     Monitor.Enter(evaluator._socketLock);
     #if DEBUG
     Debug.Assert(evaluator._socketLockedThread == null);
     evaluator._socketLockedThread = Thread.CurrentThread;
     #endif
     _evaluator = evaluator;
 }
示例#11
0
 public StreamUnlock(CommandProcessorThread evaluator) {
     Debug.Assert(Monitor.IsEntered(evaluator._streamLock));
     _evaluator = evaluator;
     Monitor.Exit(evaluator._streamLock);
 }
示例#12
0
                public StreamLock(CommandProcessorThread evaluator, bool throwIfDisconnected) {
                    Monitor.Enter(evaluator._streamLock);
                    try {
                        if (throwIfDisconnected) {
                            evaluator.ThrowIfDisconnected();
                        }
                        _evaluator = evaluator;

                    } catch {
                        // If any exceptions are thrown in the constructor, we
                        // must exit the lock to avoid a deadlock.
                        Monitor.Exit(evaluator._streamLock);
                        throw;
                    }
                }
 public static CommandProcessorThread Create(
     PythonInteractiveEvaluator evaluator,
     Stream stream
 ) {
     var thread = new CommandProcessorThread(evaluator, null);
     thread._stream = stream;
     // Should be quickly replaced, but it's the best guess we have
     thread._currentWorkingDirectory = Environment.CurrentDirectory;
     thread.StartOutputThread(false);
     return thread;
 }
 public static CommandProcessorThread Create(
     PythonInteractiveEvaluator evaluator,
     Socket listenerSocket,
     Process process
 ) {
     var thread = new CommandProcessorThread(evaluator, process);
     thread._listenerSocket = listenerSocket;
     thread._currentWorkingDirectory = process.StartInfo.WorkingDirectory;
     thread.StartOutputThread(process.StartInfo.RedirectStandardOutput);
     return thread;
 }
示例#15
0
 public SocketUnlock(CommandProcessorThread evaluator)
 {
     #if DEBUG
     Debug.Assert(evaluator._socketLockedThread == Thread.CurrentThread);
     evaluator._socketLockedThread = null;
     #endif
     _evaluator = evaluator;
     Monitor.Exit(evaluator._socketLock);
 }
示例#16
0
 public virtual void Close() {
     if (_curListener != null) {
         _curListener.Dispose();
         _curListener = null;
     }
     _attached = false;
 }
        protected virtual Task <CommandProcessorThread> ConnectAsync(CancellationToken ct)
        {
            _serviceProvider.GetUIThread().MustBeCalledFromUIThreadOrThrow();

            var interpreterPath = Configuration?.GetInterpreterPath();

            if (string.IsNullOrWhiteSpace(interpreterPath))
            {
                WriteError(Strings.ReplEvaluatorInterpreterNotConfigured.FormatUI(DisplayName));
                return(null);
            }
            else if (!File.Exists(interpreterPath))
            {
                WriteError(Strings.ReplEvaluatorInterpreterNotFound);
                return(null);
            }

            var processInfo = new ProcessStartInfo(interpreterPath);

#if DEBUG
            bool debugMode = Environment.GetEnvironmentVariable("_PTVS_DEBUG_REPL") != null;
            processInfo.CreateNoWindow         = !debugMode;
            processInfo.UseShellExecute        = debugMode;
            processInfo.RedirectStandardOutput = !debugMode;
            processInfo.RedirectStandardError  = !debugMode;
            processInfo.RedirectStandardInput  = !debugMode;
#else
            processInfo.CreateNoWindow         = true;
            processInfo.UseShellExecute        = false;
            processInfo.RedirectStandardOutput = true;
            processInfo.RedirectStandardError  = true;
            processInfo.RedirectStandardInput  = true;
#endif

            var conn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
            conn.Bind(new IPEndPoint(IPAddress.Loopback, 0));
            conn.Listen(0);
            var portNum = ((IPEndPoint)conn.LocalEndPoint).Port;

            var workingDirectory = Configuration.WorkingDirectory;
            if (!string.IsNullOrEmpty(workingDirectory))
            {
                processInfo.WorkingDirectory = workingDirectory;
            }
            else
            {
                processInfo.WorkingDirectory = CommonUtils.GetParent(processInfo.FileName);
            }

#if DEBUG
            if (!debugMode)
            {
#endif
            var env = processInfo.Environment;
            foreach (var kv in _serviceProvider.GetPythonToolsService().GetFullEnvironment(Configuration))
            {
                env[kv.Key] = kv.Value;
            }
#if DEBUG
        }
#endif

            var args = new List <string>();
            var interpreterArguments = Configuration.InterpreterArguments;
            if (!string.IsNullOrWhiteSpace(interpreterArguments))
            {
                args.Add(interpreterArguments);
            }

            args.Add(ProcessOutput.QuoteSingleArgument(PythonToolsInstallPath.GetFile("visualstudio_py_repl.py")));
            args.Add("--port");
            args.Add(portNum.ToString());

            args.Add("--execution-mode");
            args.Add(string.IsNullOrEmpty(BackendName) ? "standard" : BackendName);

            processInfo.Arguments = string.Join(" ", args);

            Process process;
            try {
                if (!File.Exists(processInfo.FileName))
                {
                    throw new Win32Exception(Microsoft.VisualStudioTools.Project.NativeMethods.ERROR_FILE_NOT_FOUND);
                }
                process = Process.Start(processInfo);
                if (process.WaitForExit(100))
                {
                    throw new Win32Exception(process.ExitCode);
                }
            } catch (Win32Exception e) {
                if (e.NativeErrorCode == Microsoft.VisualStudioTools.Project.NativeMethods.ERROR_FILE_NOT_FOUND)
                {
                    WriteError(Strings.ReplEvaluatorInterpreterNotFound);
                }
                else
                {
                    WriteError(Strings.ErrorStartingInteractiveProcess.FormatUI(e.ToString()));
                }
                return(null);
            } catch (Exception e) when(!e.IsCriticalException())
            {
                return(null);
            }

            return(Task.FromResult(CommandProcessorThread.Create(this, conn, process)));
        }
 public static CommandProcessorThread Create(
     PythonInteractiveEvaluator evaluator,
     Stream stream
 ) {
     var thread = new CommandProcessorThread(evaluator, null);
     thread._stream = stream;
     thread.StartOutputThread(false);
     return thread;
 }