Android (*vm)>;GetEnv segfaults仅适用于HTC设备

Android (*vm)>;GetEnv segfaults仅适用于HTC设备,android,segmentation-fault,java-native-interface,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_

我目前正在一个更大的项目中工作,在本地环境中有多个线程。因此,我需要调用(*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 segfaults的调用:

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非常相似,即使在同一点上它也会崩溃。

我不明白,为什么要错配JNIEnv变量?安卓为你做这件事。无论如何,这是我的代码,它对我的HTC愿望起到了很大的作用:

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

这是错误的

它分配的内存可以容纳指向
JNIEnv
对象的指针,而不是
JNIEnv
对象本身的内存量

应该是

JNIEnv *env = malloc(sizeof(JNIEnv));
或者更好:

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

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

这一点可以忽略。我试图找出它是否是由堆栈上的一些错误地址引起的,并使用malloc()将地址移动到堆中。但问题似乎在其他地方。你的版本也不行,我已经试过了。但是谢谢你花时间回答。