我有一个Linux C++应用程序,创建了一个JVM并进行JNI调用。 我对JNI不太熟悉,到目前为止,我发现在开发期间唯一有效的调试应用程序的方法是通过不断试错。 有什么技巧可以用来调试臭名昭著的“Java Runtime Environment发现致命错误”Java虚拟机崩溃? 我如何知道问题是我的代码还是真正的JVM错误?
通常,我所知道的明显事情有:
- 在代码中,在继续进一步之前,始终检查从JNI调用返回的jobject,class和jmethodID值是否为NULL值。 - 在适当的地方调用env->ExceptionCheck()以确保没有未决的异常。
目前,我陷入了一个问题,即错误报告文件中的堆栈跟踪不太有用:
通常,我所知道的明显事情有:
- 在代码中,在继续进一步之前,始终检查从JNI调用返回的jobject,class和jmethodID值是否为NULL值。 - 在适当的地方调用env->ExceptionCheck()以确保没有未决的异常。
目前,我陷入了一个问题,即错误报告文件中的堆栈跟踪不太有用:
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00002b137a99db59, pid=19977, tid=47362673452544
#
# JRE version: 6.0_20-b02
# Java VM: Java HotSpot(TM) 64-Bit Server VM (16.3-b01 mixed mode linux-amd64 )
# Problematic frame:
# V [libjvm.so+0x40fb59]
... <snip> ...
Stack: [0x00007fff1964f000,0x00007fff1974f000], sp=0x00007fff1974e050, free space=3fc0000000000000018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0x40fb59]
V [libjvm.so+0x3ecbe1]
C [libDataFabric.so+0x1bb5b] _Jv_JNIEnv::CallObjectMethod(__jobject*, _jmethodID*, ...)+0xe3
etc. ...
好的,我知道问题出在env->CallObjectMethod()这里。在代码跳进JVM之前,我已经在GDB中检查了所有参数,但是没有看到任何明显的NULL或奇怪的值。当然,所有的JNI类,比如jobject,都是不透明的,所以我无法看到它们的指针是指向虚假数据还是真实数据。
针对这种问题,有什么提示/建议/想法吗?