FarragoStackTrace

From Eigenpedia

Jump to: navigation, search

How do I get a Java stack trace?


The most informative stack traces can be obtained with a debugger (see FarragoEclipse for instructions on setting one up).

Some front-end tools allow you to see Java stack traces directly in certain contexts. For example, in sqlline, if you issue the !set verbose on command, a stack trace is reported with every subsequent error.

For other cases, you can often make use of the fact that all exceptions propagated through the Farrago JDBC driver are traced. In file farrago/trace/FarragoTrace.properties, set net.sf.farrago.jdbc.level=FINER, then do whatever causes the exception and look at the tail of file farrago/trace/FarragoTrace.log.

On Linux, sending the JVM process signal 3 (SIGQUIT) at any time will produce a Java-only stack trace for all threads on the process's stdout. (Don't worry, despite the signal name, the process keeps right on running.) This can be useful for activities like deadlock debugging as it also contains information about which threads hold which locks. If you're running an interactive process such as sqllineEngine, you can send this signal by hitting Ctrl-\ in the sqlline console. Otherwise, use ps to find the right process ID and then use the kill command to send the signal:


jvs@bagheera:~$ ps ax
PID TTY STAT TIME COMMAND
1 ? S 0:01 init [2]
...
11280 pts/0 Sl+ 0:14 java -ea -esa -cp /home/jvs/open/thirdparty/sqlline.j11417 pts/1 R+ 0:00 ps ax
jvs@bagheera:~$ kill -s SIGQUIT 11280

Output should appear on the sqlline console something like this:

sqlline version 1.0.0-jvs-1 by Marc Prud'hommeaux
0: jdbc:farrago:> Full thread dump Java HotSpot(TM) Client VM (1.5.0_04-b05 mixed mode):
"Timer-0" prio=1 tid=0x08319428 nid=0x2c3b in Object.wait() [0xa5418000..0xa5418e30]
at java.lang.Object.wait(Native Method)
- waiting on <0xacd17b08> (a java.util.TaskQueue)
at java.util.TimerThread.mainLoop(Timer.java:509)
- locked <0xacd17b08> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:462)
"MDR event dispatcher" daemon prio=1 tid=0x0812f130 nid=0x2c36 in Object.wait() [0xa89ff000..0xa89ffeb0]
at java.lang.Object.wait(Native Method)
- waiting on <0xaca0b820> (a java.util.LinkedList)
at java.lang.Object.wait(Object.java:474)
at org.netbeans.mdr.util.EventNotifier$EventsDelivery.run(EventNotifier.java:257)
- locked <0xaca0b820> (a java.util.LinkedList)
at java.lang.Thread.run(Thread.java:595)
"HSQLDB Timer @9cb0f4" daemon prio=1 tid=0x083d4df8 nid=0x2c35 in Object.wait() [0xa8b1d000..0xa8b1df30]
at java.lang.Object.wait(Native Method)
- waiting on <0xac70c5c0> (a org.hsqldb.lib.HsqlTimer)
at org.hsqldb.lib.HsqlTimer.nextTask(Unknown Source)
- locked <0xac70c5c0> (a org.hsqldb.lib.HsqlTimer)
at org.hsqldb.lib.HsqlTimer$TaskRunner.run(Unknown Source)
at java.lang.Thread.run(Thread.java:595)
...


If you are using the JRockit VM, you can use the jrcmd utility to obtain a stack trace for all threads for a given JVM's process ID. The really nice part about this is that you can get full hybrid Java/native stacks for each thread. Here's the command:

jrcmd <pid> print_threads nativestack=true

See FennelStackTrace for information on C++ stack dumps.