2011-11-10 9 views
1

現在、ネイティブ環境で複数のスレッドを持つより大きなプロジェクトで作業しています。したがって、ネイティブスレッドの現在アクティブなJNIEnvを受け取るには、(* vm) - > GetEnvを呼び出す必要があります。スレッドは、作成時に添付されているが、私はのgetenvを呼び出す方法でフェイルオーバを追加しました:(* vm) - > HTCデバイスでのみGetEnv segfaults

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 

同じコードは、SamsungとSony Ericssonデバイス、およびエミュレータで完全に正常に動作します。私はこの特定のエラーのアイデアから幾分外れています。私はCyanogenMod 7.1のHTCデバイスもテストしました。これはAOSPのアンドロイドにかなり似ていて、同じ場所でクラッシュします。

答えて

1

あなたのJNIEnv変数をなぜ割り振るのですか? Androidはあなたのためにそれを行います。とにかく、ここに私のHTCの欲望に大きく働く私のコードは、次のとおりです。

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

これは無視できます。私はそれがスタック上のいくつかの不良アドレスによって引き起こされたかどうかを調べ、malloc()でアドレスをヒープに移動しました。しかし、この問題はどこかにあるようです。あなたのバージョンはどちらも動作しません、私はすでにそれを事前に試してみました。しかし、答えに時間を割いてくれてありがとう。 – lhw

0

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

間違っです。

JNIEnvオブジェクトではなく、JNIEnvオブジェクト自体の量メモリへポインタを保持することができるメモリを割り当てます。

それは

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

またはさらに良くする必要があります:

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

他のプラットフォーム上で "完全に罰金作品" それが正しいだという意味ではありません。

関連する問題