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

Reflect.Instances.add of a null causes a Sig 11 in 1.4.2

XMLWordPrintable

    • b49
    • x86
    • linux, windows_xp

       Set s1 = (Set)((Map.Entry)o1).getValue();
                              Set s2 = (Set)((Map.Entry)o2).getValue();
                              return s2.size() - s1.size();
                          }
                      });
                  return new Itr(v);
              default:
                  throw new IllegalArgumentException();
              }
          }

          // Iterates over the given collection of map entries
          static private class Itr implements Iterator {
              Iterator i;
              Itr(Collection c) {
                  i = c.iterator();
              }
              public boolean hasNext () {
                  return i.hasNext();
              }
              public Object next () {
                  Map.Entry entry = (Map.Entry)i.next();
                  return entry.getKey()+": "+((Set)entry.getValue()).size();
              }
              public void remove () {
                  i.remove();
              }
          }

          /** Merges the given graph into this graph and returns the
           * combined graph. Any type that appeared in one of the two
           * graphs now appears in this graph. If the same instance appears
           * in both graphs, it counts only as one instance in the new
           * graph. In particular, adding a graph to itself leaves this
           * graph unchanged.
           *
           * @param inst a graph of instances, along with their type names
           * @return this graph after the merge
           */
          public Instances add (Instances inst) {
              Iterator i = inst.allInstances.entrySet().iterator();
              while (i.hasNext()) {
                  Map.Entry e = (Map.Entry)i.next();
                  String key = (String)e.getKey();
                  Set more = (Set)e.getValue();
                  Set s = (Set)allInstances.get(key);
                  if (s == null)
                      allInstances.put(key, s = new HashSet());
                  s.addAll(more);
              }
              return this;
          }

          /*
          // for debugging purposes
          public String toString () {
              StringBuffer b = new StringBuffer();
              Iterator i = allInstances.keySet().iterator();
              while (i.hasNext()) {
                  Object key = i.next();
                  b.append("("+key+","+allInstances.get(key)+")\n");
              }
              return b.toString();
          }
          */

          public static void main (String[] args) {
              Instances inst = new Instances(new Thread() {public void run(){}});
          }
      }

      REPRODUCIBILITY :
      This bug can be reproduced always.
      (Incident Review ID: 240076)
      ======================================================================


      Name: rmT116609 Date: 03/12/2004


      FULL PRODUCT VERSION :
      java version "1.4.2"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-b28)
      Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)

      java version "1.5.0-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b32c)
      Java HotSpot(TM) Client VM (build 1.5.0-beta-b32c, mixed mode)

      FULL OS VERSION :
      Linux berlioz 2.4.20-13.9custom #4 Wed Sep 24 08:56:20 EDT 2003 i686 i686 i386 GNU/Linux


      A DESCRIPTION OF THE PROBLEM :
      The VM crashes while running a recursive method. The method uses reflection to list all the instances referenced by a Thread object.


      ERROR MESSAGES/STACK TRACES THAT OCCUR :

      Unexpected Signal : 11 occurred at PC=0x404216B8
      Function=(null)+0x404216B8
      Library=/usr/java/j2sdk1.4.2/jre/lib/i386/client/libjvm.so

      NOTE: We are unable to locate the function name symbol for the error
            just occurred. Please refer to release documentation for possible
            reason and solutions.


      Current Java thread:
      at java.lang.Class.getName(Native Method)
      at Reflect.Instances.add(Instances.java:36)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:46)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:46)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:46)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:46)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.add(Instances.java:57)
      at Reflect.Instances.main(Instances.java:121)

      Dynamic libraries:
      08048000-0804e000 r-xp 00000000 03:07 115900 /usr/java/j2sdk1.4.2/bin/java
      0804e000-0804f000 rw-p 00005000 03:07 115900 /usr/java/j2sdk1.4.2/bin/java
      40000000-40012000 r-xp 00000000 03:03 48178 /lib/ld-2.3.2.so
      40012000-40013000 rw-p 00011000 03:03 48178 /lib/ld-2.3.2.so
      40014000-4001c000 r-xp 00000000 03:07 588040 /usr/java/j2sdk1.4.2/jre/lib/i386/native_threads/libhpi.so
      4001c000-4001d000 rw-p 00007000 03:07 588040 /usr/java/j2sdk1.4.2/jre/lib/i386/native_threads/libhpi.so
      4001d000-40021000 rw-s 00000000 03:03 144855 /tmp/hsperfdata_charpov/7966
      40022000-40030000 r-xp 00000000 03:03 48127 /lib/libpthread-0.10.so
      40030000-40033000 rw-p 0000e000 03:03 48127 /lib/libpthread-0.10.so
      40073000-40075000 r-xp 00000000 03:03 48109 /lib/libdl-2.3.2.so
      40075000-40076000 rw-p 00002000 03:03 48109 /lib/libdl-2.3.2.so
      40076000-40196000 r-xp 00000000 03:03 48105 /lib/libc-2.3.2.so
      40196000-40199000 rw-p 00120000 03:03 48105 /lib/libc-2.3.2.so
      4019c000-40593000 r-xp 00000000 03:07 490517 /usr/java/j2sdk1.4.2/jre/lib/i386/client/libjvm.so
      40593000-405ae000 rw-p 003f6000 03:07 490517 /usr/java/j2sdk1.4.2/jre/lib/i386/client/libjvm.so
      405c1000-405d1000 r-xp 00000000 03:03 48113 /lib/libnsl-2.3.2.so
      405d1000-405d2000 rw-p 00010000 03:03 48113 /lib/libnsl-2.3.2.so
      405d4000-405f4000 r-xp 00000000 03:03 48111 /lib/libm-2.3.2.so
      405f4000-405f5000 rw-p 00020000 03:03 48111 /lib/libm-2.3.2.so
      405f5000-405f8000 r--s 00000000 03:07 881428 /usr/java/j2sdk1.4.2/jre/lib/ext/dnsns.jar
      405f8000-405fe000 r--s 00000000 03:07 407433 /usr/lib/gconv/gconv-modules.cache
      40603000-4060d000 r-xp 00000000 03:03 48192 /lib/libnss_compat-2.3.2.so
      4060d000-4060e000 rw-p 00009000 03:03 48192 /lib/libnss_compat-2.3.2.so
      4060e000-4061e000 r-xp 00000000 03:07 588047 /usr/java/j2sdk1.4.2/jre/lib/i386/libverify.so
      4061e000-40620000 rw-p 0000f000 03:07 588047 /usr/java/j2sdk1.4.2/jre/lib/i386/libverify.so
      40620000-40640000 r-xp 00000000 03:07 588048 /usr/java/j2sdk1.4.2/jre/lib/i386/libjava.so
      40640000-40642000 rw-p 0001f000 03:07 588048 /usr/java/j2sdk1.4.2/jre/lib/i386/libjava.so
      40642000-40656000 r-xp 00000000 03:07 588050 /usr/java/j2sdk1.4.2/jre/lib/i386/libzip.so
      40656000-40659000 rw-p 00013000 03:07 588050 /usr/java/j2sdk1.4.2/jre/lib/i386/libzip.so
      40659000-41fe4000 r--s 00000000 03:07 588306 /usr/java/j2sdk1.4.2/jre/lib/rt.jar
      4202e000-42044000 r--s 00000000 03:07 588277 /usr/java/j2sdk1.4.2/jre/lib/sunrsasign.jar
      42044000-4211f000 r--s 00000000 03:07 588303 /usr/java/j2sdk1.4.2/jre/lib/jsse.jar
      4211f000-42130000 r--s 00000000 03:07 588278 /usr/java/j2sdk1.4.2/jre/lib/jce.jar
      42130000-42689000 r--s 00000000 03:07 588304 /usr/java/j2sdk1.4.2/jre/lib/charsets.jar
      44731000-4473e000 r--s 00000000 03:07 881430 /usr/java/j2sdk1.4.2/jre/lib/ext/ldapsec.jar
      4c7c0000-4c9c0000 r--p 00000000 03:07 196947 /usr/lib/locale/locale-archive
      4c9c0000-4c9dc000 r--s 00000000 03:07 881427 /usr/java/j2sdk1.4.2/jre/lib/ext/sunjce_provider.jar
      4c9dc000-4ca98000 r--s 00000000 03:07 881462 /usr/java/j2sdk1.4.2/jre/lib/ext/localedata.jar

      Heap at VM Abort:
      Heap
       def new generation total 576K, used 497K [0x44740000, 0x447e0000, 0x44c20000)
        eden space 512K, 97% used [0x44740000, 0x447bc498, 0x447c0000)
        from space 64K, 0% used [0x447c0000, 0x447c0000, 0x447d0000)
        to space 64K, 0% used [0x447d0000, 0x447d0000, 0x447e0000)
       tenured generation total 1408K, used 0K [0x44c20000, 0x44d80000, 0x48740000)
         the space 1408K, 0% used [0x44c20000, 0x44c20000, 0x44c20200, 0x44d80000)
       compacting perm gen total 4096K, used 1154K [0x48740000, 0x48b40000, 0x4c740000)
         the space 4096K, 28% used [0x48740000, 0x48860be8, 0x48860c00, 0x48b40000)

      Local Time = Mon Feb 23 17:51:34 2004
      Elapsed Time = 2
      #
      # HotSpot Virtual Machine Error : 11
      # Error ID : 4F530E43505002EF
      # Please report this error at
      # http://java.sun.com/cgi-bin/bugreport.cgi
      #
      # Java VM: Java HotSpot(TM) Client VM (1.4.2-b28 mixed mode)
      #


      With 1.5.0 Beta 1:

       of type class java.lang.Class
       of type class java.lang.String
       of type class [C
       of type class [Ljava.io.ObjectStreamField;
       of type class java.lang.String$CaseInsensitiveComparator
       of type class java.lang.Class
       of type class [Ljava.io.ObjectStreamField;
       of type class sun.reflect.ReflectionFactory
       of type class [Ljava.lang.annotation.Annotation;
       of type class sun.reflect.UnsafeStaticObjectFieldAccessorImpl
      #
      # An unexpected error has been detected by HotSpot Virtual Machine:
      #
      # SIGSEGV (0xb) at pc=0x403473f8, pid=2783, tid=8192
      #
      # Java VM: Java HotSpot(TM) Client VM (1.5.0-beta-b32c mixed mode)
      # Problematic frame:
      # V [libjvm.so+0x2e43f8]
      #
      # An error report file with more information is saved as hs_err_pid2783.log
      #
      # If you would like to submit a bug report, please visit:
      # http://java.sun.com/webapps/bugreport/crash.jsp



      Source Code:

      package Reflect;

      // as is, it crashes
      // uncomment line 111 to get a bizarre exception
      // (object o seems to "become" null inside String.ValueOf)
      // Replace the call to recAdd by iterAdd on line 81 to get the same kind of
      // strange thing: ArrayStoreException in Vector.addElement!


      import java.util.*;
      import java.lang.reflect.*;

      /** Explores a graph of instances. Given an object as a starting
       * point, all instances reachable from this object are explored. This
       * implementation can then provide a list of all the types encountered
       * along with the number of occurrences in each type. Different
       * graphs can be combined using the <code>add</code> method.
       *
       * @author Michel Charpentier
       * @version 1.0, 02/24/04
       * @see Class
       * @see <a href="Tests.java">Tests.java</a>
       */
      public class Instances {

          /** Types are returned in an unspecified order.
           *
           * @see #iterator
           */
          public static final int UNSORTED = 0;

          /** Types are returned in alphabetical order of their fully qualified names.
           *
           * @see #iterator
           */
          public static final int SORTED_BY_NAME = 1;

          /** Types are returned in decreasing order of the number of
           * occurrences in each type.
           *
           * @see #iterator
           */
          public static final int SORTED_BY_OCCURRENCES = 2;

          // Keys are type names, values are sets of instances
          private final Map allInstances = new TreeMap();

          // Wrapper around instances to make java.util stuff rely on ==
          // instead of equals()
          static private class Instance {
              Object instance;
              Instance (Object o) {
                  instance = o;
              }
              public boolean equals (Object o) {
                  return ((Instance)o).instance == this.instance;
              }
              public int hashCode () {
                  return instance.hashCode();
              }
              public String toString () { // for debugging purposes
                  return instance.toString();
              }
          }

          /** Construct a new graph by adding instance <code>o</code> and
           * all instances reachable from <code>o</code> to an empty graph. This
           * constructor attempts to follow all data members regardless of their
           * visibility.
           *
           * @param o initial instance
           * @throws SecurityException if a security manager prevents
           * the method from accessing some data member
           * @see SecurityManager
           */
          public Instances (Object o) throws SecurityException {
              if (o == null)
                  throw new NullPointerException();
              recAdd(o, -1);
          }

          /** Construct a new graph by adding instance <code>o</code> and
           * all instances reachable from <code>o</code> within the given
           * <code>depth</code> to an empty graph. A depth of 0 only adds object
           * <code>o</code>; a depth of 1 adds all the fields of
           * <code>o</code>. This constructor attempts to follow all data
           * members regardless of their visibility.
           *
           * @param o initial instance
           * @param depth depth of the exploration (maximum distance from
           * origin <code>o</code>
           * @throws IllegalArgumentException if <code>depth</code> is negative
           * @throws SecurityException if a security manager prevents
           * the method from accessing some data member
           * @see SecurityManager
           */
          public Instances (Object o, int depth) throws SecurityException {
              if (o == null)
                  throw new NullPointerException();
              if (depth < 0)
                  throw new IllegalArgumentException("depth cannot be negative.");
              recAdd(o, depth+1);
          }

          // recursive solution
          private void recAdd (Object o, int depth) {
              if (o == null || depth == 0) return;
              Class c = o.getClass();
              //System.out.print("Found "+o);
              System.out.println(" of type "+c);
              String name = c.getName();
              Set s = (Set)allInstances.get(name);
              if (s == null) // first occurrence of this type
                  allInstances.put(name, s = new HashSet());
              if (s.add(new Instance(o))) {
                  if (c.isArray() && !c.getComponentType().isPrimitive()) {
                      int l = Array.getLength(o);
                      for (int i=0; i<l; i++)
                          recAdd(Array.get(o, i), depth-1);
                      return; // is this safe?
                  }
                  do {
                      Field[] fields = c.getDeclaredFields();
                      AccessibleObject.setAccessible(fields, true);
                      for (int i=0; i<fields.length; i++) {
                          Field f = fields[i];
                          if (!f.getType().isPrimitive())
                              try {
                                  recAdd(f.get(o), depth-1);
                              } catch (IllegalAccessException e) {
                                  System.err.println
                                      ("Could not follow field "+f+" in "+c);
                              }
                      }
                      c = c.getSuperclass();
                  } while (c != null);
              }
          }

          // iterative solution
          private void iterAdd (Object start, int depth) {
              Stack stack1 = new Stack();
              stack1.push(start);
              while (depth != 0) {
                  Stack stack2 = new Stack();
                  while (!stack1.isEmpty()) {
                      Object o = stack1.pop();
                      if (o == null) continue;
                      Class c = o.getClass();
                      String name = c.getName();
                      Set s = (Set)allInstances.get(name);
                      if (s == null) // first occurrence of this type
                          allInstances.put(name, s = new HashSet());
                      if (s.add(new Instance(o))) {
                          if (c.isArray() && !c.getComponentType().isPrimitive()) {
                              int l = Array.getLength(o);
                              for (int i=0; i<l; i++)
                                  stack2.push(Array.get(o, i));
                              continue; // is it safe?
                          }
                          do {
                              Field[] fields = c.getDeclaredFields();
                              AccessibleObject.setAccessible(fields, true);
                              for (int i=0; i<fields.length; i++) {
                                  Field f = fields[i];
                                  if (!f.getType().isPrimitive())
                                      try {
                                          stack2.push(f.get(o));
                                      } catch (IllegalAccessException e) {
                                          System.err.println
                                              ("Could not follow field "+f+" in "+c);
                                      }
                              }
                              c = c.getSuperclass();
                          } while (c != null);
                      }
                  }
                  if (stack2.isEmpty()) break;
                  stack1 = stack2;
                  depth--;
              }
          }

          /** An iterator over all the class names found in the graph. Each call
           * to <code>next()</code> returns a <code>String</code>. These
           * strings are in no particular order, in alphabetical order, or
           * in decreasing order of the number of occurrences of this type,
           * depending on the value of <code>type</code>.
           *
           * @param type specifies the order of iteration
           * @return an iterator of class names (as strings), in the specified order
           * @see #UNSORTED
           * @see #SORTED_BY_NAME
           * @see #SORTED_BY_OCCURRENCES
           */
          public Iterator iterator (int type) {
              switch (type) {
              case UNSORTED:
              case SORTED_BY_NAME:
                  return new Itr(allInstances.entrySet());
              case SORTED_BY_OCCURRENCES:
                  Vector v = new Vector(allInstances.entrySet());
                  Collections.sort(v, new Comparator() {
                          public int compare (Object o1, Object o2) {
                             

            kbr Kenneth Russell (Inactive)
            rmandalasunw Ranjith Mandala (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: