Fix crash on error paths from GenericJNI trampoline.
Test: Added a regression test to 178-app-image-native-method
Test: testrunner.py --host --optimizing -t 178-app-image-native-method
Bug: 181736463
Change-Id: Ib98d6d58ce1fb8287c32f88fda0f83b7e21ef42d
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 4c67bb9..bc5a10d 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -2114,7 +2114,6 @@
Handle<mirror::Class> h_class(hs.NewHandle(declaring_class));
if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
DCHECK(Thread::Current()->IsExceptionPending()) << called->PrettyMethod();
- self->PopHandleScope();
return nullptr; // Report error.
}
}
@@ -2130,7 +2129,6 @@
jobject lock = GetGenericJniSynchronizationObject(self, called);
cookie = JniMethodStartSynchronized(lock, self);
if (self->IsExceptionPending()) {
- self->PopHandleScope();
return nullptr; // Report error.
}
} else {
diff --git a/test/178-app-image-native-method/src/Main.java b/test/178-app-image-native-method/src/Main.java
index a9c6f0a..e6c76ff 100644
--- a/test/178-app-image-native-method/src/Main.java
+++ b/test/178-app-image-native-method/src/Main.java
@@ -51,6 +51,8 @@
$noinline$opt$testMissingCritical();
$noinline$opt$testCriticalSignatures();
+ $noinline$regressionTestB181736463();
+
new CriticalClinitCheck();
sTestCriticalClinitCheckOtherThread.join();
}
@@ -369,6 +371,15 @@
254));
}
+ static void $noinline$regressionTestB181736463() {
+ // Regression test for bug 181736463 (GenericJNI crashing when class initializer throws).
+ try {
+ BadClassB181736463.nativeMethodVoid();
+ throw new Error("Unreachable");
+ } catch (B181736463Error expected) {
+ }
+ }
+
static void initializingCriticalClinitCheck() {
// Called from CriticalClinitCheck.<clinit>().
// Test @CriticalNative calls on the initializing thread.
@@ -823,3 +834,17 @@
Main.initializingCriticalClinitCheck();
}
}
+
+class B181736463Error extends Error {
+}
+
+class BadClassB181736463 {
+ static {
+ // Deliberately throw from class initializer.
+ if (true) {
+ throw new B181736463Error();
+ }
+ }
+
+ public static native int nativeMethodVoid();
+}