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

Hashtable.writeObject() synchronization risks serialization deadlock

XMLWordPrintable

    • beta
    • b132
    • generic
    • generic
    • Verified

      NOTE
      ----
      This issue was previously investigated under CR 5085747, but it was closed
      due to a lack of sufficient information or testcase. A Licensee has provided
      us with with a testcase in hopes of us picking up on a fresh investigation.
      Please cross-refernce the related bug id's to supplement this new investigation.

      OPERATING SYSTEM
      ----------------
      All

      FULL JDK VERSION
      ----------------
      All current JDKs, including 7-ea-b83, 6u18, 5.0u23, 1.4.2_25

      DESCRIPTION
      -----------
      See CR 5085747 Description, comments, eval.

      REPRODUCTION INSTRUCTIONS
      -------------------------
      1. Compile and run attached testcase, HTProblem.java.
      2. Wait until "Deadlock" message is printed.
      3. Gather a thread dump using CTRL-BREAK or "kill -3".
      4. Observe the deadlock below:

      Found one Java-level deadlock:
      =============================
      "Thread-1":
        waiting to lock monitor 0x0aab8654 (object 0x029d35b0, a java.util.Hashtable),
        which is held by "Thread-0"
      "Thread-0":
        waiting to lock monitor 0x0aaf5a24 (object 0x029d3610, a java.util.Hashtable),
        which is held by "Thread-1"

      Java stack information for the threads listed above:
      ===================================================
      "Thread-1":
              at java.util.Hashtable.writeObject(Hashtable.java:814)
              - waiting to lock <0x029d35b0> (a java.util.Hashtable)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:597)
              at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
              at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
              at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
              at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
              at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
              at MyObject.writeObject(HTProblem.java:48)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:597)
              at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
              at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
              at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
              at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
              at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
              at java.util.Hashtable.writeObject(Hashtable.java:824)
              - locked <0x029d3610> (a java.util.Hashtable)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:597)
              at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
              at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
              at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
              at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
              at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
              at MyThread.run(HTProblem.java:68)
      "Thread-0":
              at java.util.Hashtable.writeObject(Hashtable.java:814)
              - waiting to lock <0x029d3610> (a java.util.Hashtable)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:597)
              at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
              at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
              at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
              at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
              at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
              at MyObject.writeObject(HTProblem.java:48)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:597)
              at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
              at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
              at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
              at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
              at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
              at java.util.Hashtable.writeObject(Hashtable.java:824)
              - locked <0x029d35b0> (a java.util.Hashtable)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:597)
              at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
              at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
              at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
              at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
              at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
              at MyThread.run(HTProblem.java:68)

      Found 1 deadlock.


      TESTCASE SOURCE
      ---------------
      import java.io.FileNotFoundException;
      import java.io.IOException;
      import java.io.ObjectOutput;
      import java.io.ObjectOutputStream;
      import java.io.Serializable;
      import java.io.FileOutputStream;
      import java.util.Hashtable;

      public class HTProblem {
       public static void main(String args[]) {
      MyObject mo1=new MyObject();
      MyObject mo2=new MyObject();
      Hashtable ht1=new Hashtable();
      Hashtable ht2=new Hashtable();
      mo1.ht=ht2;
      mo1.sleepTime=100;
      mo2.ht=ht1;
      mo2.sleepTime=100;
      ht1.put("key",mo1);
      ht2.put("key",mo2);
      MyThread t1=new MyThread(ht1,"file1");
      MyThread t2=new MyThread(ht2,"file2");
      t1.start();
      t2.start();
      try {
      Thread.sleep(5000);
      } catch (Exception e) {
      e.printStackTrace();
      }
      if(t1.isAlive() && t2.isAlive()) {
      System.out.println("Deadlock");
      }
      }
       
      }

      class MyObject implements Serializable{
      public transient Hashtable ht;
      public transient long sleepTime;

          private void writeObject(java.io.ObjectOutputStream s)
          throws IOException
      {
      try {
      Thread.sleep(sleepTime);
      } catch (Exception e) {
      }
      s.writeObject(ht);
      }

          private void readObject(java.io.ObjectInputStream s)
          throws IOException, ClassNotFoundException
      {
      ht = (Hashtable)s.readObject();
      }
      }

      class MyThread extends Thread {
      Hashtable ht;
      String file;
      public MyThread(Hashtable ht,String file){
      this.ht=ht;
      this.file=file;
      }
      public void run() {
      try {
      ObjectOutput oo=new ObjectOutputStream(new FileOutputStream(file));
      oo.writeObject(ht);
      } catch (FileNotFoundException e) {
      e.printStackTrace();
      } catch (IOException e) {
      e.printStackTrace();
      }
      }
      }

            mduigou Mike Duigou
            dkorbel David Korbel (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: