7177128: SA cannot get correct system properties after 7126277

Fri, 22 Jun 2012 15:39:16 -0700

author
minqi
date
Fri, 22 Jun 2012 15:39:16 -0700
changeset 3873
d8a240abb23a
parent 3872
cfa2c82f4c04
child 3874
588f559105c1
child 3875
246d977b51f2

7177128: SA cannot get correct system properties after 7126277
Summary: Bug fix of 7126277 changed hashing algorithm and also changed key as final field, this led SA unable to set correct value for key. Solution by reading key/value and insert them into the new table.
Reviewed-by: dholmes, mikael
Contributed-by: yumin.qi@oracle.com

agent/src/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java file | annotate | diff | comparison | revisions
     1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java	Fri Jun 22 15:35:30 2012 -0700
     1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java	Fri Jun 22 15:39:16 2012 -0700
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -85,6 +85,21 @@
    1.11        this(new ProcImageClassLoader());
    1.12     }
    1.13  
    1.14 +   static void debugPrintln(String msg) {
    1.15 +      if (DEBUG) {
    1.16 +         System.err.println("DEBUG>" + msg);
    1.17 +      }
    1.18 +   }
    1.19 +
    1.20 +   static void debugPrintStackTrace(Exception exp) {
    1.21 +      if (DEBUG) {
    1.22 +         StackTraceElement[] els = exp.getStackTrace();
    1.23 +         for (int i = 0; i < els.length; i++) {
    1.24 +            System.err.println("DEBUG>" + els[i].toString());
    1.25 +         }
    1.26 +      }
    1.27 +   }
    1.28 +
    1.29     public Object readObject(Oop oop) throws ClassNotFoundException {
    1.30        if (oop instanceof Instance) {
    1.31           return readInstance((Instance) oop);
    1.32 @@ -120,13 +135,96 @@
    1.33     }
    1.34  
    1.35     protected Symbol javaLangString;
    1.36 +   protected Symbol javaUtilHashtableEntry;
    1.37 +   protected Symbol javaUtilHashtable;
    1.38 +   protected Symbol javaUtilProperties;
    1.39 +
    1.40 +   protected Symbol getVMSymbol(String name) {
    1.41 +      return VM.getVM().getSymbolTable().probe(name);
    1.42 +   }
    1.43 +
    1.44     protected Symbol javaLangString() {
    1.45        if (javaLangString == null) {
    1.46 -         javaLangString = VM.getVM().getSymbolTable().probe("java/lang/String");
    1.47 +         javaLangString = getVMSymbol("java/lang/String");
    1.48        }
    1.49        return javaLangString;
    1.50     }
    1.51  
    1.52 +   protected Symbol javaUtilHashtableEntry() {
    1.53 +      if (javaUtilHashtableEntry == null) {
    1.54 +         javaUtilHashtableEntry = getVMSymbol("java/util/Hashtable$Entry");
    1.55 +      }
    1.56 +      return javaUtilHashtableEntry;
    1.57 +   }
    1.58 +
    1.59 +   protected Symbol javaUtilHashtable() {
    1.60 +      if (javaUtilHashtable == null) {
    1.61 +         javaUtilHashtable = getVMSymbol("java/util/Hashtable");
    1.62 +      }
    1.63 +      return javaUtilHashtable;
    1.64 +   }
    1.65 +
    1.66 +   protected Symbol javaUtilProperties() {
    1.67 +      if (javaUtilProperties == null) {
    1.68 +         javaUtilProperties = getVMSymbol("java/util/Properties");
    1.69 +      }
    1.70 +      return javaUtilProperties;
    1.71 +   }
    1.72 +
    1.73 +   private void setHashtableEntry(java.util.Hashtable p, Oop oop) {
    1.74 +      InstanceKlass ik = (InstanceKlass)oop.getKlass();
    1.75 +      OopField keyField = (OopField)ik.findField("key", "Ljava/lang/Object;");
    1.76 +      OopField valueField = (OopField)ik.findField("value", "Ljava/lang/Object;");
    1.77 +      OopField nextField = (OopField)ik.findField("next", "Ljava/util/Hashtable$Entry;");
    1.78 +      if (DEBUG) {
    1.79 +         if (Assert.ASSERTS_ENABLED) {
    1.80 +            Assert.that(ik.getName().equals(javaUtilHashtableEntry()), "Not a Hashtable$Entry?");
    1.81 +            Assert.that(keyField != null && valueField != null && nextField != null, "Invalid fields!");
    1.82 +         }
    1.83 +      }
    1.84 +
    1.85 +      Object key = null;
    1.86 +      Object value = null;
    1.87 +      Oop next = null;
    1.88 +      try {
    1.89 +         key = readObject(keyField.getValue(oop));
    1.90 +         value = readObject(valueField.getValue(oop));
    1.91 +         next =  (Oop)nextField.getValue(oop);
    1.92 +         // For Properties, should use setProperty(k, v). Since it only runs in SA
    1.93 +         // using put(k, v) should be OK.
    1.94 +         p.put(key, value);
    1.95 +         if (next != null) {
    1.96 +            setHashtableEntry(p, next);
    1.97 +         }
    1.98 +      } catch (ClassNotFoundException ce) {
    1.99 +         if( DEBUG) {
   1.100 +            debugPrintln("Class not found " + ce);
   1.101 +            debugPrintStackTrace(ce);
   1.102 +         }
   1.103 +      }
   1.104 +   }
   1.105 +
   1.106 +   protected Object getHashtable(Instance oop, boolean isProperties) {
   1.107 +      InstanceKlass k = (InstanceKlass)oop.getKlass();
   1.108 +      OopField tableField = (OopField)k.findField("table", "[Ljava/util/Hashtable$Entry;");
   1.109 +      if (tableField == null) {
   1.110 +         debugPrintln("Could not find field of [Ljava/util/Hashtable$Entry;");
   1.111 +         return null;
   1.112 +      }
   1.113 +      java.util.Hashtable table = (isProperties) ? new java.util.Properties()
   1.114 +                                                 : new java.util.Hashtable();
   1.115 +      ObjArray kvs = (ObjArray)tableField.getValue(oop);
   1.116 +      long size = kvs.getLength();
   1.117 +      debugPrintln("Hashtable$Entry Size = " + size);
   1.118 +      for (long i=0; i<size; i++) {
   1.119 +         Oop entry = kvs.getObjAt(i);
   1.120 +         if (entry != null && entry.isInstance()) {
   1.121 +            setHashtableEntry(table, entry);
   1.122 +         }
   1.123 +      }
   1.124 +      return table;
   1.125 +   }
   1.126 +
   1.127     public Object readInstance(Instance oop) throws ClassNotFoundException {
   1.128        Object result = getFromObjTable(oop);
   1.129        if (result == null) {
   1.130 @@ -134,11 +232,21 @@
   1.131           // Handle java.lang.String instances differently. As part of JSR-133, fields of immutable
   1.132           // classes have been made final. The algorithm below will not be able to read Strings from
   1.133           // debuggee (can't use reflection to set final fields). But, need to read Strings is very
   1.134 -         // important. FIXME: need a framework to handle many other special cases.
   1.135 +         // important.
   1.136 +         // Same for Hashtable, key and hash are final, could not be set in the algorithm too.
   1.137 +         // FIXME: need a framework to handle many other special cases.
   1.138           if (kls.getName().equals(javaLangString())) {
   1.139              return OopUtilities.stringOopToString(oop);
   1.140           }
   1.141  
   1.142 +         if (kls.getName().equals(javaUtilHashtable())) {
   1.143 +            return getHashtable(oop, false);
   1.144 +         }
   1.145 +
   1.146 +         if (kls.getName().equals(javaUtilProperties())) {
   1.147 +            return getHashtable(oop, true);
   1.148 +         }
   1.149 +
   1.150           Class clz = readClass(kls);
   1.151           try {
   1.152              result = clz.newInstance();
   1.153 @@ -164,8 +272,8 @@
   1.154                    break;
   1.155                 } catch (Exception exp) {
   1.156                    if (DEBUG) {
   1.157 -                     System.err.println("Can't create object using " + c);
   1.158 -                     exp.printStackTrace();
   1.159 +                     debugPrintln("Can't create object using " + c);
   1.160 +                     debugPrintStackTrace(exp);
   1.161                    }
   1.162                 }
   1.163              }
   1.164 @@ -329,8 +437,8 @@
   1.165                                       arrayObj[ifd.getIndex()] = readObject(field.getValue(getObj()));
   1.166                                    } catch (Exception e) {
   1.167                                       if (DEBUG) {
   1.168 -                                        System.err.println("Array element set failed for " + ifd);
   1.169 -                                        e.printStackTrace();
   1.170 +                                        debugPrintln("Array element set failed for " + ifd);
   1.171 +                                        debugPrintStackTrace(e);
   1.172                                       }
   1.173                                    }
   1.174                                 }
   1.175 @@ -348,8 +456,8 @@
   1.176  
   1.177        private void printFieldSetError(java.lang.reflect.Field f, Exception ex) {
   1.178           if (DEBUG) {
   1.179 -            if (f != null) System.err.println("Field set failed for " + f);
   1.180 -            ex.printStackTrace();
   1.181 +            if (f != null) debugPrintln("Field set failed for " + f);
   1.182 +            debugPrintStackTrace(ex);
   1.183           }
   1.184        }
   1.185  
   1.186 @@ -601,7 +709,7 @@
   1.187              return Class.forName(className, true, cl);
   1.188           } catch (Exception e) {
   1.189              if (DEBUG) {
   1.190 -               System.err.println("Can't load class " + className);
   1.191 +               debugPrintln("Can't load class " + className);
   1.192              }
   1.193              throw new RuntimeException(e);
   1.194           }

mercurial