Java JNI - EXCEPTION_ACCESS_VIOLATION while returning jintArray
-
17-06-2021 - |
Question
A really weird thing happens in this code
JNIEXPORT jintArray JNICALL Java_jsdr_SdrLibrary_getTunerGains
(JNIEnv * env, jclass obj, jlong pointer) {
rtlsdr_dev_t * dev;
int * gains;
jintArray ji;
jint * buff;
int i;
int size;
dev = (rtlsdr_dev_t *) pointer;
size = rtlsdr_get_tuner_gains(dev, gains);
if (size <= 0)
.. throws an error, irrelevant code ..
buff = (jint *) malloc(size * sizeof(jint));
for (i = 0; i < size; i++) buff[i] = gains[i];
ji = (*env)->NewIntArray(env, size);
(*env)->SetIntArrayRegion(env, ji, 0, size, buff);
return ji;
}
The method actually returns a result that I can handle in Java with
System.out.println(printArray(SdrLibrary.getTunerGains(pointer)));
where printArray is just a simple
public static String printArray(int[] arr) {
String buff = "["+arr[0];
for (int i = 1; i < arr.length; i++) buff+=", "+arr[i];
return buff+"]";
}
The output is the following
[-10, 15, 40, 65, 90, 115, 140, 165, 190, 215, 240, 290, 340, 420, 430, 450, 470, 490]
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d86c2ff, pid=7160, tid=5880
#
# JRE version: 6.0_31-b05
# Java VM: Java HotSpot(TM) Client VM (20.6-b01 mixed mode, sharing windows-x86 )
# Problematic frame:
# V [jvm.dll+0x7c2ff]
#
# An error report file with more information is saved as:
# C:\Users\Marto\workspace\JSDR\hs_err_pid7160.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
As you can see it returns a result but immediately after that the JM crashes and no further lines get executed. I would definitely appreciate any help! Thank you!
EDIT: If I remove the call to rtlsdr_get_tuner_gains and instead initialize the gains array manually, no error is observed. Since this method is inside a dll, can I prevent it somehow from crashing the JNI?
Solution
I discovered the source of the error. It turns out that the original library does not allocate the buffer that is being passed to it resulting in overwriting memory which is not held by the JNI (thanks to QuantumMechanic to giving me the simple idea to actually look at the source of the library).
The solution was simple enough. Change this
int * gains;
to this
int gains[30];