internal static void KillProcessTree(Process p) { bool isLinux = PlatformUtilities.IsLinux(); bool isOSX = PlatformUtilities.IsOSX(); if (isLinux || isOSX) { // On linux run 'ps -x -o "%p %P"' (similarly on Mac), which generates a list of the process ids (%p) and parent process ids (%P). // Using this list, issue a 'kill' command for each child process. Kill the children (recursively) to eliminate // the entire process tree rooted at p. Process ps = new Process(); ps.StartInfo.FileName = "/bin/ps"; ps.StartInfo.Arguments = isLinux ? "-x -o \"%p %P\"" : "-x -o \"pid ppid\""; ps.StartInfo.RedirectStandardOutput = true; ps.StartInfo.UseShellExecute = false; ps.Start(); string line; List <Tuple <int, int> > processAndParent = new List <Tuple <int, int> >(); char[] whitespace = new char[] { ' ', '\t' }; while ((line = ps.StandardOutput.ReadLine()) != null) { line = line.Trim(); int id, pid; if (Int32.TryParse(line.Substring(0, line.IndexOfAny(whitespace)), NumberStyles.Integer, CultureInfo.InvariantCulture, out id) && Int32.TryParse(line.Substring(line.IndexOfAny(whitespace)).Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out pid)) { processAndParent.Add(new Tuple <int, int>(id, pid)); } } KillChildren(processAndParent, p.Id); } }
public ProcessMonitor(int processId) { if (!PlatformUtilities.IsLinux() && !PlatformUtilities.IsOSX()) { throw new NotImplementedException(); } _processId = processId; }
public override bool UseExternalConsoleForLocalLaunch(LocalLaunchOptions localLaunchOptions) { // NOTE: On Linux, there are issues if we try to have GDB launch the process as a child of VS // code -- it will cause a deadlock during debuggee launch. So we always use the external console // unless we are in a scenario where the debuggee will not be a child process. if (PlatformUtilities.IsLinux()) { return(String.IsNullOrEmpty(localLaunchOptions.MIDebuggerServerAddress) && !localLaunchOptions.IsCoreDump); } else { return(base.UseExternalConsoleForLocalLaunch(localLaunchOptions)); } }
public static TerminalLauncher MakeTerminal(string title, string initScript, ReadOnlyCollection <EnvironmentEntry> environment) { TerminalLauncher terminal = null; if (PlatformUtilities.IsLinux()) { terminal = new LinuxTerminalLauncher(title, initScript, environment); } else if (PlatformUtilities.IsOSX()) { terminal = new MacTerminalLauncher(title, initScript, environment); } else { Debug.Fail("Cannot make a terminal for non Linux or OS X."); throw new InvalidOperationException(); } return(terminal); }
internal static string GetDebuggerCommand(LocalLaunchOptions localOptions) { string quotedDebuggerPath = String.Format(CultureInfo.InvariantCulture, "\"{0}\"", localOptions.MIDebuggerPath); if (PlatformUtilities.IsLinux()) { string debuggerPathCorrectElevation = quotedDebuggerPath; string prompt = string.Empty; // If running as root, make sure the new console is also root. bool isRoot = UnixNativeMethods.GetEUid() == 0; // If the system doesn't allow a non-root process to attach to another process, try to run GDB as root if (localOptions.ProcessId.HasValue && !isRoot && UnixUtilities.GetRequiresRootAttach(localOptions.DebuggerMIMode)) { prompt = String.Format(CultureInfo.CurrentCulture, "echo -n '{0}'; read yn; if [ \"$yn\" != 'y' ] && [ \"$yn\" != 'Y' ] ; then exit 1; fi; ", MICoreResources.Warn_AttachAsRootProcess); // Prefer pkexec for a nice graphical prompt, but fall back to sudo if it's not available if (File.Exists(UnixUtilities.PKExecPath)) { debuggerPathCorrectElevation = String.Concat(UnixUtilities.PKExecPath, " ", debuggerPathCorrectElevation); } else if (File.Exists(UnixUtilities.SudoPath)) { debuggerPathCorrectElevation = String.Concat(UnixUtilities.SudoPath, " ", debuggerPathCorrectElevation); } else { Debug.Fail("Root required to attach, but no means of elevating available!"); } } return(String.Concat(prompt, debuggerPathCorrectElevation)); } else { return(quotedDebuggerPath); } }