2015-04-26 15 views
12


Ben yerel C (NDK R10d) bir resim işleyen bir Android uygulaması yazıyorum olduğunu. Kod, JNI ile daha katı olan yeni ART girişine kadar iyi çalışıyordu. Bu yüzden kod Dalvik'le iyi çalışıyor (örneğin Lolipop öncesi cihazlarda) ancak ii en yeni telefonlarda bir SIGENV yaratıyor.Android (ART) çarpışma UYGULAMASI HATA DETECTED: jarray geçersiz yığın dolaylı başvuru tablosu veya geçersiz referans

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/[email protected]@boot.art"] 
04-26 16:18:34.170: E/art(21443): 0xb4875220 imagespace /data/dalvik-cache/arm/[email protected]@boot.art live-bitmap 0[begin=0x6f5ab000,end=0x6ff21f00] 
04-26 16:18:34.170: E/art(21443): 0xb4875220 imagespace /data/dalvik-cache/arm/[email protected]@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/[email protected]@[email protected]@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) 

Java çalıştırmak kodudur:

/** 
    * 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); 

gelen doğal kodudur:

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; 
} 

GetByteArrayElements kaynağı olduğu görünüyor
şimdi hatası alıyorum hata, ama JNIEnv referans ve jbyteArray Android tarafından sağlanmıştır ve bunları saklamıyorum ya da değiştirmiyorum. Tampon dizisi her zaman aynı Java iş parçacığı içinde ayrılmış olduğundan, nasıl bozulduğunu göremiyorum ... Tamamen şaşırıyorum :)
Bu sorunun kaynağı ne olabilir?
Yığın çok mu küçük? Yoksa bir SANAT meselesi mi (gerçekten şüpheliyim ki ...)?
Yardımlarınız için teşekkürler!

+2

Lütfen "nativeGetDataSize()" ile döndürülen boyutu kontrol edin ve 'env-> GetArrayLength()' aslında aynı şeyi döndürür. Bu sorunu çözme iddiasında bulunmamakla birlikte, diziyi yerel kodda tahsis etmeyi öneririm ve JNI çağrılarının yarısını ilgili tüm masraflardan kurtulur. –

+1

Maalesef, bu, jbyteArray öğesinin referansının bozuk olduğunu doğrular: "env-> GetArrayLength()" çağrısı şimdi aynı hatayı tetikler. Yarın yerel kodun içinden tahsis edeceğim. Teşekkürler! – Stef

+1

Bir çekicilik gibi çalışır! Teşekkürler! – Stef

cevap

4

bakın:

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); 


Yerli
JAVA

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; 
} 


Teşekkürler!

1

Geçerli iş parçacığında geçerli yerel yöntem süresi için geçerli olduğu anlamına gelir. Özgün yöntem döndükten sonra nesnenin kendisi devam etse bile, başvuru geçerli değildir.

Bunu jclass/jarray bildiriminde değiştirmeyi deneyin.

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

aşağıdaki kod çalışması yapılmış Alex Cohn 'ın tavsiyelerine uyarak JNI Tips

+0

Üzgünüz, anladığımdan emin değilim. Kavanoz, java parçasında, bir dişte, daha sonra JNI'ye verilir. Bahsettiğim java işlevinin çağrısının eşzamanlı olduğunu belirtmeyi unuttum. Bundan sonra, jarray yalnızca JNI işlevinin yürütülmesi sırasında kullanıldığından, yerel başvuru burada iyi olmalı, değil mi? Yine de, jarray'dan global bir referans oluşturmaya çalıştım ama bu durum durumu değiştirmiyor. – Stef

İlgili konular