简体   繁体   English

Android(ART)崩溃,错误JNI DETECTED ERROR IN APPLICATION:jarray是无效的堆栈间接引用表或无效的引用

[英]Android (ART) crash with error JNI DETECTED ERROR IN APPLICATION: jarray is an invalid stack indirect reference table or invalid reference


I am writing an Android application that processes a picture from the native C (NDK r10d). 我正在编写一个处理原生C(NDK r10d)图片的Android应用程序。 The code was working well until recent ART introduction that is more strict with JNI. 该代码运行良好,直到最近的ART介绍对JNI更严格。 So the code is working fine with Dalvik (eg on pre-Lolipop devices) but ii creates a SIGENV on the newest phones. 因此代码与Dalvik一起工作正常(例如在Lolipop之前的设备上),但ii在最新的手机上创建了一个SIGENV。
I now get the error: 我现在得到错误:

04-26 16:18:34.169: E/art(21443): 0xb4a2dd00 SpaceTypeMallocSpace begin=0x12c00000,end=0x12e01000,limit=0x32c00000,size=2MB,capacity=192MB,non_growth_limit_capacity=512MB,name="main rosalloc space"]
04-26 16:18:34.170: E/art(21443): 0xb4ae5640 allocspace main rosalloc space live-bitmap 3[begin=0x12c00000,end=0x32c00000]
04-26 16:18:34.170: E/art(21443): 0xb4ae5660 allocspace main rosalloc space mark-bitmap 3[begin=0x12c00000,end=0x32c00000]
04-26 16:18:34.170: E/art(21443): 0xb4874120 SpaceTypeImageSpace begin=0x6f5ab000,end=0x6ff21e58,size=9MB,name="/data/dalvik-cache/arm/system@framework@boot.art"]
04-26 16:18:34.170: E/art(21443): 0xb4875220 imagespace /data/dalvik-cache/arm/system@framework@boot.art live-bitmap 0[begin=0x6f5ab000,end=0x6ff21f00]
04-26 16:18:34.170: E/art(21443): 0xb4875220 imagespace /data/dalvik-cache/arm/system@framework@boot.art live-bitmap 0[begin=0x6f5ab000,end=0x6ff21f00]
04-26 16:18:34.170: E/art(21443): 0xb49d9dd0 SpaceTypeZygoteSpace begin=0x72f09000,end=0x740c7000,size=17MB,name="Zygote space"]
04-26 16:18:34.170: E/art(21443): 0xb4875440 allocspace zygote / non moving space live-bitmap 0[begin=0x72f09000,end=0x740c7000]
04-26 16:18:34.170: E/art(21443): 0xb4875460 allocspace zygote / non moving space mark-bitmap 0[begin=0x72f09000,end=0x740c7000]
04-26 16:18:34.170: E/art(21443): 0xb4a2dc80 SpaceTypeMallocSpace begin=0x740c7000,end=0x740d6000,limit=0x76f09000,size=60KB,capacity=46MB,non_growth_limit_capacity=46MB,name="non moving space"]
04-26 16:18:34.170: E/art(21443): 0xb4ae5460 allocspace non moving space live-bitmap 4[begin=0x740c7000,end=0x76f09000]
04-26 16:18:34.170: E/art(21443): 0xb4ae53c0 allocspace non moving space mark-bitmap 4[begin=0x740c7000,end=0x76f09000]
04-26 16:18:34.170: E/art(21443): 0xb486d340 large object space:GcRetentionPolicyAlwaysCollect
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: jarray is an invalid stack indirect reference table or invalid reference: 0x740c9268 (0xdead4321)
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]     in call to GetByteArrayElements
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]     from boolean com.googlecode.leptonica.android.Pix.nativeGetData(int, byte[])
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65] "main" prio=5 tid=1 Runnable
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   | group="main" sCount=0 dsCount=0 obj=0x72f09000 self=0xb4827800
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   | sysTid=21443 nice=0 cgrp=default sched=0/0 handle=0xb6f6abec
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   | state=R schedstat=( 427402282 63106827 397 ) utm=28 stm=14 core=3 HZ=100
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   | stack=0xbe5e3000-0xbe5e5000 stackSize=8MB
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   | held mutexes= "mutator lock"(shared held)
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   native: #00 pc 00004e64  /system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, ucontext*)+23)
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   native: #01 pc 00003665  /system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, ucontext*)+8)
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   native: #02 pc 00256429  /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+84)
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   native: #03 pc 00238fe7  /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+158)
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   native: #04 pc 000b191b  /system/lib/libart.so (art::JniAbort(char const*, char const*)+610)
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   native: #05 pc 000b2055  /system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+68)
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   native: #06 pc 000b4455  /system/lib/libart.so (art::ScopedCheck::Check(bool, char const*, ...) (.constprop.129)+480)
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   native: #07 pc 000bee03  /system/lib/libart.so (art::CheckJNI::GetByteArrayElements(_JNIEnv*, _jbyteArray*, unsigned char*)+62)
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   native: #08 pc 00239478  /data/app/com.bill2bin.core.lib.demo-1/lib/arm/liblept.so (_JNIEnv::GetByteArrayElements(_jbyteArray*, unsigned char*)+48)
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   native: #09 pc 0023992c  /data/app/com.bill2bin.core.lib.demo-1/lib/arm/liblept.so (Java_com_googlecode_leptonica_android_Pix_nativeGetData+540)
04-26 16:18:34.263: A/art(21443): art/runtime/check_jni.cc:65]   native: #10 pc 0008d3b5  /data/dalvik-cache/arm/data@app@com.bill2bin.core.lib.demo-1@base.apk@classes.dex (Java_com_googlecode_leptonica_android_Pix_nativeGetData__I_3B+104)
04-26 16:18:34.264: A/art(21443): art/runtime/check_jni.cc:65]   at com.googlecode.leptonica.android.Pix.nativeGetData(Native method)
04-26 16:18:34.264: A/art(21443): art/runtime/check_jni.cc:65]   at com.googlecode.leptonica.android.Pix.getData(Pix.java:94)
04-26 16:18:34.264: A/art(21443): art/runtime/check_jni.cc:65]   at com.bill2bin.core.lib.demo.VideoPipeDebug.testDoJNIDebug(VideoPipeDebug.java:449)
04-26 16:18:34.264: A/art(21443): art/runtime/check_jni.cc:65]   at com.bill2bin.core.lib.demo.CameraActivity.runTest1(CameraActivity.java:133)

The code I run in Java is: 我在Java中运行的代码是:

    /**
     * Return the raw bytes of the native PIX object. You can reconstruct the
     * Pix from this data using createFromPix().
     *
     * @return a copy of this PIX object's raw data
     */
    public byte[] getData() {
        int size = nativeGetDataSize(mNativePix);
        // Size is usually quite big since I work on pictures (1Mo-300Ko)
        byte[] buffer = new byte[size];

        if (!nativeGetData(mNativePix, buffer)) {
            throw new RuntimeException("native getData failed");
        }

        return buffer;
    }

   private static native boolean nativeGetData(long nativePix, byte[] data);

The corresponding native code is: 相应的本机代码是:

jboolean Java_com_googlecode_leptonica_android_Pix_nativeGetData(JNIEnv *env,
        jclass clazz, jlong nativePix, jbyteArray data) {
    PIX *pix = (PIX *) nativePix;

    jbyte *data_buffer = env->GetByteArrayElements(data, NULL);

    l_uint8 *byte_buffer = (l_uint8 *) data_buffer;

     size_t size = 4 * pixGetWpl(pix) * pixGetHeight(pix);
     memcpy(byte_buffer, pixGetData(pix), size);

    env->ReleaseByteArrayElements(data, data_buffer, 0);

    return JNI_TRUE;
}

It seems that GetByteArrayElements is the source of the error, but the JNIEnv reference and the jbyteArray are provided by Android and I do not store nor modify them. 似乎GetByteArrayElements是错误的来源,但JNIEnv引用和jbyteArray是由Android提供的,我不存储也不修改它们。 Since the buffer array is always allocated in the same Java thread, I do not see how it can be corrupted...I am quite puzzled :) 由于缓冲区数组总是在同一个Java线程中分配,我不知道它是如何被破坏的...我很困惑:)
What can be the source of this issue? 这个问题的根源是什么?
Is the heap too small? 堆太小了吗? Or is it an ART issue (I really doubt it though...) ? 或者它是一个ART问题(我真的怀疑它虽然......)?
Thanks for you help ! 谢谢你的帮助!

Following Alex Cohn 's advice I made the following code work: 按照Alex Cohn的建议,我做了以下代码:
JAVA JAVA

public byte[] getData() {
       byte[] buffer = nativeGetData(mNativePix);

        if (buffer == null) {
            throw new RuntimeException("native getData failed");
        }
        return buffer;
  }
  private static native byte[] nativeGetData(long nativePix);


Native 本地人

jbyteArray Java_com_googlecode_leptonica_android_Pix_nativeGetData(
        JNIEnv *env, jclass clazz, jlong nativePix) {
    PIX *pix = (PIX *) nativePix;
    // Get the size
    size_t size = 4 * pixGetWpl(pix) * pixGetHeight(pix);

    jbyteArray  result = env->NewByteArray(size);
    if (result == NULL) {
        LOGE("Cannot allocate JNI Byte Array");

        return NULL; /* out of memory error thrown */
    }
    // move from the Pix to the java structure
    env->SetByteArrayRegion(result, 0, size,(jbyte*)pixGetData(pix));
    return result;
}


Thanks! 谢谢!

This means that it's valid for the duration of the current native method in the current thread. 这意味着它在当前线程中当前本机方法的持续时间内有效。 Even if the object itself continues to live on after the native method returns, the reference is not valid. 即使在本机方法返回后对象本身继续存在,引用也无效。

Try replace this in your jclass/jarray declare. 尝试在jclass / jarray声明中替换它。

jclass localClass = env->FindClass("MyClass");
jclass globalClass = reinterpret_cast<jclass>(env->NewGlobalRef(localClass));

Refer JNI Tips 参考JNI提示

I faced the same problem. 我遇到了同样的问题。 I've written a C function, taking jbyteArray from Java, which was very similar to other already existing and working functions. 我编写了一个C函数,从Java中获取jbyteArray,这与其他现有和正在运行的函数非常相似。 But it crashed violently with horrible messages about accessing deleted long time ago object, accessing record number ~6000 in a table with fifty records etc... I simplified my code to the minimum and noticed that function fails during any attempt to access jbyteArray which has been passed to it. 但它与关于访问已删除的很久以前的对象的可怕消息猛烈地崩溃,在50个记录等的表中访问记录号~6000 ...我将我的代码简化为最小化并注意到在尝试访问jbyteArray期间函数失败被传递给它。 No matter from which thread I made call, no matter how I formed this array. 无论我如何形成这个数组,无论从哪个线程调用。 I checked signature and all that I could. 我检查了签名和我能做的一切。 Function definitely had been called because I could print to log from it. 功能肯定被调用,因为我可以打印从它进行记录。

After I've read this topic I felt doomed :) I definitely couldn't generate data inside of my c-function. 在我读完这个主题之后,我感到注定了:)我绝对无法在我的c函数中生成数据。

What helped to me: I have rewritten this function by hand (no copy-paste) in slightly different part of the source file. 对我有什么帮助:我在源文件的略微不同的部分手工重写了这个功能(没有复制粘贴)。 I also changed its name just in case. 我也改名,以防万一。 Old function's body was deleted. 旧功能的身体被删除了。 And it immediately began to work properly. 它立即开始正常工作。

I don't know what it was, but I faced similar situations in my life a few times in pure C and Perl languages. 我不知道它是什么,但我在生活中遇到过类似的情况,有几次使用纯C语言和Perl语言。

Android Studio. Android Studio。 AOSP 7.1.2 fork. AOSP 7.1.2前叉。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android(ART)崩溃,错误JNI DETECTED ERROR IN APPLICATION:jstring是无效的本地引用 - Android (ART) crash with error JNI DETECTED ERROR IN APPLICATION: jstring is an invalid local reference JNI异常:jarray是无效的全局引用 - JNI Exception: jarray is an invalid global reference 如何调试:应用程序中的JNI检测到错误:使用无效的jobject - How to debug: JNI DETECTED ERROR IN APPLICATION: use of invalid jobject JNI在应用程序中检测到错误:使用已删除的本地引用0x1 - JNI DETECTED ERROR IN APPLICATION: use of deleted local reference 0x1 JNI检测到应用程序错误:使用已删除的弱全局引用 - JNI DETECTED ERROR IN APPLICATION: use of deleted weak global reference JNI 在应用程序中检测到错误:为内部类调用 NewObject 时使用无效的作业 - JNI DETECTED ERROR IN APPLICATION: use of invalid jobject when calling NewObject for innerclass Android JNI 在应用程序中检测到错误:调用 JNI GetMethodID 时出现未决异常 - Android JNI DETECTED ERROR IN APPLICATION: JNI GetMethodID called with pending exception Android:无效的父参考 - Android: invalid parent reference JNI:对 C++ 中的 jarray 的全局引用 - JNI: global reference to a jarray in C++ Spring Data + MongoDB无效参考错误 - Spring Data + MongoDB invalid reference error
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM