(* vm) - > GetEnv仅在HTC设备上发生段错误

时间:2011-11-10 13:04:34

标签: android segmentation-fault java-native-interface

我目前正在开发一个在本机环境中具有多个线程的更大项目。因此,我需要调用(* vm) - > GetEnv来接收本机线程的当前活动JNIEnv。线程在创建时附加,但我在调用GetEnv:

的方法中添加了故障转移
void get_jni_env(void **e) {
    JNIEnv *env = malloc(sizeof(JNIEnv *));

    if((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_4) != JNI_OK) {
        __android_log_write(ANDROID_LOG_ERROR, "Call to GetEnv from a unattached native thread. Trying to attach thread.");
        if((*vm)->AttachCurrentThread(vm, &env, NULL) != JNI_OK) {
            __android_log_write(ANDROID_LOG_ERROR, "Failed to receive any jni environment. Crashing soon");
        }
    }

    *e = env;
}

当你走过时,你会看到对(* vm) - > GetEnv段错误的调用:

jni_get_long (ctx=0x40525080, key=0x804215e0 "hm") at jni/jni.c:50
50      GET_JNI_ENV(&env);
(gdb) s
get_jni_env (e=0xbec603e8) at jni/../../../../core/android/util.c:159
159     if((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_4) != JNI_OK) {
(gdb) n
156 void get_jni_env(void **e) {
(gdb) 
157     JNIEnv *env = malloc(sizeof(JNIEnv *));
(gdb) 
159     if((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_4) != JNI_OK) {
(gdb) 

Program received signal SIGSEGV, Segmentation fault.
0xaca43510 in ?? ()  ← this is somewhere on the heap

相同的代码在三星和索尼爱立信设备以及仿真器中完美运行。对于这个特殊错误,我有点想法。我还测试了一个带有CyanogenMod 7.1的HTC设备,它应该与AOSP android非常相似,甚至在同一点崩溃。

2 个答案:

答案 0 :(得分:1)

无法理解,为什么要对你的JNIEnv变量进行mallocate? Android为你做到了。无论如何,这是我的代码,它对我的​​HTC Desire非常有用:

JNIEnv *GetJEnv() {
  JNIEnv *res;
  if (jvm->GetEnv((void **)&res,JNI_VERSION_1_6)==JNI_EDETACHED)
    jvm->AttachCurrentThread(&res,NULL);
  return res;
}

答案 1 :(得分:0)

JNIEnv *env = malloc(sizeof(JNIEnv *));

错误

它分配可以将指针保存到JNIEnv对象的内存,而不是JNIEnv对象本身的内存量。

应该是

JNIEnv *env = malloc(sizeof(JNIEnv));

甚至更好:

JNIEnv *env = malloc(sizeof( *env ));

"工作得非常好"在其他平台上并不意味着它是正确的。