I have some Java code which invokes C++ code, and the C++ code turns around and calls Java, all via JNI. We were getting the notorius "hs_err_pidXXXX.log", which, strangely enough, was occurring when we invoked JNIEnv_::GetMethodID(myJniEnv->GetObjectClass(anException), "printStackTrace", "()V")
on the currently pending exception! So we added:
if ((javaException = getJniEnv()->ExceptionOccurred()) != NULL)
{
jniEnv->ExceptionDescribe();
.... <other exception handling code> ...
}
...after each time we call JNI to try and uncover what exception was occurring. The result of ExceptionDescribe() was:
Uncaught exception of type <unknown>
How does this happen? The anException
value above came straight from a JNI call to anException = myJniEnv->ExceptionOccurred()
, wich should yield a throwable, right? I should be able to print a stack trace on a throwable without JNI crashing, I would think. Anyone ever run across something like this before?
This sounds like a memory corruption issue, possibly because of Java local references which have already been cleaned up. Try adding some or all of the following options to your Java command line (or JVM creation arguments in C/C++):
-verbose:jni
-verbose:gc
-Xcheck:jni
Probably the most interesting of these is –Xcheck:jni (See the Command-line docs). This will add a bunch of checks for things like using already-deleted local references, and throw an exception at the point the error is detected, instead of much further down in your program when the memory has already been corrupted. Once you get a java exception at the original source of the error, it should be much easier to use a debugger (like gdb for finding the C++ crash location) or the java stack trace to find exactly where the error happens and hopefully pinpoint the exact object that’s causing the issue.
I learned this from our resident JNI Warrior at work ;)
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