-
Bug
-
Resolution: Fixed
-
P3
-
5.0
-
b83
-
generic
-
generic
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2137166 | 5.0u8 | Mala Bankal | P3 | Resolved | Fixed | b01 |
JDK-2142705 | 1.4.2_15 | Mala Bankal | P3 | Resolved | Fixed | b01 |
Deadlock happens with nsk/stress/jck12a/jck12a014. The following two threads
deadlock each other (the lock info in the thread dump is not very accurate).
"Thread-591" prio=10 tid=0x0053c898 nid=0x259 in Object.wait() [0xd157f000..0xd1
57fb10]
at java.util.logging.LogManager$Cleaner.run(LogManager.java:179)
- waiting to lock <0xf177beb0> (a java.util.logging.LogManager)
"Thread-453" prio=10 tid=0x004c2770 nid=0x1d0 waiting for monitor entry [0xd3f7c
000..0xd3f7fb90]
at java.util.logging.LogManager.addLogger(LogManager.java:292)
- waiting to lock <0xf177beb0> (a java.util.logging.LogManager)
at java.util.logging.LogManager+1.run(LogManager.java:160)
at java.security.AccessController.doPrivileged(Native Method)
at java.util.logging.LogManager.<clinit>(LogManager.java:141)
at java.util.logging.Logger.getLogger(Logger.java:228)
- locked <0xf4862c60> (a java.lang.Class)
at java.util.logging.Logger.<clinit>(Logger.java:181)
at java.awt.Component.<clinit>(Component.java:159)
at javasoft.sqe.tests.api.java.util.EventObject.serial.ConstructorTests.
ConstructorTest0001(ConstructorTests.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:494)
at javasoft.sqe.javatest.lib.MultiTest.run(MultiTest.java:177)
at javasoft.sqe.stresstest.StressTest$TestThread.run(StressTest.java:851
)
The full thread dump is attached.
Basically "Thread-591" locks LogManager.manager and waits for the class initializer
of LogManager to be finished. But "Thread-453" is inside the class initializer
of LogManager and it wants to lock LogManager.manager.
Usually instantiation can only happen after class is fully initialized. But in this
case, LogManager.manager is instantiated inside the class initializer of LogManager.
And "Thread-591" gets a chance to lock the object before class LogManager
is fully initialized.
Grabbing locks inside class initializer can be dangeous since there is a hidden
class object that other threads may be waiting on. It's required by spec, see
http://java.sun.com/docs/books/vmspec/2nd-edition/html/Concepts.doc.html#19075
Section 2.17.5, step 2.
It's also a question whether there are places in JDK other than LogManager that are
subject to such vulnerability.
The following simplified testcase shows the possibility of such deadlock.
// B.java
//
// Deadlock happens when Thread 0 is initializing class A and wants C.c and
// Thread 1 holds C.c and waits for Class A to be fully initialized.
class A {
static {
try { Thread.sleep(5000); } catch (Exception e) {}
synchronized (C.c) {
}
}
}
public class B {
public static void main(String[] args) {
// Thread 0
new Thread() {
public void run() {
// Cause Class A to be initialized.
new A();
}
}.start();
try { Thread.sleep(1000); } catch (Exception e) {}
// Thread 1
new Thread() {
public void run() {
synchronized (C.c) {
// Class A is being initialized so wait
// for the initialization to finish.
new A();
}
}
}.start();
}
}
class C {
static C c = new C();
}
###@###.### 2004-02-13
I've added a testcase provided by customer SAP which deadlogs if you:
a) run it on a multi-cpu box.
b) run it 1-5 times, often it happens on the 1st attempt.
HTH
deadlock each other (the lock info in the thread dump is not very accurate).
"Thread-591" prio=10 tid=0x0053c898 nid=0x259 in Object.wait() [0xd157f000..0xd1
57fb10]
at java.util.logging.LogManager$Cleaner.run(LogManager.java:179)
- waiting to lock <0xf177beb0> (a java.util.logging.LogManager)
"Thread-453" prio=10 tid=0x004c2770 nid=0x1d0 waiting for monitor entry [0xd3f7c
000..0xd3f7fb90]
at java.util.logging.LogManager.addLogger(LogManager.java:292)
- waiting to lock <0xf177beb0> (a java.util.logging.LogManager)
at java.util.logging.LogManager+1.run(LogManager.java:160)
at java.security.AccessController.doPrivileged(Native Method)
at java.util.logging.LogManager.<clinit>(LogManager.java:141)
at java.util.logging.Logger.getLogger(Logger.java:228)
- locked <0xf4862c60> (a java.lang.Class)
at java.util.logging.Logger.<clinit>(Logger.java:181)
at java.awt.Component.<clinit>(Component.java:159)
at javasoft.sqe.tests.api.java.util.EventObject.serial.ConstructorTests.
ConstructorTest0001(ConstructorTests.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:494)
at javasoft.sqe.javatest.lib.MultiTest.run(MultiTest.java:177)
at javasoft.sqe.stresstest.StressTest$TestThread.run(StressTest.java:851
)
The full thread dump is attached.
Basically "Thread-591" locks LogManager.manager and waits for the class initializer
of LogManager to be finished. But "Thread-453" is inside the class initializer
of LogManager and it wants to lock LogManager.manager.
Usually instantiation can only happen after class is fully initialized. But in this
case, LogManager.manager is instantiated inside the class initializer of LogManager.
And "Thread-591" gets a chance to lock the object before class LogManager
is fully initialized.
Grabbing locks inside class initializer can be dangeous since there is a hidden
class object that other threads may be waiting on. It's required by spec, see
http://java.sun.com/docs/books/vmspec/2nd-edition/html/Concepts.doc.html#19075
Section 2.17.5, step 2.
It's also a question whether there are places in JDK other than LogManager that are
subject to such vulnerability.
The following simplified testcase shows the possibility of such deadlock.
// B.java
//
// Deadlock happens when Thread 0 is initializing class A and wants C.c and
// Thread 1 holds C.c and waits for Class A to be fully initialized.
class A {
static {
try { Thread.sleep(5000); } catch (Exception e) {}
synchronized (C.c) {
}
}
}
public class B {
public static void main(String[] args) {
// Thread 0
new Thread() {
public void run() {
// Cause Class A to be initialized.
new A();
}
}.start();
try { Thread.sleep(1000); } catch (Exception e) {}
// Thread 1
new Thread() {
public void run() {
synchronized (C.c) {
// Class A is being initialized so wait
// for the initialization to finish.
new A();
}
}
}.start();
}
}
class C {
static C c = new C();
}
###@###.### 2004-02-13
I've added a testcase provided by customer SAP which deadlogs if you:
a) run it on a multi-cpu box.
b) run it 1-5 times, often it happens on the 1st attempt.
HTH
- backported by
-
JDK-2137166 deadlock in LogManager
- Resolved
-
JDK-2142705 deadlock in LogManager
- Resolved
- relates to
-
JDK-6651311 nsk/logging/Logger/setParent/setparent002 FAILS on 142_16/15fcs and UR but PASSES on 142_14fcs
- Resolved