Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch exception in Android NDK C++ code

I am trying to catch an error in native C++ code on Android. According to the docs FindClass returns NULL when class name cannot be find. But I got FATAL EXCEPTION: main java.lang.NoClassDefFoundError: fake/class and execution never reaches the if statement.

#include <string.h>
#include <jni.h>

extern "C"
void Java_com_example_MainActivity_testError(JNIEnv *env, jobject) {
    jclass clazz = env->FindClass("fake/class");
    // never gets here
    if (clazz == NULL) {
        return;
    }
}

Also this exception skips the try-catch block and crashes the app. My Java code:

static {
    System.loadLibrary("native-lib");
}

public native void testError();

...
try {
    testError();
} catch (Exception e) {
    // exception never get cought
}

Also I use cppFlags '-fexceptions'. Is there a proper way to catch this exception or recover from it so the app does not crash?

like image 315
kosev Avatar asked Sep 13 '25 10:09

kosev


1 Answers

First, to prevent native code from crashing on FindClass, etc. you have to use this code after every JNI call:

bool checkExc(JNIEnv *env) {
    if (env->ExceptionCheck()) {
        env->ExceptionDescribe(); // writes to logcat
        env->ExceptionClear();
        return true;
    }
    return false;
}

Actually, ExceptionClear() stops the crash. I have found the code on this answer https://stackoverflow.com/a/33777516/2424777

Second, to be sure to catch all crashes from native code, you have to use this try-catch. Credits @Richard Critten Also use it on all native function calls:

static {
    try {
        System.loadLibrary("native-lib");
    } catch (Error | Exception ignore) { }
}

And cppFlags '-fexceptions' has nothing to do it so you can remove it.

like image 93
kosev Avatar answered Sep 14 '25 22:09

kosev