Tôi đang viết một ứng dụng Android xử lý ảnh từ nguồn gốc C (NDK r10d). Mã này hoạt động tốt cho đến khi giới thiệu ART gần đây nghiêm ngặt hơn với JNI. Vì vậy, mã hoạt động tốt với Dalvik (ví dụ: trên các thiết bị trước Lolipop) nhưng ii tạo một SIGENV trên các điện thoại mới nhất.
bây giờ tôi nhận được lỗi:Lỗi Android (ART) với lỗi JNI DETECTED ERROR IN APPLICATION: jarray là bảng tham chiếu gián tiếp gián tiếp hoặc tham chiếu không hợp lệ
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)
Mã tôi chạy trong Java là:
/**
* 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);
Các mã nguồn gốc tương ứng là:
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;
}
Dường như GetByteArrayElements là nguồn gốc của lỗi, nhưng tham chiếu JNIEnv và jbyteArray được cung cấp bởi Android và tôi không lưu trữ hoặc sửa đổi chúng. Kể từ khi mảng đệm luôn được phân bổ trong cùng một chuỗi Java, tôi không thấy nó có thể bị hỏng ... Tôi khá bối rối :)
Điều gì có thể là nguồn gốc của vấn đề này?
Heap có quá nhỏ không? Hay nó là một vấn đề ART (tôi thực sự nghi ngờ nó mặc dù ...)?
Cảm ơn sự giúp đỡ của bạn!
Vui lòng kiểm tra kích thước được trả về bởi 'nativeGetDataSize()' và 'env-> GetArrayLength()' thực sự trả về giống nhau. Không yêu cầu giải quyết vấn đề này, tôi vẫn sẽ đề xuất phân bổ mảng trong mã gốc, loại bỏ một nửa số cuộc gọi JNI với tất cả các phí liên quan. –
Thật không may, điều này xác nhận rằng tham chiếu của jbyteArray bị hỏng: cuộc gọi đến 'env-> GetArrayLength()' hiện đang trigerring cùng một lỗi. Tôi sẽ thử ngày mai phân bổ từ bên trong mã gốc. Cảm ơn! – Stef
Hoạt động như một sự quyến rũ! cảm ơn! – Stef