0

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?

6
  • 1
    You're passing a pointer disguised as a long? Really? I suspect some code you haven't shown here is corrupting memory. Apart from the fact that you're leaking buff, and you're not checking for errors on JNI calls, there's nothing obviously wrong in the code you have posted. Commented Jun 25, 2012 at 20:16
  • As for the long, I don't have a lot of choice. It needs to be stored somewhere... Do you have any better suggestions? Also, look at the edit, I have added a few observations. As for the leaking of buff, I had a delete(buff) but I thought this might be causing the problem but it isn't. It seems like it's coming from the library. That's quite weird. Commented Jun 25, 2012 at 20:23
  • Your edit makes it sound even more like you have a bug elsewhere. You can prevent it from crashing by fixing the bug. Commented Jun 25, 2012 at 20:29
  • 2
    Post the code to rtlsdr_get_tuner_gains. Commented Jun 25, 2012 at 20:30
  • rtlsdr_get_tuner_gains is from a dll library -> cgit.osmocom.org/cgit/rtl-sdr/tree/src/librtlsdr.c Commented Jun 25, 2012 at 20:35

1 Answer 1

2

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];
Sign up to request clarification or add additional context in comments.

2 Comments

With that signature, how could it? It would have to be int ** to transmit the new value back to the caller. int *& in C++.
Oooh, yeah, this makes sense... Yeah, I'm quite new to c programming so I guess that's why I didn't spot it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.