【问题标题】:(*vm)->GetEnv segfaults only on HTC devices(*vm)->GetEnv 段错误仅在 HTC 设备上
【发布时间】:2011-11-10 13:04:34
【问题描述】:

我目前正在做一个更大的项目,在本机环境中使用多个线程。因此,我需要调用 (*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 非常相似,即使在同一点上它也会崩溃。

【问题讨论】:

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


    【解决方案1】:

    不明白,你为什么要分配你的 JNIEnv 变量? Android 为您完成。无论如何,这是我的代码,它在我的 HTC Desire 上非常有用:

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

    【讨论】:

    • 这个可以忽略。我试图找出它是否是由堆栈上的一些错误地址引起的,并使用 malloc() 将地址移动到堆中。但问题似乎出在其他地方。你的版本也不行,我已经试过了。但感谢您抽出宝贵时间回答。
    【解决方案2】:

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

    错了

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

    应该是

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

    甚至更好:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-22
      • 2016-07-16
      • 1970-01-01
      • 2015-11-09
      相关资源
      最近更新 更多