< prev index next >

hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java

Print this page
rev 7149 : 8073688: Infinite loop reading types during jmap attach.
Reviewed-by: dsamersoff, sla

@@ -49,10 +49,13 @@
   private static final int UNINITIALIZED_SIZE = -1;
   private static final int C_INT8_SIZE  = 1;
   private static final int C_INT32_SIZE = 4;
   private static final int C_INT64_SIZE = 8;
   private static int pointerSize = UNINITIALIZED_SIZE;
+  // Counter to ensure read loops terminate:
+  private static final int MAX_DUPLICATE_DEFINITIONS = 100;
+  private int duplicateDefCount = 0;
 
   private static final boolean DEBUG;
   static {
     DEBUG = System.getProperty("sun.jvm.hotspot.HotSpotTypeDataBase.DEBUG")
             != null;

@@ -164,10 +167,14 @@
     typeEntryIsIntegerTypeOffset  = getLongValueFromProcess("gHotSpotVMTypeEntryIsIntegerTypeOffset");
     typeEntryIsUnsignedOffset     = getLongValueFromProcess("gHotSpotVMTypeEntryIsUnsignedOffset");
     typeEntrySizeOffset           = getLongValueFromProcess("gHotSpotVMTypeEntrySizeOffset");
     typeEntryArrayStride          = getLongValueFromProcess("gHotSpotVMTypeEntryArrayStride");
 
+    if (typeEntryArrayStride == 0L) {
+      throw new RuntimeException("zero stride: cannot read types.");
+    }
+
     // Start iterating down it until we find an entry with no name
     Address typeNameAddr = null;
     do {
       // Fetch the type name first
       typeNameAddr = entryAddr.getAddressAt(typeEntryTypeNameOffset);

@@ -190,11 +197,15 @@
           pointerSize = (int)size;
         }
       }
 
       entryAddr = entryAddr.addOffsetTo(typeEntryArrayStride);
-    } while (typeNameAddr != null);
+    } while (typeNameAddr != null && duplicateDefCount < MAX_DUPLICATE_DEFINITIONS);
+
+    if (duplicateDefCount >= MAX_DUPLICATE_DEFINITIONS) {
+      throw new RuntimeException("too many duplicate definitions");
+    }
   }
 
   private void initializePrimitiveTypes() {
     // Look up the needed primitive types by name...they had better be present
     setJBooleanType(lookupPrimitiveType("jboolean"));

@@ -393,10 +404,14 @@
     structEntryIsStaticOffset     = getLongValueFromProcess("gHotSpotVMStructEntryIsStaticOffset");
     structEntryOffsetOffset       = getLongValueFromProcess("gHotSpotVMStructEntryOffsetOffset");
     structEntryAddressOffset      = getLongValueFromProcess("gHotSpotVMStructEntryAddressOffset");
     structEntryArrayStride        = getLongValueFromProcess("gHotSpotVMStructEntryArrayStride");
 
+    if (structEntryArrayStride == 0L) {
+      throw new RuntimeException("zero stride: cannot read types.");
+    }
+
     // Fetch the address of the VMStructEntry*
     Address entryAddr = lookupInProcess("gHotSpotVMStructs");
     // Dereference this once to get the pointer to the first VMStructEntry
     entryAddr = entryAddr.getAddressAt(0);
     if (entryAddr == null) {

@@ -470,10 +485,15 @@
 
     intConstantEntryNameOffset  = getLongValueFromProcess("gHotSpotVMIntConstantEntryNameOffset");
     intConstantEntryValueOffset = getLongValueFromProcess("gHotSpotVMIntConstantEntryValueOffset");
     intConstantEntryArrayStride = getLongValueFromProcess("gHotSpotVMIntConstantEntryArrayStride");
 
+    if (intConstantEntryArrayStride == 0L) {
+      throw new RuntimeException("zero stride: cannot read types.");
+    }
+
+
     // Fetch the address of the VMIntConstantEntry*
     Address entryAddr = lookupInProcess("gHotSpotVMIntConstants");
     // Dereference this once to get the pointer to the first VMIntConstantEntry
     entryAddr = entryAddr.getAddressAt(0);
     if (entryAddr == null) {

@@ -499,16 +519,21 @@
                                        "\" had its value redefined (old was " + oldValue +
                                        ", new is " + value + ". Aborting.");
           } else {
             System.err.println("Warning: the int constant \"" + name + "\" (declared in the remote VM in VMStructs::localHotSpotVMIntConstants) " +
                                "had its value declared as " + value + " twice. Continuing.");
+            duplicateDefCount++;
           }
         }
       }
 
       entryAddr = entryAddr.addOffsetTo(intConstantEntryArrayStride);
-    } while (nameAddr != null);
+    } while (nameAddr != null && duplicateDefCount < MAX_DUPLICATE_DEFINITIONS);
+
+    if (duplicateDefCount >= MAX_DUPLICATE_DEFINITIONS) {
+      throw new RuntimeException("too many duplicate definitions");
+    }
   }
 
   private void readVMLongConstants() {
     // Get the variables we need in order to traverse the VMLongConstantEntry[]
     long longConstantEntryNameOffset;

@@ -517,10 +542,14 @@
 
     longConstantEntryNameOffset  = getLongValueFromProcess("gHotSpotVMLongConstantEntryNameOffset");
     longConstantEntryValueOffset = getLongValueFromProcess("gHotSpotVMLongConstantEntryValueOffset");
     longConstantEntryArrayStride = getLongValueFromProcess("gHotSpotVMLongConstantEntryArrayStride");
 
+    if (longConstantEntryArrayStride == 0L) {
+      throw new RuntimeException("zero stride: cannot read types.");
+    }
+
     // Fetch the address of the VMLongConstantEntry*
     Address entryAddr = lookupInProcess("gHotSpotVMLongConstants");
     // Dereference this once to get the pointer to the first VMLongConstantEntry
     entryAddr = entryAddr.getAddressAt(0);
     if (entryAddr == null) {

@@ -546,16 +575,21 @@
                                        "\" had its value redefined (old was " + oldValue +
                                        ", new is " + value + ". Aborting.");
           } else {
             System.err.println("Warning: the long constant \"" + name + "\" (declared in the remote VM in VMStructs::localHotSpotVMLongConstants) " +
                                "had its value declared as " + value + " twice. Continuing.");
+            duplicateDefCount++;
           }
         }
       }
 
       entryAddr = entryAddr.addOffsetTo(longConstantEntryArrayStride);
-    } while (nameAddr != null);
+    } while (nameAddr != null && duplicateDefCount < MAX_DUPLICATE_DEFINITIONS);
+
+    if (duplicateDefCount >= MAX_DUPLICATE_DEFINITIONS) {
+      throw new RuntimeException("too many duplicate definitions.");
+    }
   }
 
   private BasicType lookupOrFail(String typeName) {
     BasicType type = (BasicType) lookupType(typeName, false);
     if (type == null) {

@@ -740,10 +774,11 @@
             }
 
             if (!typeNameIsPointerType(typeName)) {
             System.err.println("Warning: the type \"" + typeName + "\" (declared in the remote VM in VMStructs::localHotSpotVMTypes) " +
                                "had its size declared as " + size + " twice. Continuing.");
+                duplicateDefCount++;
         }
         }
 
     }
 
< prev index next >