How to Programaticly Generate a Thread Dump
I would like to programmatically generate a thread dump of all threads that can be parsed by idea's Analyze Stacktrace feature. I've hacked something together using Thread.getAllStackTraces(), but I'm making a lot of guesses about what information to provide and what format to put it in. It seems like there would be a simple call I could make like Thread.dumpThreads(Printwriter), but I can't find one. Any suggestions?
Please sign in to leave a comment.
Here's a snippet of code I use to do this:
/**
* Get a system thread dump.
*
* @return Full dump of all threads, including monitors and synchronizers.
*/
@SuppressWarnings({"HardCodedStringLiteral"})
public static String getThreadDumps()
{
ThreadInfo[] threadInfos = ManagementFactory.getThreadMXBean()
.dumpAllThreads(true,
true);
StringBuilder dump = new StringBuilder();
dump.append(String.format("%n"));
for (ThreadInfo threadInfo : threadInfos) {
dump.append(threadInfo);
}
return dump.toString();
}
Unfortunately, Analyze Stacktrace doesn't handle this properly for some reason -- it doesn't realize there are multiple threads in the output.
http://www.jetbrains.net/jira/browse/IDEA-22189
anders
Thanks for your help. I'm getting basicly the same results calling Thread.getAllStackTraces(). I ran into the same problem you have. Idea is expecting the header of the stack to be in a different format. Your code produces a header for each stacktrace like this:
"AWT-EventQueue-0" Id=14 RUNNABLE
While Sun's JRE (from the applet console or the ctrl-break feature) produces headers like this:
java.lang.Thread.State: WAITING (on object monitor)
The extra information in the header is necessary. In my code, I filled in what I could and printed zeros for the rest. Idea was able to parse it. But it's not exactly a peice of code I'm proud of.
I would assume the code Sun uses to generate the thread dump is programaticly accessable. Idea is geneating the same thread dumps from a button on the console. Does anyone know how Sun or Idea produces these dumps?
Would new Throwable().printStackTrace not suffice?
-tt
That would print the stack trace of one thread -- what we're trying to accomplish is to get a dump of all thread stacks.
Ah, missed that.
If you're willing to limit yourself to Sun 1.6 JVMs, I guess you could
use the same internal APIs that the "jstack" tool is using.
Or, access the JVM JMX beans in order to acquire a stack dump, or
trigger one to be generate to the console stream.
-tt
I'm quite happy to limit myself to 1.6 JVM's -- the problem is that the output from the JMX bean (and other means) is not parseable by IntelliJ, so I'm stuck manually analyzing these thread dumps, for now.
anders
Does the output from jstack conform to what IDEA expects?
If so, I think it's possible to get to that..the only thing I'm not sure
about is how to obtain the pid of the target process.
-tt
Yes, IDEA parses the output of jstack as expected.
Anders,
Have a look here for the source of JStack - I imagine you could do the same (although you'd need to know what JVM implementation is running):
http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-sun/tools/sun/tools/jstack/JStack.java.htm
Cheers,
Bonny
Hello Bryan,
In IDEA, we have it hand-coded - I don't think there's any JDK code that
we could reuse for that.
--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"
It is pretty easy to generate a thread dump which is parseable by IntelliJ IDEA. The following code works on JDK5:
final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
final ThreadInfo[] threadInfos =
threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds(), 100);
for (ThreadInfo threadInfo : threadInfos) {
dump.append('"');
dump.append(threadInfo.getThreadName());
dump.append("\" ");
final Thread.State state = threadInfo.getThreadState();
dump.append("\n java.lang.Thread.State: ");
dump.append(state);
final StackTraceElement[] stackTraceElements = threadInfo.getStackTrace();
for (final StackTraceElement stackTraceElement : stackTraceElements) {
dump.append("\n at ");
dump.append(stackTraceElement);
}
dump.append("\n\n");
}
return dump.toString();
}
Bas
That code will generate a stack that can be parsed by idea... but only parsed as a regular stack trace. A thread dump parses a little different. Idea breaks out each thread and adds icons for each:
Here's the code I used to generate the thread dump above:
private static String getDump() {
StringBuilder builder = new StringBuilder();
for (Thread thread : Thread.getAllStackTraces().keySet()) {
builder.append(String.format("\"%s\" %s prio=%d tid=%d nid=1 %s\njava.lang.Thread.State: %s\n",
thread.getName(),
(thread.isDaemon() ? "daemon" : ""),
thread.getPriority(),
thread.getId(),
Thread.State.WAITING.equals(thread.getState()) ? "in Object.wait()" : thread.getState().name().toLowerCase(),
(thread.getState().equals(Thread.State.WAITING) ? "WAITING (on object monitor)" : thread.getState())));
builder.append(Exceptions.getFullStackTrace(thread.getStackTrace()));
builder.append("\n");
}
return builder.toString();
}
It's a bit flawed, as I have no idea what some of the values mean (nid?) or how to format them correctly. But I got close enought for IDEA to parse it.
I would have rather called a JDK method to get this, but it doesn't seem possible.
Thanks. That's what I thought.
Thanks. I looked everywhere for that. Turns out it's calling into the HotspotVM. I don't see a clean way of using this within my code. Thanks for pointing it out though.
Hi Dmitry,
On a related note, any comments on this one?
http://www.jetbrains.net/jira/browse/IDEA-20060
-tt