当我从本机代码进行JNI回调时,我遇到致命错误:
SIGSEGV ..
Distribution: CentOS release 5.9 (Final), x64
Problematic frame:
V [libjvm.so+0x53499f] JNI_CreateJavaVM+0x20e6f
对此问题很重要的代码:
JavaVM *JVM;
JavaVMAttachArgs args;
jobject jlistener;
jmethodID callback;
JNIEXPORT void JNICALL JNI_FUNC_NAME(open) (JNIEnv *env, jobject obj, jobject config) {
env->GetJavaVM(&JVM);
args.version = JNI_VERSION_1_6;
args.name = "notifyThread";
args.group = NULL;
// ...
}
JNIEXPORT void JNICALL JNI_FUNC_NAME(setListener) (JNIEnv *env, jobject obj, jobject listener) {
jlistener = env->NewGlobalRef(listener);
jclass thisClass = env->GetObjectClass(listener);
jmethodID callback = env->GetMethodID(thisClass, "messageRx", "(B)V");
// if (NULL == notifyMethod) return;
return;
}
void notify(jbyte x) {
JNIEnv *jniEnv;
int envState = JVM->GetEnv((void **)&jniEnv, 0x00010006);
if(envState == (-2)) {
if(JVM->AttachCurrentThread((void**)&jniEnv, &args) != 0)
jniEnv->ThrowNew(exc, "Could not attach current notifying thread.");
}
jniEnv->CallVoidMethod(jlistener, callback, x); // notify
JVM->DetachCurrentThread();
}
如果我注释掉回调行(jniEnv->CallVoidMethod ...
),则没有问题,一切都按预期工作。问题在于实际的回调,甚至更奇怪的是,它可以在一些JVM上运行。
你对此有什么想法吗?
答案 0 :(得分:0)
问题是在创建对侦听器对象的全局引用之前使用了回调(jlistener
未初始化)。