我目前正在本机环境中从事具有多个线程的更大项目。因此,我需要调用(* 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
相同的代码在Samsung和Sony Ericsson设备以及仿真器中都可以正常工作。对于这个特定的错误,我有些想法。我还使用CyanogenMod 7.1测试了HTC设备,该设备应该与AOSP android非常相似,甚至在同一时间崩溃。
最佳答案
不明白,为什么要分配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;
}
关于android - (* vm)-> GetEnv segfaults仅在HTC设备上,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8079917/