2008-07-10

Pimpin' thread dump utility class

When you're looking at your source and wondering "how the hell did I get here? Am I on the Swing worker thread, or...", there's a few things you can do to make finding the answer easier.

You've already looked at the call hierarchy with Ctrl+Alt+H, and you can't figure it out. One approach is to just slap down a breakpoint and restart under the Eclipse debugger, but if you put the breakpoint in a method that's called commonly, and you're instead looking for the uncommon hit, it's going to be really annoying to have the debugger jump up every three seconds and click "nope, nope, next, etc" while looking at the call stack.


AAAAUUUUUGH!!

So here's the second option: good old printf debugging. Now there's no one-liner (that I know of) in Java to just dump the current stack (You could instantiate a Throwable and tell it to print its stack in like 2 lines, but how ugly is that?), so here's a little utility class (ThreadUtil.java) you can grab:



import java.io.PrintStream;

/**
* Debugging utility class for printing current thread's stack trace.
*
* To print to STDOUT, just call {@link #printMyStackTrace()}. If using a
* logging framework, instead call {@link #getMyStackTrace()} and log the
* result.
*
* @author Jean-Philippe Daigle
*
*/
public class ThreadUtil {

private ThreadUtil() {
}

/**
* Prints current stack to System.out.
*/
public static void printMyStackTrace() {
printMyStackTrace(System.out);
}

/**
* Prints current stack to the specified PrintStream.
*/
public static void printMyStackTrace(final PrintStream out) {
out.print(getMyStackTrace());
}

/**
* Gets current stack trace as a String.
*/
public static String getMyStackTrace() {
StackTraceElement[] ste_arr = dumpFilteredStack();
StringBuilder sb = new StringBuilder();
sb.append(getHeader()).append("\n");
for (StackTraceElement stackTraceElement : ste_arr) {
sb.append("\t" + stackTraceElement + "\n");
}
return sb.toString();
}

private static StackTraceElement[] dumpFilteredStack() {
StackTraceElement[] ste = Thread.currentThread().getStackTrace();

/*
* The first few elements in the stack will be in Thread.dumpThreads,
* and in the current class, so we need to skip that noise.
*/
int i = 0;
for (i = 0; i < ste.length; i++) {
String cc = ste[i].getClassName();
if (!(cc.equals("java.lang.Thread")
|| cc.equals(ThreadUtil.class.getCanonicalName())))
break;
}

StackTraceElement[] ste2 = new StackTraceElement[ste.length - i];
System.arraycopy(ste, i, ste2, 0, ste2.length);
return ste2;
}

private static String getHeader() {
final Thread ct = Thread.currentThread();
return String.format("Thread: \"%s\" %s id=%s, prio=%s:",
ct.getName(),
ct.isDaemon() ? "daemon " : "",
ct.getId(),
ct.getPriority());
}
}

3 comments:

Anonymous said...

http://blogs.msdn.com/oldnewthing/archive/2008/07/14/8730046.aspx#8732597

Anonymous said...

Hi
http://www.golfpoloshirts.net/ - generic sertraline
But it is approved for pediatric patients but only as a cure of obsessive-compulsive disorder.
[url=http://www.golfpoloshirts.net/]zoloft price[/url]

When taking the drug, you might be have some thinking in having suicide especially if you are younger than 24 years old.
buy zoloft
There have been studies that this drug works much better than Prozac.

Anonymous said...

Hello
http://www.printhousesigns.com/ - generic finasteride
People who suffer from baldness should also try out Propecia.
[url=http://www.printhousesigns.com/]finasteride online[/url]
Isn’t it a nice one? Hence you should not take much tension about it.
cheap propecia

Propecia first came in the year 1992.