/* * Copyright (c) 2016 Red Hat Inc. * * 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.
*/
@Override publicvoid exceptionThrown(ExceptionEvent event) {
String name = event.exception().referenceType().name();
System.err.println("DEBUG: Exception thrown in debuggee was: " + name);
}
}); /* * Get to the top of entry() * to determine targetClass and mainThread
*/
BreakpointEvent bpe = startTo("OomDebugTestTarget", "entry", "()V");
targetClass = bpe.location().declaringType();
/* * Test case: Object reference as method parameter.
*/
@SuppressWarnings("unused") // called via reflection privatevoid test1() throws Exception {
System.out.println("DEBUG: ------------> Running test1"); try {
Field field = targetClass.fieldByName("fooCls");
ClassType clsType = (ClassType)field.type();
Method constructor = getConstructorForClass(clsType); for (int i = 0; i < 15; i++) {
@SuppressWarnings({ "rawtypes", "unchecked" })
ObjectReference objRef = clsType.newInstance(mainThread,
constructor, new ArrayList(0),
ObjectReference.INVOKE_NONVIRTUAL); if (objRef.isCollected()) {
System.out.println("DEBUG: Object got GC'ed before we can use it. NO-OP."); continue;
}
invoke("testMethod", "(LOomDebugTestTarget$FooCls;)V", objRef);
}
} catch (InvocationException e) {
handleFailure(e);
}
}
/* * Test case: Array reference as method parameter.
*/
@SuppressWarnings("unused") // called via reflection privatevoid test2() throws Exception {
System.out.println("DEBUG: ------------> Running test2"); try {
Field field = targetClass.fieldByName("byteArray");
ArrayType arrType = (ArrayType)field.type();
for (int i = 0; i < 15; i++) {
ArrayReference byteArrayVal = arrType.newInstance(3000000); if (byteArrayVal.isCollected()) {
System.out.println("DEBUG: Object got GC'ed before we can use it. NO-OP."); continue;
}
invoke("testPrimitive", "([B)V", byteArrayVal);
}
} catch (VMOutOfMemoryException e) {
defaultHandleOOMFailure(e);
}
}
/* * Test case: Array reference as return value.
*/
@SuppressWarnings("unused") // called via reflection privatevoid test3() throws Exception {
System.out.println("DEBUG: ------------> Running test3"); try { for (int i = 0; i < 15; i++) {
invoke("testPrimitiveArrRetval", "()[B",
Collections.EMPTY_LIST,
vm().mirrorOfVoid());
}
} catch (InvocationException e) {
handleFailure(e);
}
}
/* * Test case: Object reference as return value.
*/
@SuppressWarnings("unused") // called via reflection privatevoid test4() throws Exception {
System.out.println("DEBUG: ------------> Running test4"); try { for (int i = 0; i < 15; i++) {
invoke("testFooClsRetval", "()LOomDebugTestTarget$FooCls;",
Collections.EMPTY_LIST,
vm().mirrorOfVoid());
}
} catch (InvocationException e) {
handleFailure(e);
}
}
/* * Test case: Constructor
*/
@SuppressWarnings({ "unused", "unchecked", "rawtypes" }) // called via reflection privatevoid test5() throws Exception {
System.out.println("DEBUG: ------------> Running test5"); try {
ClassType type = (ClassType)thisObject.type(); for (int i = 0; i < 15; i++) {
type.newInstance(mainThread,
findMethod(targetClass, "", "()V"), new ArrayList(0),
ObjectReference.INVOKE_NONVIRTUAL);
}
} catch (InvocationException e) {
handleFailure(e);
}
}
private Method getConstructorForClass(ClassType clsType) {
List<Method> methods = clsType.methodsByName(""); if (methods.size() != 1) { thrownew RuntimeException("FAIL. Expected only one, the default, constructor");
} return methods.get(0);
}
privatevoid handleFailure(InvocationException e) { // There is no good way to see the OOME diagnostic message in the target since the // TestScaffold might throw an exception while trying to print the stack trace. I.e // it might get a VMDisconnectedException before the stack trace printing finishes.
System.err.println("FAILURE: InvocationException thrown. Trying to determine cause...");
defaultHandleOOMFailure(e);
}
@SuppressWarnings({ "rawtypes", "unchecked" }) void invoke(String methodName, String methodSig, Value value) throws Exception {
List args = new ArrayList(1);
args.add(value);
invoke(methodName, methodSig, args, value);
}
void invoke(String methodName,
String methodSig,
@SuppressWarnings("rawtypes") List args,
Value value) throws Exception {
Method method = findMethod(targetClass, methodName, methodSig); if ( method == null) {
failure("FAILED: Can't find method: "
+ methodName + " for class = " + targetClass); return;
}
invoke(method, args, value);
}
@SuppressWarnings({ "rawtypes", "unchecked" }) void invoke(Method method, List args, Value value) throws Exception {
thisObject.invokeMethod(mainThread, method, args, 0);
System.out.println("DEBUG: Done invoking method via debugger.");
}
Value fieldValue(String fieldName) {
Field field = targetClass.fieldByName(fieldName); return thisObject.getValue(field);
}
// Determine the pass/fail status on some heuristic and don't fail the // test if < 3 of the total number of tests (currently 5) fail. This also // has the nice side effect that all tests are first attempted and only // all tests ran an overall pass/fail status is determined. privatestaticvoid determineOverallTestStatus(OomDebugTest oomTest) throws IOException, FileNotFoundException {
Properties resultProps = new Properties(); if (!RESULT_FILE.exists()) {
RESULT_FILE.createNewFile();
}
FileInputStream fin = null; try {
fin = new FileInputStream(RESULT_FILE);
resultProps.load(fin);
resultProps.put(oomTest.testMethod,
Integer.toString(oomTest.failedTests));
} finally { if (fin != null) {
fin.close();
}
}
System.out.println("DEBUG: Finished running test '"
+ oomTest.testMethod + "'."); if (LAST_TEST.equals(oomTest.testMethod)) {
System.out.println("DEBUG: Determining overall test status.");
Set<String> actualTestsRun = new HashSet<String>(); int totalTests = ALL_TESTS.length; int failedTests = 0; for (Object key: resultProps.keySet()) {
actualTestsRun.add((String)key);
Object propVal = resultProps.get(key); int value = Integer.parseInt((String)propVal);
failedTests += value;
} if (!ALL_TESTS_SET.equals(actualTestsRun)) {
String errorMsg = "Test failed! Expected to run tests '"
+ ALL_TESTS_SET + "', but only these were run '"
+ actualTestsRun + "'"; thrownew RuntimeException(errorMsg);
} if (failedTests >= 3) {
String errorMsg = "Test failed. Expected < 3 sub-tests to fail "
+ "for a pass. Got " + failedTests
+ " failed tests out of " + totalTests + "."; thrownew RuntimeException(errorMsg);
}
RESULT_FILE.delete();
System.out.println("All " + totalTests + " tests passed.");
} else {
System.out.println("DEBUG: More tests to run. Coninuing.");
FileOutputStream fout = null; try {
fout = new FileOutputStream(RESULT_FILE);
resultProps.store(fout, "Storing results after test "
+ oomTest.testMethod);
} finally { if (fout != null) {
fout.close();
}
}
}
}
publicstaticvoid main(String[] args) throws Exception {
System.setProperty("test.vm.opts", "-Xmx40m"); // Set debuggee VM option
OomDebugTest oomTest = new OomDebugTest(args); try {
oomTest.startTests();
} catch (Throwable e) {
System.out.println("DEBUG: Got exception for test run. " + e);
e.printStackTrace();
oomTest.failure();
}
determineOverallTestStatus(oomTest);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.