JNI未知类型<unknown>的例外......这是怎么发生的?

Ogr*_*m33 5 java java-native-interface exception-handling

我有一些调用C++代码的Java代码,C++代码转向并调用Java,所有这些都是通过JNI实现的.我们得到了notorius"hs_err_pidXXXX.log",奇怪的是,当我们调用JNIEnv_::GetMethodID(myJniEnv->GetObjectClass(anException), "printStackTrace", "()V")当前挂起的异常时,它正在发生!所以我们补充说:

if ((javaException = getJniEnv()->ExceptionOccurred()) != NULL)
{
   jniEnv->ExceptionDescribe();
   .... <other exception handling code> ...
}
Run Code Online (Sandbox Code Playgroud)

...每次我们打电话给JNI以试图发现正在发生的异常.ExceptionDescribe()的结果是:

Uncaught exception of type <unknown>
Run Code Online (Sandbox Code Playgroud)

这是怎么发生的?anException上面的值直接来自JNI调用anException = myJniEnv->ExceptionOccurred(),它应该产生一个throwable,对吧?我想,我应该能够在没有JNI崩溃的情况下在throwable上打印堆栈跟踪.以前有人遇到这样的事吗?

bla*_*nda 7

这听起来像是内存损坏问题,可能是因为已经清理过的Java本地引用.尝试将以下部分或全部选项添加到Java命令行(或C/C++中的JVM创建参数):

  -verbose:jni
  -verbose:gc
  -Xcheck:jni
Run Code Online (Sandbox Code Playgroud)

可能最有趣的是-Xcheck:jni(参见命令行文档).这将添加一系列检查,例如使用已经删除的本地引用,并在检测到错误时抛出异常,而不是在内存已损坏时程序中的更多内容.一旦在错误的原始源处获得java异常,就应该更容易使用调试器(如gdb来查找C++崩溃位置)或java堆栈跟踪以找到错误发生的确切位置并希望精确定位导致问题的对象.

我从我们的常驻JNI战士那里学到了这一点;)

  • 优秀!在将这些选项添加到我们的JVM调用之后,应用程序开始快速死亡,除了"本机方法中的致命错误:错误的全局或本地引用传递给JNI",我们能够相当快地跟踪到本地JNI引用是(很可能)被释放并再次被调用(26次!),然后最终崩溃<unknown>异常.<unknown>例外是一只红鲱鱼. (2认同)
  • 仅供参考,命令行文档可以在这里找到:http://download.oracle.com/javase/6/docs/technotes/tools/windows/java.html (2认同)