Java JNI - VIOLATION D'ACCÈS AUX EXCEPTIONS lors du retour de jintArray


Une chose vraiment bizarre se produit dans ce 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;
  }

La méthode renvoie en fait un résultat que je peux gérer en Java avec

  System.out.println(printArray(SdrLibrary.getTunerGains(pointer)));

Où printArray est juste un simple

public static String printArray(int[] arr) {
    String buff = "["+arr[0];
    for (int i = 1; i < arr.length; i++) buff+=", "+arr[i];
    return buff+"]";
}

La sortie est la suivante

[-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
#

Comme vous pouvez le voir, il renvoie un résultat mais immédiatement après, le JM se bloque et aucune autre ligne n'est exécutée. J'apprécierais certainement toute aide! Merci!!!!

EDIT: Si je supprime l'appel à rtlsdr_get_tuner_gains et au lieu d'initialiser manuellement le tableau gains, aucune erreur n'est observée. Puisque cette méthode est à l'intérieur d'une dll, puis-je l'empêcher de planter le JNI?

Author: Martin Marinov, 2012-06-26

1 answers

J'ai découvert la source de l'erreur. Il s'avère que la bibliothèque d'origine n'alloue pas le tampon qui lui est transmis, ce qui entraîne l'écrasement de la mémoire qui n'est pas détenue par le JNI (grâce à QuantumMechanic pour me donner l'idée simple de regarder réellement la source de la bibliothèque).

La solution était assez simple. Changer ceci

  int * gains;

À ce

  int gains[30];
 2
Author: Martin Marinov, 2012-06-25 20:45:51