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:
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?
Ok, so here's how I approached the problem I mentioned above. Somewhat tedious, but, given enough time and effort, it eventually paid off.
std::string getClassInfo(JNIEnv* env, jclass aJavaClass)
that gets the MethodID for "toString" on a class, calls that method, and returns the result as a std::string. That told me weather an object was what I thought it was or not.Be aware that on Linux, the JVM itself uses SEGV signals to indicate that the garbage collector should run. I use "handle SIGSEGV pass noprint nostop" in gdb to let the JVM deal with those things.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With