I have a Linux C++ application that creates a JVM and makes JNI calls. I am new to JNI, and so far I the only effective way I have found to debug my application during development is by trial and error. What are some techniques to use to debug the infamous "A fatal error has been detected by the Java Runtime Environment" Java VM crashes? How do I know if the problem is my code or a genuine JVM bug?
In general, the obvious thing I know so far are:
- In the code, always check jobject, class, and jmethodID values returned from JNI calls for NULL values before proceeding further.
- Call env->ExceptionCheck() where appropriate to ensure there are no pending exceptions.
Currently, I'm stuck on an issue where the stack trace in the error report file is less than helpful:
# 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. ...
Ok, so I know that it's dying in env->CallObjectMethod(). I checked all the parameters to that in GDB before it dives into the JVM code, but I don't see any obvious NULL or strange values. And of course, all the JNI classes, such as jobject, are unhelpfully opaque, so I can't see if their pointers are pointing to bogus or real data.
Any tips/suggestions/ideas for this kind of problem?