Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4994705

deadlock in LogManager

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 5.0
    • Fix Version/s: 6
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • Resolved In Build:
      b83
    • CPU:
      generic
    • OS:
      generic
    • Verification:
      Verified

      Backports

        Description

        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

          Attachments

            Issue Links

              Activity

                People

                Assignee:
                sspitsyn Serguei Spitsyn
                Reporter:
                myangsunw Mingyao Yang (Inactive)
                Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                  Dates

                  Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: