Beispiel #1
0
        private void OnStartDebuggingFailed(Exception exception)
        {
            Logger.Flush();
            SendStartDebuggingError(exception);

            Dispose();
        }
Beispiel #2
0
 public void Send(string cmd)
 {
     _logger?.WriteLine("<-" + cmd);
     _logger?.Flush();
     _asyncCommand.WriteLine(cmd);
 }
Beispiel #3
0
        private void TransportLoop()
        {
            try
            {
                while (!_bQuit)
                {
                    string line = GetLine();
                    if (line == null)
                    {
                        break;
                    }

                    line = line.TrimEnd();
                    Logger?.WriteLine("->" + line);
                    Logger?.Flush();

                    try
                    {
                        if (_filterStdout)
                        {
                            line = FilterLine(line);
                        }
                        if (!String.IsNullOrWhiteSpace(line) && !line.StartsWith("-", StringComparison.Ordinal))
                        {
                            _callback.OnStdOutLine(line);
                        }
                    }
                    catch (ObjectDisposedException)
                    {
                        Debug.Assert(_bQuit);
                        break;
                    }
                }
                if (!_bQuit)
                {
                    OnReadStreamAborted();
                }
            }
            finally
            {
                lock (_locker)
                {
                    _bQuit = true;
                    _streamReadCancellationTokenSource.Dispose();

                    // If we are shutting down without notice from the debugger (e.g., the terminal
                    // where the debugger was hosted was closed), at this point it's possible that
                    // there is a thread blocked doing a read() syscall.
                    ForceDisposeStreamReader(_reader);

                    try
                    {
                        _writer.Dispose();
                    }
                    catch
                    {
                        // This can fail flush side effects if the debugger goes down. When this happens we don't want
                        // to crash OpenDebugAD7/VS. Stack:
                        //   System.IO.UnixFileStream.WriteNative(Byte[] array, Int32 offset, Int32 count)
                        //   System.IO.UnixFileStream.FlushWriteBuffer()
                        //   System.IO.UnixFileStream.Dispose(Boolean disposing)
                        //   System.IO.FileStream.Dispose(Boolean disposing)
                        //   System.IO.Stream.Close()
                        //   System.IO.StreamWriter.Dispose(Boolean disposing)
                        //   System.IO.TextWriter.Dispose()
                    }
                }
            }
        }
Beispiel #4
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);
        }