/// <summary> /// Default KillTree implementation. /// </summary> /// <param name="p"></param> public virtual void KillTree(Process p, SynchronizedStreamWriter log) { List <int> processes = new List <int> (); FindChildren(p.Id, processes); Kill(processes, log); }
protected virtual internal void Kill(IEnumerable <int> pids, SynchronizedStreamWriter log) { foreach (int pid in pids) { Kill(pid, log); } }
public override void Terminate(SynchronizedStreamWriter logstream) { bool success = TerminateJobObject(job_handle, 1); log.InfoFormat("JobWindows: terminated job object with status: {0}", success); CloseHandle(job_handle); job_handle = IntPtr.Zero; }
protected internal override void Kill(IEnumerable <int> pids, SynchronizedStreamWriter log) { foreach (var pid in pids) { RenderStackTraceWithGdb(pid, log); } KillImpl(pids, log); }
/// <summary> /// Implementation using kill /// </summary> /// <param name="pids"></param> internal static void KillImpl(IEnumerable <int> pids, SynchronizedStreamWriter log) { using (Process kill = new Process()) { kill.StartInfo.FileName = "kill"; kill.StartInfo.Arguments = "-9 "; foreach (int pid in pids) { kill.StartInfo.Arguments += pid.ToString() + " "; } log.WriteLine(string.Format("\n * Killing the processes {0} * ", kill.StartInfo.Arguments.Substring(3))); kill.StartInfo.UseShellExecute = false; kill.Start(); if (!kill.WaitForExit(1000 * 15 /* 15 seconds */)) { throw new ApplicationException(string.Format("The 'kill' process didn't exit in 15 seconds.")); } } }
internal static void PrintProcessesImplPS(SynchronizedStreamWriter log) { using (var ps = new Job()) { ps.StartInfo.FileName = "ps"; ps.StartInfo.Arguments = "aux"; var reader = new ProcessReader(log); reader.Setup(ps); ps.Start(); reader.Start(); try { if (!ps.WaitForExit(1000 * 30 /* 30 seconds */)) { throw new ApplicationException(string.Format("The 'ps' process didn't exit in 30 seconds.")); } } finally { reader.Join(); } } }
internal static void RenderStackTraceWithGdb(int pid, SynchronizedStreamWriter log) { log.WriteLine(string.Format("\n * Fetching stack trace for process {0} * \n", pid)); using (var gdb = new Job()) { gdb.StartInfo.FileName = "gdb"; gdb.StartInfo.Arguments = string.Format("-ex attach {0} --ex \"info target\" --ex \"info threads\" --ex \"thread apply all bt\" --batch", pid); var reader = new ProcessReader(log); reader.Setup(gdb); gdb.Start(); reader.Start(); try { if (!gdb.WaitForExit(1000 * 30 /* 30 seconds */)) { throw new ApplicationException(string.Format("The 'gdb' process didn't exit in 30 seconds.")); } } finally { reader.Join(); } } }
public ProcessReader(SynchronizedStreamWriter output) { this.logstream = output; }
public override void PrintProcesses(SynchronizedStreamWriter log) { log.WriteLine("IProcessHelper.PrintProcesses is unimplemented on windows"); }
/// <summary> /// Terminate this job and all the processes within. /// </summary> public virtual void Terminate(SynchronizedStreamWriter logstream) { p.KillTree(logstream); }
protected internal override void Kill(int pid, SynchronizedStreamWriter log) { this.Kill(new int [] { pid }, log); }
internal static void RenderStackTraceWithGdb(int pid, SynchronizedStreamWriter log) { log.WriteLine(string.Format("\n * Fetching stack trace for process {0} * \n", pid)); var template = Path.GetTempFileName(); try { bool using_lldb = false; string debugger; if (File.Exists("/usr/bin/gdb")) { using_lldb = false; debugger = "/usr/bin/gdb"; } else if (File.Exists("/usr/bin/lldb")) { using_lldb = true; debugger = "/usr/bin/lldb"; } else { using_lldb = false; // lets hope "gdb" is somewhere. debugger = "gdb"; } var commands = new StringBuilder(); using (var dbg = new Job()) { dbg.StartInfo.UseShellExecute = false; dbg.StartInfo.FileName = debugger; if (using_lldb) { commands.AppendFormat("process attach --pid {0}\n", pid); commands.Append("script lldb.debugger.HandleCommand (\"thread list\")\n"); commands.Append("script lldb.debugger.HandleCommand (\"thread backtrace all\")\n"); commands.Append("detach\n"); commands.Append("quit\n"); dbg.StartInfo.Arguments = "--source \"" + template + "\""; } else { commands.AppendFormat("attach {0}\n", pid); commands.Append("info target\n"); commands.Append("info threads\n"); commands.Append("thread apply all bt\n"); dbg.StartInfo.Arguments = "-batch -x \"" + template + "\""; } File.WriteAllText(template, commands.ToString()); var reader = new ProcessReader(log); reader.Setup(dbg); dbg.Start(); reader.Start(); try { if (!dbg.WaitForExit(1000 * 30 /* 30 seconds */)) { throw new ApplicationException(string.Format("The 'gdb' process didn't exit in 30 seconds.", dbg.StartInfo.FileName)); } } finally { reader.Join(); } } } finally { try { File.Delete(template); } catch { } } }
/// <summary> /// Kills this process and all its child processes (recursively, grand children are killed too). /// Also waits until the process has actually exited. /// </summary> /// <param name="process"></param> public static void KillTree(this Process process, SynchronizedStreamWriter log) { GetHelper().KillTree(process, log); }
/// <summary> /// Default Kill implementation. /// </summary> /// <param name="pid"></param> protected virtual internal void Kill(int pid, SynchronizedStreamWriter log) { using (Process p = Process.GetProcessById(pid)) { p.Kill(); } }
public abstract void PrintProcesses(SynchronizedStreamWriter log);
public override void PrintProcesses(SynchronizedStreamWriter log) { PrintProcessesImplPS(log); }