Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 176e3e29 authored by Andreas Gampe's avatar Andreas Gampe
Browse files

Binder: Change reaction to Error

Instead of aborting immediately with a native error, try to call
Thread.dispatchUncaughtException to trigger a Java-side abort.
Only fall back to the old strategy if this fails.

(cherry picked from commit 1cd76f5c)

Bug: 64689630
Test: m
Test: manual test
Merged-In: If07a04d3769f3b9181c4736220333df9a2871a16
Change-Id: If07a04d3769f3b9181c4736220333df9a2871a16
parent 03c6030c
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -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;
}