Java.lang.StackOverflow Erreur pour Android L aperçu en cours d'exécution art


En passant directement au sujet, Android L introduit un ART comme runtime par défaut. J'ai un exemple d'application, essentiellement une visionneuse de documents. La plupart du code de visualisation de documents, y compris les boutons de retour, la recherche,etc. sont écrits en C et l'application Android utilise l'interface JNI. J'ai mis à jour mon code pour le faire construire pour Android L et il semble ouvrir le document très bien. Cependant, lorsque vous appuyez sur le bouton Précédent et fermez le document, l'application semble planter et la trace arrière suivante est vu:

I/DEBUG   ( 1390): Abort message: 'art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: JNI CallIntMethodV called with pending exception 'java.lang.StackOverflowError' thrown in unknown throw location'
I/DEBUG   ( 1390): backtrace:
I/DEBUG   ( 1390):     #00 pc 000390d0  /system/lib/libc.so (tgkill+12)
I/DEBUG   ( 1390):     #01 pc 0001636d  /system/lib/libc.so (pthread_kill+64)
I/DEBUG   ( 1390):     #02 pc 00016e41  /system/lib/libc.so (raise+10)
I/DEBUG   ( 1390):     #03 pc 00013cdd  /system/lib/libc.so (__libc_android_abort+36)
I/DEBUG   ( 1390):     #04 pc 000125ac  /system/lib/libc.so (abort+4)
I/DEBUG   ( 1390):     #05 pc 00230fe9  /system/lib/libart.so (art::Runtime::Abort()+188)
I/DEBUG   ( 1390):     #06 pc 000b9571  /system/lib/libart.so     (art::LogMessage::~LogMessage()+1360)
I/DEBUG   ( 1390):     #07 pc 000c28cd  /system/lib/libart.so (art::JniAbort(char const*, char const*)+1124)
I/DEBUG   ( 1390):     #08 pc 000c2e11  /system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+68)
I/DEBUG   ( 1390):     #09 pc 000c65e9  /system/lib/libart.so (art::ScopedCheck::ScopedCheck(_JNIEnv*, int, char const*)+1952)
I/DEBUG   ( 1390):     #10 pc 000cc8eb  /system/lib/libart.so (art::CheckJNI::CallIntMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+42)

En appuyant sur le bouton Retour, lorsque le descripteur de fichier est censé se fermer, CallIntMethodV est appelé, ce qui échoue finalement dans check JNI. Même code semble fonctionner très bien sur dalvik. J'ai dû ajouter les drapeaux suivants pour que le code JNI soit bien compilé pour Android L preview:

-Wno-switch -Wno-sizeof-pointer-memaccess
LOCAL_DISABLE_FORMAT_STRING_CHECKS := true

Le point clé est pourquoi il commence à échouer maintenant sur l'art, mais pas sur dalvik. Des changements spécifiques dans CallIntMethodV causant le problème ou la rigueur du compilateur provoquent une telle erreur? Tout pointeur. Je serai heureux de fournir des détails supplémentaires si nécessaire.

MISE À JOUR: J'ai temporairement désactivé l'appel à la fonction de fermeture de fichier que le code natif appelle dans JNI et je ne semble pas voir de plantage maintenant.

Author: learn_develop, 2014-10-15

1 answers

Je m'attendrais à ce que ce problème soit lié à un problème de références-garder une référence locale et l'utiliser sur un thread différent ou quelque chose comme ça. Je ne sais pas ce que vous vouliez dire par "appels de code natif dans JNI pour fermer le fichier", mais peut-être que vous transmettez une structure à Java à partir de JNI qui doit être vidée/libérée (de sorte que la machine virtuelle copie les données de la structure c vers la machine virtuelle).

Apparemment, l'ART a quelques contrôles jni plus stricts que Dalvik. Y est quelques détails sur le site Android et plus loin cette page nous dit comment les déboguer. Vous activez la vérification sur un appareil réel en utilisant adb comme ceci:

adb shell setprop debug.checkjni 1

Le réglage sur à une autre valeur ou le redémarrage de l'appareil l'éteindra.

 1
Author: hack_on, 2014-10-27 11:45:04