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 ("thread list\n"); commands.Append ("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 { } } }
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} (name '{1}') * \n", pid, GetProcessName (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 (); } } }
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(); } } }
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 { } } }