The class java.lang.Runtime has two methods designed to help you debug things in the absence of a debugger. These methods are public native void traceInstructions(boolean on); public native void traceMethodCalls(boolean on); The boolean on controls whether to turn tracing on or off. It's up to the JVM implementation to determine what, if anything, happens when you call these methods. Many implementations ignore these requests for performance reasons. For machines that do something interesting, the output can be quite extensive. Here is a method that computes Fibonacci numbers: .method static fib (I)I iload_0.var 0 is i I iconst_2 if_icmpgt recurse ; If i > 2, recurse iconst_1 ; If i <= 2, return 1 ireturn recurse: iload_0 ; Compute fib(i-1) iconst_1 isub invokestatic fib/fib(I)I iload_0 ; Compute fib(i-2) iconst_2 isub invokestatic fib/fib(I)I iadd ; Add them up and ireturn ; return the sum .end method This code runs a method trace using the method fib: public static void main(String a[]) { Runtime.getRuntime().traceMethodCalls(true); System.out.println(fib(3)); } Using the Java Development Kit's JVM implementation, this code prints: # main [ 1] | > fib.fib(I)I (1) entered # main [ 2] | | > fib.fib(I)I (1) entered # main [ 2] | | < fib.fib(I)I returning # main [ 2] | | > fib.fib(I)I (1) entered # main [ 2] | | < fib.fib(I)I returning # main [ 1] | < fib.fib(I)I returning Here's a sample instruction trace, with traceInstructions set to true: F600A8 1D1997F iconst_3 F600A8 1D19980 invokestatic fib.fib(I)I F600A8 1D19980 invokestatic_quick fib.fib(I)I (1) Entering fib.fib F600A8 1D199C0 iload_0 => 3 F600A8 1D199C1 iconst_2 F600A8 1D199C2 if_icmpgt goto 1D199C7 (taken) F600A8 1D199C7 iload_0 => 3 F600A8 1D199C8 iconst_1 F600A8 1D199C9 isub => 2 F600A8 1D199CA invokestatic fib.fib(I)I F600A8 1D199CA invokestatic_quick fib.fib(I)I (1) Entering fib.fib F600A8 1D199C0 iload_0 => 2 F600A8 1D199C1 iconst_2 F600A8 1D199C2 if_icmpgt goto 1D199C7 (not taken) F600A8 1D199C5 iconst_1 F600A8 1D199C6 ireturn 1 Leaving fib.fib F600A8 1D199CD iload_0 => 3 F600A8 1D199CE iconst_2 F600A8 1D199CF isub => 1 F600A8 1D199D0 invokestatic fib.fib(I)I F600A8 1D199D0 invokestatic_quick fib.fib(I)I (1) Entering fib.fib F600A8 1D199C0 iload_0 => 1 F600A8 1D199C1 iconst_2 F600A8 1D199C2 if_icmpgt goto 1D199C7 (not taken) F600A8 1D199C5 iconst_1 F600A8 1D199C6 ireturn 1 Leaving fib.fib F600A8 1D199D3 iadd => 2 F600A8 1D199D4 ireturn 2 Leaving fib.fib F600A8 1D19983 istore_1 2 => r1 This instruction trace was produced using Sun's java_g virtual machine, available with the Java Development Kit. |