Inheritance: IDisposable
Example #1
0
		public void Setup (Job p)
		{
			p.StartInfo.UseShellExecute = false;
			p.StartInfo.RedirectStandardError = true;
			p.StartInfo.RedirectStandardOutput = true;

			stdout_thread = new Thread (delegate () {
				try {
					string line;
					while (null != (line = p.StandardOutput.ReadLine ())) {
						log.WriteLine (line);
					}
				} catch (Exception ex) {
					Logger.Log ("? Stdin reader thread got exception: {0}", ex.Message);
				}
			});

			stderr_thread = new Thread (delegate () {
				try {
					string line;
					while (null != (line = p.StandardError.ReadLine ())) {
						log.WriteLine (line);
					}
				} catch (Exception ex) {
					Logger.Log ("? Stderr reader thread got exception: {0}", ex.Message);
				}
			});
		}
		public void Setup (Job p, bool timestamp=false)
		{
			p.StartInfo.UseShellExecute = false;
			p.StartInfo.RedirectStandardError = true;
			p.StartInfo.RedirectStandardOutput = true;

			stdout_thread = new Thread (delegate () {
				try {
					string line;
					while (null != (line = p.StandardOutput.ReadLine ())) {
						if (timestamp && !line.StartsWith("@MonkeyWrench:") && !line.StartsWith("@Moonbuilder:")) { line = "[" + DateTime.Now.ToString("h:mm:ss") + "] " + line; }
						logstream.WriteLine (line);
					}
				} catch (Exception ex) {
					log.ErrorFormat ("Stdin reader thread got exception: {0}", ex);
				}
			});

			stderr_thread = new Thread (delegate () {
				try {
					string line;
					while (null != (line = p.StandardError.ReadLine ())) {
						if (timestamp && !line.StartsWith("@MonkeyWrench:") && !line.StartsWith("@Moonbuilder:")) { line = "[" + DateTime.Now.ToString("h:mm:ss") + "] " + line; }
						logstream.WriteLine (line);
					}
				} catch (Exception ex) {
					log.ErrorFormat ("Stderr reader thread got exception: {0}", ex);
				}
			});
		}
		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 ();
				}
			}
		}