首页  编辑  

Android安卓下JNI调用返回空字符串异常崩溃的一种情况

Tags: /Android/   Date Created:
在安卓下开发,如果NDK JNI调用,出现异常崩溃,完全抓不住代码行,编译没有任何错误,代码功能核查没有问题,请考虑是否返回了空字符串并且处理是否正确:
例如下面的错误:
  1. 01-07 14:20:33.395 A/art: art/runtime/check_jni.cc:70] JNI DETECTED ERROR IN APPLICATION: invalid reference returned from java.lang.String com.xxxx.get_data()
  2. 01-07 14:20:33.396 A/art: art/runtime/check_jni.cc:70]     from com.xxxx.get_data()
  3.     art/runtime/check_jni.cc:70"main" prio=5 tid=1 Runnable
  4.     art/runtime/check_jni.cc:70]   | group="main" sCount=0 dsCount=0 obj=0x748d7000 self=0xf4427400
  5.     art/runtime/check_jni.cc:70]   | sysTid=30805 nice=0 cgrp=default sched=0/0 handle=0xf70abbec
  6.     art/runtime/check_jni.cc:70]   | state=R schedstat=( 819063235 509719918 3292 ) utm=65 stm=16 core=0 HZ=100
  7.     art/runtime/check_jni.cc:70]   | stack=0xff6f1000-0xff6f3000 stackSize=8MB
  8.     art/runtime/check_jni.cc:70]   | held mutexes= "mutator lock"(shared held)
  9. 01-07 14:20:33.397 A/art: art/runtime/check_jni.cc:70]   native: #00 pc 0000505c  /system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, ucontext*)+23)
  10.     art/runtime/check_jni.cc:70]   native: #01 pc 00003739  /system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, ucontext*)+8)
  11.     art/runtime/check_jni.cc:70]   native: #02 pc 0024a6e9  /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+68)
  12.     art/runtime/check_jni.cc:70]   native: #03 pc 0022e7e1  /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+148)
  13.     art/runtime/check_jni.cc:70]   native: #04 pc 000b0d0f  /system/lib/libart.so (art::JniAbort(char const*, char const*)+582)
  14.     art/runtime/check_jni.cc:70]   native: #05 pc 000b144f  /system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+58)
  15.     art/runtime/check_jni.cc:70]   native: #06 pc 0026862b  /system/lib/libart.so (art::CheckReferenceResult(art::mirror::Object*, art::Thread*)+662)
  16.     art/runtime/check_jni.cc:70]   native: #07 pc 00087b4b  /system/lib/libart.so (art::JniMethodEndWithReference(_jobject*, unsigned int, art::Thread*)+62)
  17.     art/runtime/check_jni.cc:70]   native: #08 pc 00000227  /data/dalvik-cache/arm/data@app@com.xxx.yyy-1@base.apk@classes.dex (Java_com_xxx.xxx.xxx_getAeroInfo2__+90)
  18. 01-07 14:20:33.398 A/art: art/runtime/check_jni.cc:70]   at com.xxxx.get_data(Native method)
  19.     art/runtime/check_jni.cc:70]   at com.xxx.MainActivity.GetAero(MainActivity.java:1026)
  20.     art/runtime/check_jni.cc:70]   at com.xxx.MainActivity.GetData(MainActivity.java:962)
  21.     art/runtime/check_jni.cc:70]   at com.xxx.MainActivity$5$1.run(MainActivity.java:503)
  22.     art/runtime/check_jni.cc:70]   at android.os.Handler.handleCallback(Handler.java:815)
  23.     art/runtime/check_jni.cc:70]   at android.os.Handler.dispatchMessage(Handler.java:104)
  24.     art/runtime/check_jni.cc:70]   at android.os.Looper.loop(Looper.java:194)
  25.     art/runtime/check_jni.cc:70]   at android.app.ActivityThread.main(ActivityThread.java:5643)
  26. 01-07 14:20:33.399 A/art: art/runtime/check_jni.cc:70]   at java.lang.reflect.Method.invoke!(Native method)
  27.     art/runtime/check_jni.cc:70]   at java.lang.reflect.Method.invoke(Method.java:372)
  28.     art/runtime/check_jni.cc:70]   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
  29.     art/runtime/check_jni.cc:70]   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
  30.     art/runtime/check_jni.cc:70
  31. 01-07 14:20:39.200 A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 30805 (aaa.app)

上述错误引发的原因在于get_data()代码中,在某些情况下处理返回""字符串的错误:
  1. JNIEXPORT jstring JNICALL Java_com_xxx_yyy_GPIO_getAeroInfo2(JNIEnv *env, jobject jobj) {
  2.     int fd = open("/dev/ttyS1", O_RDWR);
  3.    if (fd <= 0return "";    // -<------------ 引发崩溃的行
  4.     // .......
  5.    return (*env)->NewStringUTF(env, "OK")
  6. }
正确的处理方法是:
  1.  if (fd <= 0return (*env)->NewStringUTF(env, "");