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?

15 comments
Comment actions Permalink

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

0
Comment actions Permalink

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:


     "AWT-EventQueue-0" prio=6 tid=0x03a5fc00 nid=0xd4c in Object.wait() [0x0409f000..0x0409fd94]
        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?


0
Comment actions Permalink

Would new Throwable().printStackTrace not suffice?

-tt

0
Comment actions Permalink

That would print the stack trace of one thread -- what we're trying to accomplish is to get a dump of all thread stacks.

0
Comment actions Permalink

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

0
Comment actions Permalink

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

0
Comment actions Permalink

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

0
Comment actions Permalink

Yes, IDEA parses the output of jstack as expected.

0
Comment actions Permalink

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

0
Comment actions Permalink

Hello Bryan,

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?


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!"


0
Comment actions Permalink

It is pretty easy to generate a thread dump which is parseable by IntelliJ IDEA. The following code works on JDK5:

public static String getThreadDump() {

final StringBuilder dump = new StringBuilder();

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

0
Comment actions Permalink

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:
stack.gif
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.

0
Comment actions Permalink

Thanks. That's what I thought.

0
Comment actions Permalink

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.

0
Comment actions Permalink

Hi Dmitry,

On a related note, any comments on this one?
http://www.jetbrains.net/jira/browse/IDEA-20060

-tt

0

Please sign in to leave a comment.