Beispiel #1
0
        private bool TrySetOperationInternalWithProgress(AsyncProgressOperation op, string text, CancellationTokenSource canTokenSource)
        {
            var waitLoop = new HostWaitLoop(text);

            lock (_eventLock)
            {
                if (_isClosed)
                {
                    throw new ObjectDisposedException("WorkerThread");
                }

                if (_runningOp == null)
                {
                    _runningOpCompleteEvent.Reset();

                    OperationDescriptor runningOp = new OperationDescriptor(new AsyncOperation(() => { return(op(waitLoop)); }));
                    _runningOp = runningOp;

                    _opSet.Set();

                    waitLoop.Wait(_runningOpCompleteEvent, canTokenSource);

                    Debug.Assert(runningOp.IsComplete, "Why isn't the running op complete?");

                    if (runningOp.ExceptionDispatchInfo != null)
                    {
                        runningOp.ExceptionDispatchInfo.Throw();
                    }

                    return(true);
                }
            }

            return(false);
        }
Beispiel #2
0
        void IPlatformAppLauncher.SetupForDebugging(out LaunchOptions result)
        {
            if (_launchOptions == null)
            {
                Debug.Fail("Why is SetupForDebugging being called before ParseLaunchOptions?");
                throw new InvalidOperationException();
            }

            ManualResetEvent doneEvent  = new ManualResetEvent(false);
            var cancellationTokenSource = new CancellationTokenSource();
            ExceptionDispatchInfo exceptionDispatchInfo = null;
            LaunchOptions         localLaunchOptions    = null;

            _waitLoop = new HostWaitLoop(LauncherResources.WaitDialogText);

            // Do the work on a worker thread to avoid blocking the UI. Use ThreadPool.QueueUserWorkItem instead
            // of Task.Run to avoid needing to unwrap the AggregateException.
            ThreadPool.QueueUserWorkItem((object o) =>
            {
                string launchErrorTelemetryResult = null;

                try
                {
                    localLaunchOptions         = SetupForDebuggingWorker(cancellationTokenSource.Token);
                    launchErrorTelemetryResult = "None";
                }
                catch (Exception e)
                {
                    exceptionDispatchInfo = ExceptionDispatchInfo.Capture(e);
                    if (!(e is OperationCanceledException))
                    {
                        launchErrorTelemetryResult = Telemetry.GetLaunchErrorResultValue(e);
                    }
                }

                doneEvent.Set();

                if (launchErrorTelemetryResult != null)
                {
                    Telemetry.SendLaunchError(launchErrorTelemetryResult, _targetEngine.ToString());
                }
            }
                                         );

            _waitLoop.Wait(doneEvent, cancellationTokenSource);

            if (exceptionDispatchInfo != null)
            {
                exceptionDispatchInfo.Throw();
            }
            if (localLaunchOptions == null)
            {
                Debug.Fail("No result provided? Should be impossible.");
                throw new InvalidOperationException();
            }

            result = localLaunchOptions;
        }
Beispiel #3
0
 public virtual void Init(ITransportCallback transportCallback, LaunchOptions options, Logger logger, HostWaitLoop waitLoop = null)
 {
     Logger    = logger;
     _callback = transportCallback;
     InitStreams(options, out _reader, out _writer);
     StartThread(GetThreadName());
 }
Beispiel #4
0
 public void Init(ITransportCallback transportCallback, LaunchOptions options, Logger logger, HostWaitLoop waitLoop = null)
 {
     _launchTimeout = ((LocalLaunchOptions)options).ServerLaunchTimeout;
     _serverTransport.Init(transportCallback, options, logger, waitLoop);
     WaitForStart();
     if (!_clientTransport.IsClosed)
     {
         _clientTransport.Init(transportCallback, options, logger, waitLoop);
     }
 }
Beispiel #5
0
        public void Init(ITransportCallback transportCallback, LaunchOptions options, Logger logger, HostWaitLoop waitLoop = null)
        {
            _launchOptions = (UnixShellPortLaunchOptions)options;
            _callback      = transportCallback;
            _logger        = logger;
            _startRemoteDebuggerCommand = _launchOptions.StartRemoteDebuggerCommand;

            if (_launchOptions.DebuggerMIMode == MIMode.Clrdbg)
            {
                if (!UnixShellPortLaunchOptions.HasSuccessfulPreviousLaunch(_launchOptions))
                {
                    waitLoop?.SetText(MICoreResources.Info_InstallingDebuggerOnRemote);
                    try
                    {
                        Task.Run(() => DownloadAndCopyFileToRemote(_launchOptions.DebuggerInstallationDirectory, _launchOptions.GetClrDbgUrl)).Wait();
                    }
                    catch (Exception e)
                    {
                        // Even if downloading & copying to remote fails, we will still try to invoke the script as it might already exist.
                        string message = String.Format(CultureInfo.CurrentUICulture, MICoreResources.Warning_DownloadingClrDbgToRemote, e.Message);
                        _callback.AppendToInitializationLog(message);
                    }
                }
            }

            _callback.AppendToInitializationLog(string.Format(CultureInfo.CurrentUICulture, MICoreResources.Info_StartingUnixCommand, _startRemoteDebuggerCommand));
            _launchOptions.UnixPort.BeginExecuteAsyncCommand(_startRemoteDebuggerCommand, true, this, out _asyncCommand);
        }
Beispiel #6
0
        public override async void Init(ITransportCallback transportCallback, LaunchOptions options, Logger logger, HostWaitLoop waitLoop = null)
        {
            LocalLaunchOptions localOptions = options as LocalLaunchOptions;

            Encoding encNoBom = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);

            string        commandPipeName;
            string        outputPipeName;
            string        pidPipeName;
            List <string> cmdArgs = new List <string>();

            string windowtitle = FormattableString.Invariant($"cppdbg: {Path.GetFileName(options.ExePath)}");

            if (PlatformUtilities.IsWindows())
            {
                // Create Windows Named pipes
                commandPipeName = Utilities.GetMIEngineTemporaryFilename("In");
                outputPipeName  = Utilities.GetMIEngineTemporaryFilename("Out");
                pidPipeName     = Utilities.GetMIEngineTemporaryFilename("Pid");
                string errorPipeName = Utilities.GetMIEngineTemporaryFilename("Error");

                NamedPipeServerStream inputToDebugger    = new NamedPipeServerStream(commandPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte);
                NamedPipeServerStream outputFromDebugger = new NamedPipeServerStream(outputPipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte);
                NamedPipeServerStream errorFromDebugger  = new NamedPipeServerStream(errorPipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte);
                NamedPipeServerStream pidPipe            = new NamedPipeServerStream(pidPipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte);

                _pidReader = new StreamReader(pidPipe, encNoBom, false, UnixUtilities.StreamBufferSize);

                string thisModulePath = typeof(RunInTerminalTransport).GetTypeInfo().Assembly.ManifestModule.FullyQualifiedName;
                string launchCommand  = Path.Combine(Path.GetDirectoryName(thisModulePath), "WindowsDebugLauncher.exe");

                if (!File.Exists(launchCommand))
                {
                    string errorMessage = string.Format(CultureInfo.CurrentCulture, MICoreResources.Error_InternalFileMissing, launchCommand);
                    transportCallback.OnStdErrorLine(errorMessage);
                    transportCallback.OnDebuggerProcessExit(null);
                    return;
                }

                cmdArgs.Add(launchCommand);
                cmdArgs.Add("--stdin=" + commandPipeName);
                cmdArgs.Add("--stdout=" + outputPipeName);
                cmdArgs.Add("--stderr=" + errorPipeName);
                cmdArgs.Add("--pid=" + pidPipeName);
                cmdArgs.Add("--dbgExe=" + localOptions.MIDebuggerPath);
                cmdArgs.Add(localOptions.GetMiDebuggerArgs());

                _waitForConnection = Task.WhenAll(
                    inputToDebugger.WaitForConnectionAsync(),
                    outputFromDebugger.WaitForConnectionAsync(),
                    errorFromDebugger.WaitForConnectionAsync(),
                    pidPipe.WaitForConnectionAsync());

                _commandStream = new StreamWriter(inputToDebugger, encNoBom);
                _outputStream  = new StreamReader(outputFromDebugger, encNoBom, false, UnixUtilities.StreamBufferSize);
                _errorStream   = new StreamReader(errorFromDebugger, encNoBom, false, UnixUtilities.StreamBufferSize);
            }
            else
            {
                // Do Linux style pipes
                commandPipeName = UnixUtilities.MakeFifo(identifier: "In", logger: logger);
                outputPipeName  = UnixUtilities.MakeFifo(identifier: "Out", logger: logger);
                pidPipeName     = UnixUtilities.MakeFifo(identifier: "Pid", logger: logger);

                // Create filestreams
                FileStream stdInStream  = new FileStream(commandPipeName, FileMode.Open);
                FileStream stdOutStream = new FileStream(outputPipeName, FileMode.Open);
                _pidReader = new StreamReader(new FileStream(pidPipeName, FileMode.Open), encNoBom, false, UnixUtilities.StreamBufferSize);

                string debuggerCmd = UnixUtilities.GetDebuggerCommand(localOptions);

                // Default working directory is next to the app
                string debuggeeDir;
                if (Path.IsPathRooted(options.ExePath) && File.Exists(options.ExePath))
                {
                    debuggeeDir = Path.GetDirectoryName(options.ExePath);
                }
                else
                {
                    // If we don't know where the app is, default to HOME, and if we somehow can't get that, go with the root directory.
                    debuggeeDir = Environment.GetEnvironmentVariable("HOME");
                    if (string.IsNullOrEmpty(debuggeeDir))
                    {
                        debuggeeDir = "/";
                    }
                }

                string dbgCmdScript          = Path.Combine(Path.GetTempPath(), Utilities.GetMIEngineTemporaryFilename(identifier: "Cmd"));
                string launchDebuggerCommand = UnixUtilities.LaunchLocalDebuggerCommand(
                    debuggeeDir,
                    commandPipeName,
                    outputPipeName,
                    pidPipeName,
                    dbgCmdScript,
                    debuggerCmd,
                    localOptions.GetMiDebuggerArgs());

                logger?.WriteTextBlock("DbgCmd:", launchDebuggerCommand);

                using (FileStream dbgCmdStream = new FileStream(dbgCmdScript, FileMode.CreateNew))
                    using (StreamWriter dbgCmdWriter = new StreamWriter(dbgCmdStream, encNoBom)
                    {
                        AutoFlush = true
                    })
                    {
                        dbgCmdWriter.WriteLine("#!/bin/sh");
                        dbgCmdWriter.Write(launchDebuggerCommand);
                        dbgCmdWriter.Flush();
                    }

                if (PlatformUtilities.IsOSX())
                {
                    string osxLaunchScript = GetOSXLaunchScript();

                    // Call osascript with a path to the AppleScript. The apple script takes 2 parameters: a title for the terminal and the launch script.
                    cmdArgs.Add("/usr/bin/osascript");
                    cmdArgs.Add(osxLaunchScript);
                    cmdArgs.Add(FormattableString.Invariant($"\"{windowtitle}\""));
                    cmdArgs.Add(FormattableString.Invariant($"sh {dbgCmdScript} ;")); // needs a semicolon because this command is running through the launchscript.
                }
                else
                {
                    cmdArgs.Add("sh");
                    cmdArgs.Add(dbgCmdScript);
                }

                _outputStream  = new StreamReader(stdOutStream, encNoBom, false, UnixUtilities.StreamBufferSize);
                _commandStream = new StreamWriter(stdInStream, encNoBom);
            }

            RunInTerminalLauncher launcher = new RunInTerminalLauncher(windowtitle, localOptions.Environment);

            launcher.Launch(
                cmdArgs,
                localOptions.UseExternalConsole,
                LaunchSuccess,
                (error) =>
            {
                transportCallback.OnStdErrorLine(error);
                throw new InvalidOperationException(error);
            },
                logger);
            logger?.WriteLine("Wait for connection completion.");

            if (_waitForConnection != null)
            {
                // Add a timeout for waiting for connection - 20 seconds
                Task  waitOrTimeout = Task.WhenAny(_waitForConnection, Task.Delay(20000));
                await waitOrTimeout;
                if (waitOrTimeout.Status != TaskStatus.RanToCompletion)
                {
                    string errorMessage = String.Format(CultureInfo.CurrentCulture, MICoreResources.Error_DebuggerInitializeFailed_NoStdErr, "WindowsDebugLauncher.exe");
                    transportCallback.OnStdErrorLine(errorMessage);
                    transportCallback.OnDebuggerProcessExit(null);
                    return;
                }
            }

            base.Init(transportCallback, options, logger, waitLoop);
        }
Beispiel #7
0
        private HttpResponseMessage CallVcRemote(Uri endpoint, string waitLoopMessage, out string responseBody)
        {
            ManualResetEvent        doneEvent = new ManualResetEvent(false);
            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            var waitLoop = new HostWaitLoop(waitLoopMessage);
            ExceptionDispatchInfo exceptionDispatchInfo = null;

            HttpResponseMessage response = null;
            string content = null;

            ThreadPool.QueueUserWorkItem(async(object o) =>
            {
                string failureCode = Telemetry.VcRemoteFailureCode.VcRemoteSucces.ToString();

                try
                {
                    response = await this.GetAsync(endpoint, cancellationTokenSource.Token);
                    response.EnsureSuccessStatusCode();

                    content = await response.Content.ReadAsStringAsync();
                }
                catch (HttpRequestException)
                {
                    if (response != null)
                    {
                        if (response.StatusCode == HttpStatusCode.Unauthorized)
                        {
                            exceptionDispatchInfo = ExceptionDispatchInfo.Capture(new LauncherException(LauncherResources.Error_Unauthorized));
                            failureCode           = Telemetry.VcRemoteFailureCode.VcRemoteUnauthorized.ToString();
                        }
                        else
                        {
                            exceptionDispatchInfo = ExceptionDispatchInfo.Capture(new LauncherException(string.Format(LauncherResources.Error_VcRemoteUnknown, response.StatusCode.ToString())));
                            failureCode           = Telemetry.VcRemoteFailureCode.VcRemoteUnkown.ToString();
                        }
                    }
                    else
                    {
                        exceptionDispatchInfo = ExceptionDispatchInfo.Capture(new LauncherException(LauncherResources.Error_UnableToReachServer));
                        failureCode           = Telemetry.VcRemoteFailureCode.VcRemoteNoConnection.ToString();
                    }
                }
                catch (TaskCanceledException)
                {
                    //timeout
                    exceptionDispatchInfo = ExceptionDispatchInfo.Capture(new LauncherException(LauncherResources.Error_UnableToReachServer));
                    failureCode           = Telemetry.VcRemoteFailureCode.VcRemoteNoConnection.ToString();
                }
                catch (Exception e)
                {
                    exceptionDispatchInfo = ExceptionDispatchInfo.Capture(e);
                    failureCode           = e.GetType().FullName;
                }

                doneEvent.Set();

                Telemetry.SendLaunchError(failureCode, _launchOptions.IOSDebugTarget);
            });

            waitLoop.Wait(doneEvent, cancellationTokenSource);

            if (exceptionDispatchInfo != null)
            {
                exceptionDispatchInfo.Throw();
            }

            if (response == null)
            {
                Debug.Fail("Null resposne? Should be impossible.");
                throw new InvalidOperationException();
            }

            responseBody = content;
            return(response);
        }
Beispiel #8
0
 public void Init(ITransportCallback transportCallback, LaunchOptions options, Logger logger, HostWaitLoop waitLoop = null)
 {
     _bQuit        = false;
     _callback     = transportCallback;
     _commandEvent = new AutoResetEvent(false);
     _reader       = new StreamReader(File.OpenRead(_filename));
     _thread       = new Thread(TransportLoop);
     _nextCommand  = null;
     _thread.Start();
 }
        public void Init(ITransportCallback transportCallback, LaunchOptions options, Logger logger, HostWaitLoop waitLoop = null)
        {
            _launchOptions = (UnixShellPortLaunchOptions)options;
            _callback      = transportCallback;
            _logger        = logger;
            _startRemoteDebuggerCommand = _launchOptions.StartRemoteDebuggerCommand;

            _callback.AppendToInitializationLog(string.Format(CultureInfo.CurrentCulture, MICoreResources.Info_StartingUnixCommand, _startRemoteDebuggerCommand));
            _launchOptions.UnixPort.BeginExecuteAsyncCommand(_startRemoteDebuggerCommand, runInShell: true, this, out _asyncCommand);
        }
        public void Init(ITransportCallback transportCallback, LaunchOptions options, Logger logger, HostWaitLoop waitLoop = null)
        {
            _launchOptions = (UnixShellPortLaunchOptions)options;
            _callback      = transportCallback;
            _logger        = logger;
            _startRemoteDebuggerCommand = _launchOptions.StartRemoteDebuggerCommand;

            waitLoop?.SetText(MICoreResources.Info_InstallingDebuggerOnRemote);

            _callback.AppendToInitializationLog("Starting unix command: " + _startRemoteDebuggerCommand);
            _launchOptions.UnixPort.BeginExecuteAsyncCommand(_startRemoteDebuggerCommand, this, out _asyncCommand);
        }