3

トピックに直接ジャンプすると、Android L はデフォルトのランタイムとして ART を導入します。基本的にドキュメントビューアであるサンプルアプリケーションがあります。戻るボタン、検索などを含むドキュメント表示コードのほとんどは C で記述されており、Android アプリは JNI インターフェイスを使用しています。Android L 用にビルドするようにコードを更新しましたが、ドキュメントは問題なく開くようです。ただし、[戻る] ボタンを押してドキュメントを閉じると、アプリケーションがクラッシュしたように見え、次のバックトレースが表示されます。

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)

戻るボタンを押すと、ファイル記述子が閉じられるはずのときに CallIntMethodV が呼び出され、最終的に JNI のチェックに失敗します。同じコードが dalvik でも問題なく動作するようです。Android L プレビュー用に JNI コードを正常にコンパイルするには、次のフラグを追加する必要がありました。

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

重要な点は、なぜ art では失敗し始めたのか、dalvik では失敗し始めたのかということです。問題を引き起こしている CallIntMethodV の特定の変更またはコンパイラの厳密さがそのようなエラーを引き起こしていますか? 任意のポインター。必要に応じて追加の詳細を提供させていただきます。

更新: ネイティブ コードが JNI に呼び出す File Close 関数の呼び出しを一時的に無効にしましたが、現在はクラッシュしていないようです。

4

1 に答える 1

1

この問題は、参照に関する問題に関係していると思います-ローカル参照を保持し、別のスレッドなどで使用します。「ネイティブ コードが JNI を呼び出してファイルを閉じる」とはどういう意味かわかりませんが、おそらく、フラッシュ/解放する必要がある構造を JNI から Java に渡しているのでしょう (VM がデータをc 構造を VM に戻します)。

どうやら ART には、Dalvik よりも厳しい jni チェックがいくつかあります。Android サイトにいくつかの詳細があり 、さらにこのページではそれらをデバッグする方法を説明しています。次のように adb を使用して、実際のデバイスでのチェックをオンにします。

adb shell setprop debug.checkjni 1

を別の値に設定するか、デバイスを再起動するとオフになります。

于 2014-10-27T11:45:04.607 に答える