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); }
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; }
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()); }
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); } }
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); }
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); }
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); }
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); }