From 999cb4b20cc20a24c7b9fbce4c31b13f8bf36cb5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 Nov 2012 04:40:49 +0000 Subject: Make "show threads" and "thread abort" console commands available on all servers --- OpenSim/Framework/Servers/ServerBase.cs | 92 +++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) (limited to 'OpenSim/Framework/Servers/ServerBase.cs') diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs index b8bc27e..47baac8 100644 --- a/OpenSim/Framework/Servers/ServerBase.cs +++ b/OpenSim/Framework/Servers/ServerBase.cs @@ -27,16 +27,19 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Reflection; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using log4net; using log4net.Appender; using log4net.Core; using log4net.Repository; using Nini.Config; using OpenSim.Framework.Console; +using OpenSim.Framework.Monitoring; namespace OpenSim.Framework.Servers { @@ -211,6 +214,22 @@ namespace OpenSim.Framework.Servers "Run a command script from file", HandleScript); m_console.Commands.AddCommand( + "General", false, "show threads", + "show threads", + "Show thread status", HandleShow); + + m_console.Commands.AddCommand( + "General", false, "threads abort", + "threads abort ", + "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort); + + m_console.Commands.AddCommand( + "General", false, "threads show", + "threads show", + "Show thread status. Synonym for \"show threads\"", + (string module, string[] args) => Notice(GetThreadsReport())); + + m_console.Commands.AddCommand( "General", false, "force gc", "force gc", "Manually invoke runtime garbage collection. For debugging purposes", @@ -244,6 +263,10 @@ namespace OpenSim.Framework.Servers case "uptime": Notice(GetUptimeReport()); break; + + case "threads": + Notice(GetThreadsReport()); + break; } } @@ -556,6 +579,75 @@ namespace OpenSim.Framework.Servers } /// + /// Get a report about the registered threads in this server. + /// + protected string GetThreadsReport() + { + // This should be a constant field. + string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}"; + + StringBuilder sb = new StringBuilder(); + Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreadsInfo(); + + sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine); + + int timeNow = Environment.TickCount & Int32.MaxValue; + + sb.AppendFormat(reportFormat, "ID", "NAME", "LAST UPDATE (MS)", "LIFETIME (MS)", "PRIORITY", "STATE"); + sb.Append(Environment.NewLine); + + foreach (Watchdog.ThreadWatchdogInfo twi in threads) + { + Thread t = twi.Thread; + + sb.AppendFormat( + reportFormat, + t.ManagedThreadId, + t.Name, + timeNow - twi.LastTick, + timeNow - twi.FirstTick, + t.Priority, + t.ThreadState); + + sb.Append("\n"); + } + + sb.Append("\n"); + + // For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting + // zero active threads. + int totalThreads = Process.GetCurrentProcess().Threads.Count; + if (totalThreads > 0) + sb.AppendFormat("Total threads active: {0}\n\n", totalThreads); + + sb.Append("Main threadpool (excluding script engine pools)\n"); + sb.Append(Util.GetThreadPoolReport()); + + return sb.ToString(); + } + + public virtual void HandleThreadsAbort(string module, string[] cmd) + { + if (cmd.Length != 3) + { + MainConsole.Instance.Output("Usage: threads abort "); + return; + } + + int threadId; + if (!int.TryParse(cmd[2], out threadId)) + { + MainConsole.Instance.Output("ERROR: Thread id must be an integer"); + return; + } + + if (Watchdog.AbortThread(threadId)) + MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId); + else + MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId); + } + + /// /// Console output is only possible if a console has been established. /// That is something that cannot be determined within this class. So /// all attempts to use the console MUST be verified. -- cgit v1.1