Tue, 03 Mar 2015 19:42:09 +0000
8073688: Infinite loop reading types during jmap attach.
Reviewed-by: dsamersoff, sla
agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java | file | annotate | diff | comparison | revisions |
1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java Fri Mar 06 17:33:37 2015 -0800 1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java Tue Mar 03 19:42:09 2015 +0000 1.3 @@ -51,6 +51,9 @@ 1.4 private static final int C_INT32_SIZE = 4; 1.5 private static final int C_INT64_SIZE = 8; 1.6 private static int pointerSize = UNINITIALIZED_SIZE; 1.7 + // Counter to ensure read loops terminate: 1.8 + private static final int MAX_DUPLICATE_DEFINITIONS = 100; 1.9 + private int duplicateDefCount = 0; 1.10 1.11 private static final boolean DEBUG; 1.12 static { 1.13 @@ -166,6 +169,10 @@ 1.14 typeEntrySizeOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySizeOffset"); 1.15 typeEntryArrayStride = getLongValueFromProcess("gHotSpotVMTypeEntryArrayStride"); 1.16 1.17 + if (typeEntryArrayStride == 0L) { 1.18 + throw new RuntimeException("zero stride: cannot read types."); 1.19 + } 1.20 + 1.21 // Start iterating down it until we find an entry with no name 1.22 Address typeNameAddr = null; 1.23 do { 1.24 @@ -192,7 +199,11 @@ 1.25 } 1.26 1.27 entryAddr = entryAddr.addOffsetTo(typeEntryArrayStride); 1.28 - } while (typeNameAddr != null); 1.29 + } while (typeNameAddr != null && duplicateDefCount < MAX_DUPLICATE_DEFINITIONS); 1.30 + 1.31 + if (duplicateDefCount >= MAX_DUPLICATE_DEFINITIONS) { 1.32 + throw new RuntimeException("too many duplicate definitions"); 1.33 + } 1.34 } 1.35 1.36 private void initializePrimitiveTypes() { 1.37 @@ -395,6 +406,10 @@ 1.38 structEntryAddressOffset = getLongValueFromProcess("gHotSpotVMStructEntryAddressOffset"); 1.39 structEntryArrayStride = getLongValueFromProcess("gHotSpotVMStructEntryArrayStride"); 1.40 1.41 + if (structEntryArrayStride == 0L) { 1.42 + throw new RuntimeException("zero stride: cannot read types."); 1.43 + } 1.44 + 1.45 // Fetch the address of the VMStructEntry* 1.46 Address entryAddr = lookupInProcess("gHotSpotVMStructs"); 1.47 // Dereference this once to get the pointer to the first VMStructEntry 1.48 @@ -472,6 +487,11 @@ 1.49 intConstantEntryValueOffset = getLongValueFromProcess("gHotSpotVMIntConstantEntryValueOffset"); 1.50 intConstantEntryArrayStride = getLongValueFromProcess("gHotSpotVMIntConstantEntryArrayStride"); 1.51 1.52 + if (intConstantEntryArrayStride == 0L) { 1.53 + throw new RuntimeException("zero stride: cannot read types."); 1.54 + } 1.55 + 1.56 + 1.57 // Fetch the address of the VMIntConstantEntry* 1.58 Address entryAddr = lookupInProcess("gHotSpotVMIntConstants"); 1.59 // Dereference this once to get the pointer to the first VMIntConstantEntry 1.60 @@ -501,12 +521,17 @@ 1.61 } else { 1.62 System.err.println("Warning: the int constant \"" + name + "\" (declared in the remote VM in VMStructs::localHotSpotVMIntConstants) " + 1.63 "had its value declared as " + value + " twice. Continuing."); 1.64 + duplicateDefCount++; 1.65 } 1.66 } 1.67 } 1.68 1.69 entryAddr = entryAddr.addOffsetTo(intConstantEntryArrayStride); 1.70 - } while (nameAddr != null); 1.71 + } while (nameAddr != null && duplicateDefCount < MAX_DUPLICATE_DEFINITIONS); 1.72 + 1.73 + if (duplicateDefCount >= MAX_DUPLICATE_DEFINITIONS) { 1.74 + throw new RuntimeException("too many duplicate definitions"); 1.75 + } 1.76 } 1.77 1.78 private void readVMLongConstants() { 1.79 @@ -519,6 +544,10 @@ 1.80 longConstantEntryValueOffset = getLongValueFromProcess("gHotSpotVMLongConstantEntryValueOffset"); 1.81 longConstantEntryArrayStride = getLongValueFromProcess("gHotSpotVMLongConstantEntryArrayStride"); 1.82 1.83 + if (longConstantEntryArrayStride == 0L) { 1.84 + throw new RuntimeException("zero stride: cannot read types."); 1.85 + } 1.86 + 1.87 // Fetch the address of the VMLongConstantEntry* 1.88 Address entryAddr = lookupInProcess("gHotSpotVMLongConstants"); 1.89 // Dereference this once to get the pointer to the first VMLongConstantEntry 1.90 @@ -548,12 +577,17 @@ 1.91 } else { 1.92 System.err.println("Warning: the long constant \"" + name + "\" (declared in the remote VM in VMStructs::localHotSpotVMLongConstants) " + 1.93 "had its value declared as " + value + " twice. Continuing."); 1.94 + duplicateDefCount++; 1.95 } 1.96 } 1.97 } 1.98 1.99 entryAddr = entryAddr.addOffsetTo(longConstantEntryArrayStride); 1.100 - } while (nameAddr != null); 1.101 + } while (nameAddr != null && duplicateDefCount < MAX_DUPLICATE_DEFINITIONS); 1.102 + 1.103 + if (duplicateDefCount >= MAX_DUPLICATE_DEFINITIONS) { 1.104 + throw new RuntimeException("too many duplicate definitions."); 1.105 + } 1.106 } 1.107 1.108 private BasicType lookupOrFail(String typeName) { 1.109 @@ -740,9 +774,10 @@ 1.110 } 1.111 1.112 if (!typeNameIsPointerType(typeName)) { 1.113 - System.err.println("Warning: the type \"" + typeName + "\" (declared in the remote VM in VMStructs::localHotSpotVMTypes) " + 1.114 - "had its size declared as " + size + " twice. Continuing."); 1.115 - } 1.116 + System.err.println("Warning: the type \"" + typeName + "\" (declared in the remote VM in VMStructs::localHotSpotVMTypes) " + 1.117 + "had its size declared as " + size + " twice. Continuing."); 1.118 + duplicateDefCount++; 1.119 + } 1.120 } 1.121 1.122 }