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, this, out _asyncCommand);
        }
Esempio n. 2
0
        void IPlatformAppLauncher.SetupForDebugging(out LaunchOptions debuggerLaunchOptions)
        {
            if (_launchOptions == null)
            {
                Debug.Fail("Why is SetupForDebugging being called before ParseLaunchOptions?");
                throw new InvalidOperationException();
            }

            string targetMachineName = LaunchOptions.RequireAttribute(_launchOptions.TargetMachine, "TargetMachine");

            var port = new AD7Port(new AD7PortSupplier(), targetMachineName, isInAddPort: false);

            // NOTE: this may put up a dialog and/or throw an AD7ConnectCanceledException
            port.EnsureConnected();

            debuggerLaunchOptions = new UnixShellPortLaunchOptions(_launchOptions.StartRemoteDebuggerCommand,
                                                                    port,
                                                                    LaunchOptions.ConvertMIModeAttribute(_launchOptions.MIMode),
                                                                    _launchOptions);
        }
Esempio n. 3
0
        /// <summary>
        /// Returns true if the previous launch was ever successful on the same session false otherwise.
        /// </summary>
        /// <param name="launchOptions">launch options</param>
        public static bool HasSuccessfulPreviousLaunch(UnixShellPortLaunchOptions launchOptions)
        {
            IDebugPort2 debugPort = launchOptions.UnixPort as IDebugPort2;
            if (debugPort != null)
            {
                string portName = null;
                debugPort.GetPortName(out portName);
                if (!string.IsNullOrWhiteSpace(portName))
                {
                    lock (s_LaunchSuccessSet)
                    {
                        // If it is successful once, we expect the clrdbg launch to be successful atleast till the end of the current VS session. 
                        // The portname will not be removed from the list.
                        return s_LaunchSuccessSet.Contains(portName);
                    }
                }
            }

            return false;
        }
Esempio n. 4
0
        public static UnixShellPortLaunchOptions CreateForAttachRequest(Microsoft.VisualStudio.Debugger.Interop.UnixPortSupplier.IDebugUnixShellPort unixPort,
            int processId,
            MIMode miMode,
            string getClrDbgUrl,
            string remoteDebuggingDirectory,
            string remoteDebuggingSubDirectory,
            string debuggerVersion)
        {
            var @this = new UnixShellPortLaunchOptions(startRemoteDebuggerCommand: null,
                                                       unixPort: unixPort,
                                                       miMode: miMode,
                                                       baseLaunchOptions: null,
                                                       getClrDbgUrl: getClrDbgUrl,
                                                       remoteDebuggerInstallationDirectory: remoteDebuggingDirectory,
                                                       remoteDebuggerInstallationSubDirectory: remoteDebuggingSubDirectory,
                                                       clrdbgVersion: debuggerVersion);

            @this.ProcessId = processId;
            @this.SetupCommands = new ReadOnlyCollection<LaunchCommand>(new LaunchCommand[] { });
            @this.SetInitializationComplete();

            return @this;
        }
Esempio n. 5
0
        private void DetermineAndAddExecutablePathCommand(IList<LaunchCommand> commands, UnixShellPortLaunchOptions launchOptions)
        {
            // TODO: rajkumar42, connecting to OSX via SSH doesn't work yet. Show error after connection manager dialog gets dismissed.

            // Runs a shell command to get the full path of the exe.
            // /proc file system does not exist on OSX. And querying lsof on privilaged process fails with no output on Mac, while on Linux the command succeedes with 
            // embedded error text in lsof output like "(readlink error)". 
            string absoluteExePath;
            if (launchOptions.UnixPort.IsOSX())
            {
                // Usually the first FD=txt in the output of lsof points to the executable.
                absoluteExePath = string.Format(CultureInfo.InvariantCulture, "shell lsof -p {0} | awk '$4 == \"txt\" {{ print $9 }}'|awk 'NR==1 {{print $1}}'", _launchOptions.ProcessId);
            }
            else if (launchOptions.UnixPort.IsLinux())
            {
                absoluteExePath = string.Format(CultureInfo.InvariantCulture, @"shell readlink -f /proc/{0}/exe", _launchOptions.ProcessId);
            }
            else
            {
                throw new LaunchErrorException(ResourceStrings.Error_UnsupportedPlatform);
            }

            Action<string> failureHandler = (string miError) =>
            {
                string message = string.Format(CultureInfo.CurrentUICulture, ResourceStrings.Error_FailedToGetExePath, miError);
                throw new LaunchErrorException(message);
            };

            Action<string> successHandler = async (string exePath) =>
            {
                string trimmedExePath = exePath.Trim();
                try
                {
                    await CmdAsync("-file-exec-and-symbols " + trimmedExePath, ResultClass.done);
                }
                catch (UnexpectedMIResultException miException)
                {
                    string message = string.Format(CultureInfo.CurrentUICulture, ResourceStrings.Error_ExePathInvalid, trimmedExePath, MICommandFactory.Name, miException.MIError);
                    throw new LaunchErrorException(message);
                }
            };

            commands.Add(new LaunchCommand(absoluteExePath, ignoreFailures: false, failureHandler: failureHandler, successHandler: successHandler));
        }