Android NDK: Java JVM openjdkjvmti :: MethodUtil :: GetMethodName Crash - PullRequest
0 голосов
/ 06 сентября 2018

Я использую Android NDK на Motorola G6 под управлением Android 8.0.

Я использую JNI для периодических обратных вызовов к моему Java-коду в следующих случаях:

if ( data_arg  && g_vm && g_obj ) {
     jint res = (*g_vm)->GetEnv(g_vm, (void**)&g_env, JNI_VERSION_1_6);
     if (res != JNI_OK) {
     res = (*g_vm)->AttachCurrentThread(g_vm, &g_env, NULL);
     if (JNI_OK != res) {
        return NULL;
     }
     jclass interfaceClass = (*g_env)->GetObjectClass(g_env,g_obj);
     if (!interfaceClass) {
        return NULL;
     }
     g_mid = (*g_env)->GetMethodID(g_env,interfaceClass, "readCallback", "(I[B)V");
     if (!g_mid){
        return NULL;
     }
     jbyteArray dataByteArray = (*g_env) -> NewByteArray(g_env,data_arg->len);
     (*g_env)->SetByteArrayRegion(g_env, dataByteArray, 0,data_arg->len,(jbyte*)data_arg->data);
     (*g_env)->CallVoidMethod(g_env, g_obj,(jmethodID)g_mid, (jint)data_arg->len, (jbyteArray)dataByteArray);
     (*g_env)->DeleteLocalRef(g_env,dataByteArray);
     (*g_env)->DeleteLocalRef(g_env,res);
     (*g_env)->DeleteLocalRef(g_env,interfaceClass);
}

Переменные g_vm и g_obj инициализируются, когда приложение запускается со следующими параметрами:

JNIEXPORT jint JNICALL Java_com_abc_register(JNIEnv *env, jobject obj) {
     int returnValueBool = 1;
     (*env)->GetJavaVM(env, &g_vm);
     g_obj = (*env)->NewGlobalRef(env,obj);
     g_env = env;
     g_res = JNI_ERR;
     return (jint)returnValueBool;
}

Класс, который вызывает вышеуказанный метод регистра, является статическим экземпляром.

Обратные вызовы происходят при частоте около 20 Гц. Обратные вызовы вызываются из одного потока, поэтому метод DetachCurrentThread не вызывается. Обычно приложение работает нормально в течение нескольких минут, пока не вылетает.

Сбой приводит к следующей трассировке стека:

* thread #65, name = 'JVMTI Agent thr', stop reason = signal SIGSEGV: invalid address (fault address: 0x765630)
* frame #0: 0x92b8d44e libopenjdkjvmti.so`openjdkjvmti::MethodUtil::GetMethodName(_jvmtiEnv*, _jmethodID*, char**, char**, char**) + 410

Прежде чем происходит сбой, использование памяти и процессора не является чрезмерным, и при этом число потоков не слишком велико. Я не верю, что есть утечка памяти, основанная на представлении профилировщика Android показано здесь

За тонну заранее спасибо!

...