Name: wm7046 Date: 07/15/97
The Source
public class ClassInitBug
{
public static void main(String argv[])
{
new ClassInitSub("foo");
}
}
class ClassInit
{
static int i;
static String s;
static {
i = 13;
s = "I'm static";
System.out.println("In \n");
}
public ClassInit(String s)
{
}
}
class ClassInitSub extends ClassInit
{
ClassInitSub(String s)
{
super(s);
System.out.println("In ClassInitSub Constructor\n"); // line 30
}
}
The Problem
A deadlock can occur when a stepping into an <clinit> method, and then setting a breakpoint in another class method.
To illustrate this, enter the command "jdb ClassInitBug", then enter the following jdb commands:
stop in ClassInitBug.main
run ClassInitBug
step
stop at ClassInitSub:30
Our Diagnosis
When a <clinit> method is run, one or more Class locks are held by the class loader/resolver. (The exact nature of these locks depends on whether the SAS fix for bug 4056193 has been applied; however, the occurence of the bug is independent of this fix.) If the debugger then sends a CMD_GET_CLASS_INFO command to the Agent for one of the locked classes, the Agent calls getInterfaces, which also requires the Class lock. A deadlock results.
It is not clear with the present debugger design how this deadlock is to be avoided. It might be possible for the CMD_GET_CLASS_INFO code to determine that the lock is held and return an error, but this doesn't help the user very much. It might be possible to disable stopping for breakpoints/step in a <clinit> routine, but this seems to be a significant loss of functionality.
======================================================================