我有一个本机进程,它通过JNI与编译的scala代码进行通信。在本机进程内部有一个函数,它创建一个Java对象并将其返回给java进程。但有时候这个电话会导致崩溃。
下面是崩溃的JVM堆栈。奇怪的是这是随机发生的。我想不出任何可能导致这种情况的事情。我检查了构造函数的类和方法id。它们都是崩溃时的有效值。
如果有人能对这里可能发生的事情提供任何线索,我将非常感激。
Stack: [0x00007fcd237ff000,0x00007fcd24000000], sp=0x00007fcd23ff9ac0, free space=8170k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0x6ecd44] jni_NewObjectV+0xd4
C [JavaRequestHandler+0x64ff36] _Jv_JNIEnv::NewObject(__jclass*, _jmethodID*, ...)+0x86
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J 621 callback.CallbackHandler.onCall(IILjava/util/ArrayList;IJ)Lcallback/ArgNode; (0 bytes) @ 0x00007fcd3c385653 [0x00007fcd3c385600+0x53]
J 678 C2 callback.CallbackHandler.call(IILscala/collection/Seq;)Lcallback/ArgNode; (45 bytes) @ 0x00007fcd3c3bf2dc [0x00007fcd3c3bee00+0x4dc]
J 642 C1 common.NativeFunctions.GetTime(Ljava/lang/String;)D (28 bytes) @ 0x00007fcd3c3906ec [0x00007fcd3c390280+0x46c]
j CheckTime.main([Ljava/lang/String;)V+8
v ~StubRoutines::call_stub
下面是我保留所有ID的结构。
struct ArgumentNode
{
jclass argNodeID;
jmethodID constructorID;
};
在本机进程的初始化时,我在代码下面调用以加载ID。
bool CallBackHandler::initScalaFields()
{
JNIEnv* env;
bool isAttached = Interpreter::getEnv(&env);
_argnode = new ArgumentNode;
_argnode->argNodeID = env->FindClass("callback/ScalaArgumentNode");
if (_argnode->argNodeID == NULL)
{
logger().error("ERR: Can't load ScalaArgumentNode");
env->ExceptionDescribe();
return false;
}
_argnode->constructorID = env->GetMethodID(_argnode->argNodeID, "<init>", "()V");
if (_argnode->constructorID == NULL)
{
logger().error("ERR: Can't load ScalaArgumentNode Constructor ID");
env->ExceptionDescribe();
return false;
}
return true;
}
此代码导致崩溃
jobject CallbackHandler::functionCallback(JNIEnv* env, jobject obj, jint numberofargs)
{
//This line causes the crash
jobject nwsc_obj = env->NewObject(_argnode->argNodeID, _argnode->constructorID, NULL);
//Some logic
return nwsc_obj;
}