如何修复env-> NewObject上的JNI崩溃?

时间:2013-11-10 08:38:24

标签: java c++ c java-native-interface clang

我正在尝试通过JNI(Clang C-API)使用Clang。 经过几次迭代后的一刻,它就停止了创建新对象和崩溃:

  

地图方法    0 args:   create Method instance 0x7fa26ba23c90 0x7fa26ba2a0c0 libclang:crash   在索引源文件中检测到:{'source_filename':   '/Users/asmirnov/Documents/dev/src/clang_jni/mac/test/TestFile.h'
  'command_line_args':[' - c',' - x','c ++'],'unsaved_files':[],
  'options':0,}

代码很简单:

mapMethod(JNIEnv *env, const CXIdxDeclInfo *info) {

    debug("map method");

    int numArgs = clang_Cursor_getNumArguments(info->cursor);
    debug("  %i args:", numArgs);

    debug("create Method instance %p %p", MethodClass, MethodConstructor);
    jobject result = env->NewObject(MethodClass, MethodConstructor);

    debug("create Method  params instance");

找到方法类和构造函数并将其正确地注册为全局(似乎是)并且它可以进行少量迭代:

// method
    MethodClass = (jclass)env->NewGlobalRef(env->FindClass("name/antonsmirnov/clang/dto/index/Method"));
    debug(MethodClass != NULL ? "found MethodClass" : "not found MethodClass");

    MethodConstructor = env->GetMethodID(MethodClass, "<init>", "()V");
    debug(MethodConstructor != NULL ? "found MethodConstructor" : "not found MethodConstructor");

我已经阅读了一些“jni提示和技巧”文章并尝试env->DeleteLocalRef并使本地引用数量过大只是为了尝试,但没有结果:

// magic 
    jint ensureResult = env->EnsureLocalCapacity(1024);
    debug("ensure result %i", ensureResult);

    jint pushResult = env->PushLocalFrame(1024);
    debug("push result %i", pushResult);

Clang正在劫持异常,所以我看不出真正的原因。 问题发生在几次迭代之后,正如我所说,似乎是一些限制超出问题或smth。

有什么问题?

更新:我做了一些研究,我发现如果我之前删除了一些本地变量,我可以获得更多的迭代和一个更多的对象实例。所以它让我觉得它确实使用了16个本地变量而忽略了我的EnsureLocalCapacity调用。它应该在哪里完成?

2 个答案:

答案 0 :(得分:1)

使用EnsureLocalCapacity中的JNI_OnLoad()修复了(在每个本机方法调用中都无效)。

答案 1 :(得分:1)

由于局部变量的数量在jni中受到限制,因此通过NewObject,FindClass创建的

对象需要通过DeleteLocalRef()释放。或者您可以在EnsureLocalCapacity中使用JNI_OnLoad()