提交 ece952dc 编写于 作者: K kohsuke

added more detailed thread stack dump screen that uses JMX.


git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@3086 71c3de6d-444a-0410-be80-ed276b4c234a
上级 4efc38b3
......@@ -36,6 +36,11 @@ import java.util.SortedMap;
import java.util.TreeMap;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.lang.management.ThreadInfo;
import java.lang.management.MonitorInfo;
import java.lang.management.LockInfo;
/**
* Utility functions used in views.
......@@ -432,4 +437,73 @@ public class Functions {
public Map<Thread,StackTraceElement[]> dumpAllThreads() {
return Thread.getAllStackTraces();
}
public ThreadInfo[] getThreadInfos() {
ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
return mbean.getThreadInfo(mbean.getAllThreadIds(),mbean.isObjectMonitorUsageSupported(),mbean.isSynchronizerUsageSupported());
}
// ThreadInfo.toString() truncates the stack trace by first 8, so needed my own version
public String dumpThreadInfo(ThreadInfo ti) {
StringBuilder sb = new StringBuilder("\"" + ti.getThreadName() + "\"" +
" Id=" + ti.getThreadId() + " " +
ti.getThreadState());
if (ti.getLockName() != null) {
sb.append(" on " + ti.getLockName());
}
if (ti.getLockOwnerName() != null) {
sb.append(" owned by \"" + ti.getLockOwnerName() +
"\" Id=" + ti.getLockOwnerId());
}
if (ti.isSuspended()) {
sb.append(" (suspended)");
}
if (ti.isInNative()) {
sb.append(" (in native)");
}
sb.append('\n');
StackTraceElement[] stackTrace = ti.getStackTrace();
for (int i=0; i < stackTrace.length; i++) {
StackTraceElement ste = stackTrace[i];
sb.append("\tat " + ste.toString());
sb.append('\n');
if (i == 0 && ti.getLockInfo() != null) {
Thread.State ts = ti.getThreadState();
switch (ts) {
case BLOCKED:
sb.append("\t- blocked on " + ti.getLockInfo());
sb.append('\n');
break;
case WAITING:
sb.append("\t- waiting on " + ti.getLockInfo());
sb.append('\n');
break;
case TIMED_WAITING:
sb.append("\t- waiting on " + ti.getLockInfo());
sb.append('\n');
break;
default:
}
}
for (MonitorInfo mi : ti.getLockedMonitors()) {
if (mi.getLockedStackDepth() == i) {
sb.append("\t- locked " + mi);
sb.append('\n');
}
}
}
LockInfo[] locks = ti.getLockedSynchronizers();
if (locks.length > 0) {
sb.append("\n\tNumber of locked synchronizers = " + locks.length);
sb.append('\n');
for (LockInfo li : locks) {
sb.append("\t- " + li);
sb.append('\n');
}
}
sb.append('\n');
return sb.toString();
}
}
<!--
Produces stack dump of all threads by using JMX.
This uses new Tiger feature and offers more information
-->
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<l:layout secure="true">
<st:include page="sidepanel.jelly" />
<l:main-panel>
<h1>Thread Dump</h1>
<j:forEach var="t" items="${h.getThreadInfos()}">
<h2>${t.threadName}</h2>
<pre>${h.dumpThreadInfo(t)}</pre>
</j:forEach>
</l:main-panel>
</l:layout>
</j:jelly>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册