Let's try that again with the attachement... Resending and including the Runtime team since I think that team owns deadlock detection support at this point... Dan -------- Original Message --------
Hi folks, I notice that when you send a sigquit to a VM, and threads are deadlocked in class initialization, then the thread state is reported as RUNNABLE. Is this deliberate? With the attached program (which mostly deadlocks on clinit - I don't have the time to remember how to write the 100-percent-will-always-deadlock version today), here is the output from JDK7 b74. 2009-11-17 15:41:14 Full thread dump OpenJDK Server VM (17.0-b03 mixed mode): "DestroyJavaVM" prio=10 tid=0xaf519c00 nid=0x2221 waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "Thread-1" prio=10 tid=0xaf518000 nid=0x2230 in Object.wait() [0xaf3db000] java.lang.Thread.State: RUNNABLE at NPE$2.run(NPE.java:60) at java.lang.Thread.run(Thread.java:717) "Thread-0" prio=10 tid=0xaf516800 nid=0x222f in Object.wait() [0xaf42c000] java.lang.Thread.State: RUNNABLE at Base.<clinit>(NPE.java:33) at NPE$1.run(NPE.java:54) at java.lang.Thread.run(Thread.java:717) "Low Memory Detector" daemon prio=10 tid=0xaf500c00 nid=0x222d runnable [0x00000000] java.lang.Thread.State: RUNNABLE "CompilerThread1" daemon prio=10 tid=0x08109c00 nid=0x222c waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "CompilerThread0" daemon prio=10 tid=0x08107800 nid=0x222b waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" daemon prio=10 tid=0x08105c00 nid=0x222a waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "Finalizer" daemon prio=10 tid=0x080f6c00 nid=0x2229 in Object.wait() [0xaf821000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0xecf30bd0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135) - locked <0xecf30bd0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177) "Reference Handler" daemon prio=10 tid=0x080f2000 nid=0x2228 in Object.wait() [0xaf872000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0xecf30990> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133) - locked <0xecf30990> (a java.lang.ref.Reference$Lock) "VM Thread" prio=10 tid=0x080ed400 nid=0x2227 runnable "GC task thread#0 (ParallelGC)" prio=10 tid=0x08057400 nid=0x2222 runnable "GC task thread#1 (ParallelGC)" prio=10 tid=0x08058c00 nid=0x2223 runnable "GC task thread#2 (ParallelGC)" prio=10 tid=0x0805a000 nid=0x2224 runnable "GC task thread#3 (ParallelGC)" prio=10 tid=0x0805b800 nid=0x2225 runnable "VM Periodic Task Thread" prio=10 tid=0xaf502c00 nid=0x222e waiting on condition JNI global references: 643 Heap PSYoungGen total 12480K, used 860K [0xecf30000, 0xedd10000, 0xf40f0000) eden space 10752K, 8% used [0xecf30000,0xed007148,0xed9b0000) from space 1728K, 0% used [0xedb60000,0xedb60000,0xedd10000) to space 1728K, 0% used [0xed9b0000,0xed9b0000,0xedb60000) PSOldGen total 113792K, used 0K [0xb40f0000, 0xbb010000, 0xecf30000) object space 113792K, 0% used [0xb40f0000,0xb40f0000,0xbb010000) PSPermGen total 16384K, used 1764K [0xb00f0000, 0xb10f0000, 0xb40f0000) object space 16384K, 10% used [0xb00f0000,0xb02a91d0,0xb10f0000) |
import java.util.*; import java.util.concurrent.*; import java.security.SecureRandom; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.lang.management.ManagementFactory; import java.util.concurrent.*; import java.util.concurrent.locks.*; import java.net.*; import java.lang.reflect.Field; import javax.management.*; import java.lang.management.*; import javax.script.*; import java.io.*; import java.util.Random; import java.security.SecureRandom; abstract class Base { static DerivedA a; static DerivedB b; static { a = new DerivedA(); Thread.yield(); while (NPE.proceed != 2); b = new DerivedB(); } } class DerivedA extends Base { } class DerivedB extends Base { } public class NPE { public static volatile int proceed = 0; static DerivedA a; static DerivedB b; public static void main(String[] args) { new Thread(new Runnable() { public void run() { proceed ++; a = new DerivedA(); } }).start(); new Thread(new Runnable() { public void run() { proceed ++; b = new DerivedB(); } }).start(); } }