public class Debugger
extends java.lang.Object
v command in the
JLambda's read-eval-print loop. For the purposes of illustration there
is a class in the util package Bugs:
package g2d.util;
public class Bugs {
public static final int ZERO = 0;
public static void loop(){
loop();
}
public static int divideByZero(int x){
return x / ZERO;
}
}
This class is designed to have methods that throw unchecked exceptions, which
from the point of view of the reflective interpreter simply result in failure:
> (sinvoke "g2d.util.Bugs" "loop")
Uncaught exception:
sinvoke: method invocation failed
Method = public static void g2d.util.Bugs.loop()
Target = g2d.util.Bugs
JLambda backtrace:
computing result of sinvoke form @ line number 1
>
As one can imagine this is not very helpful news when debugging, so
to gain more information in such a situation one can look at the internal
Java exceptions that were generated. One can either do this with the
built in read-eval-print loop
v command, or programmatically by:
> (sinvoke "g2d.jlambda.Debugger" "toggleVerbosity") true >To prevent seeing too much detail, we will also limit the printing of stack traces of the reported Java exceptions to a depth of 3 (the default is 15)
> (sinvoke "g2d.jlambda.Debugger" "setStackDepth" (int 3))and then, by re-executing the problem form, we see the real cause of the problem:
> (sinvoke "g2d.util.Bugs" "loop")
Uncaught exception:
sinvoke: method invocation failed
Method = public static void g2d.util.Bugs.loop()
Target = g2d.util.Bugs
Cause[0]: (class g2d.jlambda.EvaluateError)
stack[0] = g2d.jlambda.InvokeCont.invokeMethod(InvokeCont.java:120)
stack[1] = g2d.jlambda.InvokeCont.computeResult(InvokeCont.java:78)
stack[2] = g2d.jlambda.EvalArgsCont.handleReturn(EvalArgsCont.java:42)
stack[3] = g2d.jlambda.Continuation.ret(Continuation.java:66)
.... 6 more (see g2d.jlambda.Debugger to increase depth)
Cause[1]: (class java.lang.reflect.InvocationTargetException)
stack[0] = sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
stack[1] = sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
stack[2] = sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
stack[3] = java.lang.reflect.Method.invoke(Method.java:585)
.... 10 more (see g2d.jlambda.Debugger to increase depth)
Cause[2]: (class java.lang.StackOverflowError)
stack[0] = g2d.util.Bugs.loop(Bugs.java:7)
stack[1] = g2d.util.Bugs.loop(Bugs.java:7)
stack[2] = g2d.util.Bugs.loop(Bugs.java:7)
stack[3] = g2d.util.Bugs.loop(Bugs.java:7)
.... 1021 more (see g2d.jlambda.Debugger to increase depth)
JLambda backtrace:
computing result of sinvoke form @ line number 1
>
The underlying cause of the failure is stack overflow caused by the unguarded recursive
call to loop.| Modifier and Type | Field and Description |
|---|---|
static int |
stackDepth |
static boolean |
verbosity |
| Modifier | Constructor and Description |
|---|---|
protected |
Debugger() |
| Modifier and Type | Method and Description |
|---|---|
static int |
getStackDepth()
Gets the depth to which stack traces of Java exceptions are printed.
|
static boolean |
getVerbosity()
Gets the verbosity.
|
static void |
handle(java.lang.Throwable e) |
static void |
setStackDepth(int depth)
Sets the depth to which stack traces of Java exceptions are printed.
|
static void |
setVerbosity(boolean b)
Sets the verbosity.
|
static boolean |
toggleVerbosity()
This toggles the verbosity flag.
|
public static void handle(java.lang.Throwable e)
public static void setStackDepth(int depth)
depth - an int specifying the stack depth value. The default is 15.getStackDepth()public static int getStackDepth()
setStackDepth(int)public static void setVerbosity(boolean b)
b - the desired level of verbosity.getVerbosity()public static boolean getVerbosity()
setVerbosity(boolean)public static boolean toggleVerbosity()
v command in the JLambda's read-eval-print loop.