8316778: test hprof lib: invalid array element type from JavaValueArray.elementSize
Reviewed-by: cjplummer, lmesnik, sspitsyn
This commit is contained in:
parent
8ff10a0d35
commit
f7deaf4bef
171
test/lib-test/jdk/test/lib/hprof/HprofTest.java
Normal file
171
test/lib-test/jdk/test/lib/hprof/HprofTest.java
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.ref.Reference;
|
||||
import java.util.Enumeration;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.test.lib.JDKToolLauncher;
|
||||
import jdk.test.lib.apps.LingeredApp;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
import jdk.test.lib.hprof.model.JavaClass;
|
||||
import jdk.test.lib.hprof.model.JavaHeapObject;
|
||||
import jdk.test.lib.hprof.model.JavaObject;
|
||||
import jdk.test.lib.hprof.model.JavaValueArray;
|
||||
import jdk.test.lib.hprof.model.JavaThing;
|
||||
import jdk.test.lib.hprof.model.Snapshot;
|
||||
import jdk.test.lib.hprof.parser.Reader;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8316778
|
||||
* @library /test/lib
|
||||
* @run main HprofTest
|
||||
*/
|
||||
|
||||
class HprofTestTarg extends LingeredApp {
|
||||
// Array of primitive types
|
||||
int[] intArray = new int[2];
|
||||
// String
|
||||
String str = "test_string";
|
||||
|
||||
public static void main(String[] args) {
|
||||
HprofTestTarg testObj = new HprofTestTarg();
|
||||
|
||||
LingeredApp.main(args);
|
||||
|
||||
Reference.reachabilityFence(testObj);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class HprofTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
File dumpFile = new File("Myheapdump.hprof");
|
||||
createDump(dumpFile);
|
||||
test(dumpFile);
|
||||
}
|
||||
|
||||
private static void createDump(File dumpFile) throws Exception {
|
||||
LingeredApp theApp = null;
|
||||
try {
|
||||
theApp = new HprofTestTarg();
|
||||
|
||||
LingeredApp.startApp(theApp);
|
||||
|
||||
//jcmd <pid> GC.heap_dump <file_path>
|
||||
JDKToolLauncher launcher = JDKToolLauncher
|
||||
.createUsingTestJDK("jcmd")
|
||||
.addToolArg(Long.toString(theApp.getPid()))
|
||||
.addToolArg("GC.heap_dump")
|
||||
.addToolArg(dumpFile.getAbsolutePath());
|
||||
Process p = ProcessTools.startProcess("jcmd", new ProcessBuilder(launcher.getCommand()));
|
||||
while (!p.waitFor(5, TimeUnit.SECONDS)) {
|
||||
if (!theApp.getProcess().isAlive()) {
|
||||
log("ERROR: target VM died, killing jcmd...");
|
||||
p.destroyForcibly();
|
||||
throw new Exception("Target VM died");
|
||||
}
|
||||
}
|
||||
|
||||
if (p.exitValue() != 0) {
|
||||
throw new Exception("Jcmd exited with code " + p.exitValue());
|
||||
}
|
||||
} finally {
|
||||
LingeredApp.stopApp(theApp);
|
||||
}
|
||||
}
|
||||
|
||||
private static void test(File dumpFile) throws Exception {
|
||||
Asserts.assertTrue(dumpFile.exists(), "Heap dump file not found.");
|
||||
|
||||
log("Reading " + dumpFile + "...");
|
||||
try (Snapshot snapshot = Reader.readFile(dumpFile.getPath(), true, 0)) {
|
||||
log("Resolving snapshot...");
|
||||
snapshot.resolve(true);
|
||||
log("Snapshot resolved.");
|
||||
|
||||
JavaObject testObj = getTestObject(snapshot);
|
||||
testPrimitiveArray(testObj);
|
||||
testString(testObj);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// verifies JavaValueArray.valueString does not throw
|
||||
// "invalid array element type" exception
|
||||
private static void testPrimitiveArray(JavaObject obj) {
|
||||
JavaHeapObject field = getObjectField(obj, "intArray");
|
||||
Asserts.assertTrue(field instanceof JavaValueArray);
|
||||
log("int array: " + ((JavaValueArray)field).valueString());
|
||||
}
|
||||
|
||||
// verifies JavaObject.toString returns String value
|
||||
private static void testString(JavaObject obj) {
|
||||
JavaHeapObject field = getObjectField(obj, "str");
|
||||
Asserts.assertTrue(field instanceof JavaObject);
|
||||
JavaObject javaObj = (JavaObject)field;
|
||||
Asserts.assertTrue(javaObj.getClazz().isString());
|
||||
log("string: " + javaObj.toString());
|
||||
assert(javaObj.toString().contains(new HprofTestTarg().str));
|
||||
}
|
||||
|
||||
|
||||
private static JavaHeapObject getObjectField(JavaObject obj, String fieldName) {
|
||||
JavaThing thing = obj.getField(fieldName);
|
||||
// only non-primitive types are supported
|
||||
return (JavaHeapObject)thing;
|
||||
}
|
||||
|
||||
// gets test HprofTestTarg
|
||||
private static JavaObject getTestObject(Snapshot snapshot) {
|
||||
String testClassName = HprofTestTarg.class.getName();
|
||||
JavaHeapObject testObject = getObjects(snapshot, testClassName).nextElement();
|
||||
Asserts.assertTrue(testObject instanceof JavaObject);
|
||||
return (JavaObject)testObject;
|
||||
}
|
||||
|
||||
// finds all objects of the specified type
|
||||
private static Enumeration<JavaHeapObject> getObjects(Snapshot snapshot, String className) {
|
||||
log("Looking for '" + className + "' objects...");
|
||||
JavaClass jClass = snapshot.findClass(className);
|
||||
if (jClass == null) {
|
||||
throw new RuntimeException("Class '" + className + "' not found");
|
||||
}
|
||||
int instanceCount = jClass.getInstancesCount(false);
|
||||
if (instanceCount < 1) {
|
||||
throw new RuntimeException("Not instances of '" + className + "' found");
|
||||
}
|
||||
log("Found " + instanceCount + " instance(s).");
|
||||
return jClass.getInstances(false);
|
||||
}
|
||||
|
||||
private static void log(Object s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -190,7 +190,7 @@ public class JavaObject extends JavaLazyReadObject {
|
||||
if (getClazz().isString()) {
|
||||
JavaThing value = getField("value");
|
||||
if (value instanceof JavaValueArray) {
|
||||
return ((JavaValueArray)value).valueString();
|
||||
return ((JavaValueArray)value).valueAsString();
|
||||
} else {
|
||||
return "null";
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -66,17 +66,17 @@ public class JavaValueArray extends JavaLazyReadObject
|
||||
|
||||
private static int elementSize(byte type) {
|
||||
switch (type) {
|
||||
case T_BYTE:
|
||||
case T_BOOLEAN:
|
||||
case 'B':
|
||||
case 'Z':
|
||||
return 1;
|
||||
case T_CHAR:
|
||||
case T_SHORT:
|
||||
case 'C':
|
||||
case 'S':
|
||||
return 2;
|
||||
case T_INT:
|
||||
case T_FLOAT:
|
||||
case 'I':
|
||||
case 'F':
|
||||
return 4;
|
||||
case T_LONG:
|
||||
case T_DOUBLE:
|
||||
case 'J':
|
||||
case 'D':
|
||||
return 8;
|
||||
default:
|
||||
throw new RuntimeException("invalid array element type: " + type);
|
||||
@ -347,4 +347,18 @@ public class JavaValueArray extends JavaLazyReadObject
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
// Tries to represent the value as string (used by JavaObject.toString).
|
||||
public String valueAsString() {
|
||||
if (getElementType() == 'B') {
|
||||
JavaThing[] things = getValue();
|
||||
byte[] bytes = new byte[things.length];
|
||||
for (int i = 0; i < things.length; i++) {
|
||||
bytes[i] = ((JavaByte)things[i]).value;
|
||||
}
|
||||
return new String(bytes);
|
||||
}
|
||||
// fallback
|
||||
return valueString();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user