diff options
| -rw-r--r-- | core/jni/android_util_Binder.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 5b0f7768c165..883d4db04890 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -133,6 +133,14 @@ static struct strict_mode_callback_offsets_t jmethodID mCallback; } gStrictModeCallbackOffsets; +static struct thread_dispatch_offsets_t +{ + // Class state. + jclass mClass; + jmethodID mDispatchUncaughtException; + jmethodID mCurrentThread; +} gThreadDispatchOffsets; + // **************************************************************************** // **************************************************************************** // **************************************************************************** @@ -166,6 +174,23 @@ static JNIEnv* javavm_to_jnienv(JavaVM* vm) return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL; } +// Report a java.lang.Error (or subclass). This may terminate the runtime. +static void report_java_lang_error(JNIEnv* env, jthrowable error) +{ + // Try to run the uncaught exception machinery. + jobject thread = env->CallStaticObjectMethod(gThreadDispatchOffsets.mClass, + gThreadDispatchOffsets.mCurrentThread); + if (thread != nullptr) { + env->CallVoidMethod(thread, gThreadDispatchOffsets.mDispatchUncaughtException, + error); + // Should not return here, unless more errors occured. + } + // Some error occurred that meant that either dispatchUncaughtException could not be + // called or that it had an error itself (as this should be unreachable under normal + // conditions). Clear the exception. + env->ExceptionClear(); +} + static void report_exception(JNIEnv* env, jthrowable excep, const char* msg) { env->ExceptionClear(); @@ -192,6 +217,10 @@ static void report_exception(JNIEnv* env, jthrowable excep, const char* msg) } if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) { + // Try to report the error. This should not return under normal circumstances. + report_java_lang_error(env, excep); + // The traditional handling: re-raise and abort. + /* * It's an Error: Reraise the exception and ask the runtime to abort. */ @@ -1337,5 +1366,12 @@ int register_android_os_Binder(JNIEnv* env) gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz, "onBinderStrictModePolicyChange", "(I)V"); + clazz = FindClassOrDie(env, "java/lang/Thread"); + gThreadDispatchOffsets.mClass = MakeGlobalRefOrDie(env, clazz); + gThreadDispatchOffsets.mDispatchUncaughtException = GetMethodIDOrDie(env, clazz, + "dispatchUncaughtException", "(Ljava/lang/Throwable;)V"); + gThreadDispatchOffsets.mCurrentThread = GetStaticMethodIDOrDie(env, clazz, "currentThread", + "()Ljava/lang/Thread;"); + return 0; } |