// In case we already run in tracing mode, disable it. if (VMDebug.getMethodTracingMode() != 0) {
VMDebug.stopMethodTracing();
}
File tempFile = createTempFile();
// Start method tracing so that native methods get the generic JNI stub.
VMDebug.startMethodTracing(tempFile.getPath(), 0, 0, false, 0);
// We need the caller of `throwsException` to be nterp or compiled, because the clinit check is // executed within the generic JNI stub. The switch interpreter does a clinit check before the // invoke, and that doesn't trigger the bug.
Main.ensureJitCompiled(Runner.class, "run");
// We want the `Test` class to be loaded after `startMethodTracing`. So we call it through // `Runner` to avoid the verification of the `Main` class preload `Test`.
Runner.run();
}
class Runner { publicstaticvoid run() { try { // Will call through the generic JNI stub and when returning from the native code will need // to walk the stack to throw the exception. We used to crash when walking the stack because // we did not expect to have a generic JNI PC with an entrypoint from a shared boot image // JNI stub.
Test.throwsException();
} catch (Test e) { if (!Test.ranInitializer) { thrownew Error("Expected Test.ranInitializer to be true");
} return;
} thrownew Error("Expected exception");
}
}
class Test extends Exception { static {
ranInitializer = true; // Will update the entrypoint of `Test.throwsException` to point to a JNI stub from the boot // image.
VMDebug.stopMethodTracing();
}
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.