title: JNI reporting Invalid indirect reference on GetByteArrayElements in Android
body: <p>I have an issue.  I'm calling a test function that gets a number of bytes from a Java import function and then returns that data as an array of shorts.  At the moment I'm getting a problem that the program crashes with indirect reference.  My code is this:</p>
  
  <pre><code>#define AR_LEN  8
  JNIEXPORT jshortArray JNICALL Java_com_example_datafeed_DataFeed_decode
      (JNIEnv *env, jobject obj) {
      int out_size = 0;
      int i, frame_count;
      short  *data;          /* data stream               */
      int shutdown = 1;
      jbyte *temp;
      short data_btes = AR_LEN *2;
      jshortArray j_out_data;
  
     // This gets the java class references
      jclass cls = (*env)-&gt;FindClass(env, "com/example/datafeed/DataFeed");
      jmethodID getbytes = (*env)-&gt;GetMethodID(env, cls, "getBytes", "(I)[B");
      jmethodID outputMethod = (*env)-&gt;GetMethodID(env, cls, "playData", "([S)V");
     // Set up a return array
      j_out_data = (*env)-&gt;NewShortArray(env, AR_LEN);
      data = malloc(AR_LEN * 2 + 2);
      while(shutdown != 0) {
          __android_log_print(ANDROID_LOG_ERROR, "Native", "Calling Method %d", data_btes);
          // Call the java method to return byte array
          jbyteArray getbytes_ret = (*env)-&gt;CallObjectMethod(env, obj, getbytes, data_btes);
          // check for returned data
          __android_log_print(ANDROID_LOG_ERROR, "Native", "Returned %p %d", temp, getbytes_ret);
  
         //Get the array elements.  This line seems to crash
          temp = (*env)-&gt;GetByteArrayElements(env, getbytes_ret, 0);
  
          __android_log_print(ANDROID_LOG_ERROR, "Native", "Array Set");
          memcpy(data, temp, data_btes);
          __android_log_print(ANDROID_LOG_ERROR, "Native", "Memory Copied");
         // Delete the referece to temp
          (* env)-&gt;DeleteLocalRef(env,temp);
          if(temp == NULL)  {
              shutdown = 0;
          } else {
             // Set the Array of shorts
  
              (*env)-&gt;SetShortArrayRegion(env,j_out_data, 0, AR_LEN, data);
      // Call the return method
           (*env)-&gt;CallObjectMethod(env, obj, outputMethod, j_out_data);
        }
      }
  
      (* env)-&gt;DeleteLocalRef(env,outputMethod);
      (* env)-&gt;DeleteLocalRef(env,j_out_data);
  
   }
  </code></pre>
  
  <p>When I run this code I get this output:</p>
  
  <pre><code>E/Native(18292): Calling Method 16
  D/FEED(18292): getting 16 bytes
  D/FEED(18292): returning 16 bytes  
  E/Native(18292): Returned 
  E/Native(18292): Array Set
  E/Native(18292): Memory Copied
  W/dalvikvm(18292): JNI WARNING: DeleteLocalRef(0x42e06ac0) failed to find entry
  D/OUTPUT(18292): recieved 8 data
  E/Native(18292): Calling Method 0x6ded7770 16
  E/Native(18292): Returned 
  W/dalvikvm(18292): Invalid indirect reference 0x8 in decodeIndirectRef
  I/dalvikvm(18292): "Thread-55890" prio=5 tid=11 RUNNABLE
  I/dalvikvm(18292):   | group="main" sCount=0 dsCount=0 obj=0x42e06520 self=0x75221628
  I/dalvikvm(18292):   | sysTid=18308 nice=0 sched=0/0 cgrp=apps handle=1965187080
  I/dalvikvm(18292):   | state=R schedstat=( 0 0 0 ) utm=0 stm=0 core=0
  I/dalvikvm(18292):   at com.example.datafeed.DataFeed.decode(Native Method)
  I/dalvikvm(18292):   at com.example.datafeed.DataFeed.run(DataFeed.java:68)
  I/dalvikvm(18292):   at java.lang.Thread.run(Thread.java:841)
  E/dalvikvm(18292): VM aborting
  A/libc(18292): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 18308 (Thread-55890)
  I/DEBUG(17442): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
  I/DEBUG(17442): Build fingerprint: 'samsung/jfltexx/jflte:4.3/JSS15J/I9505XXUEMK9:user/release-keys'
  I/DEBUG(17442): Revision: '11'
  I/DEBUG(17442): pid: 18292, tid: 18308, name: Thread-55890  &gt;&gt;&gt; com.example.datafeed &lt;&lt;&lt;
  I/DEBUG(17442): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadd00d
  I/DEBUG(17442):     r0 00000000  r1 00000000  r2 00000000  r3 40b76e50
  I/DEBUG(17442):     r4 deadd00d  r5 0000020c  r6 752342dc  r7 752342e3
  I/DEBUG(17442):     r8 75336b38  r9 75225fb8  sl 75221638  fp 75336b4c
  I/DEBUG(17442):     ip 47844001  sp 753368b8  lr 00000001  pc 40afd970  cpsr 60000030
  01-17 10:57:55.342: I/DEBUG(17442):     d0  0000000000000000  d1  0000000000000000
  01-17 10:57:55.342: I/DEBUG(17442):     d2  0000000000000000  d3  0000000000000000
  01-17 10:57:55.342: I/DEBUG(17442):     d4  0010010200000010  d5  000000010000009c
  01-17 10:57:55.342: I/DEBUG(17442):     d6  ffffffffffffffff  d7  3f8000003f800000
  01-17 10:57:55.342: I/DEBUG(17442):     d8  0000000000000000  d9  0000000000000000
  01-17 10:57:55.342: I/DEBUG(17442):     d10 0000000000000000  d11 0000000000000000
  01-17 10:57:55.342: I/DEBUG(17442):     d12 0000000000000000  d13 0000000000000000
  01-17 10:57:55.342: I/DEBUG(17442):     d14 0000000000000000  d15 0000000000000000
  01-17 10:57:55.342: I/DEBUG(17442):     d16 6e616c2e6176616a  d17 6461657268542e67
  01-17 10:57:55.342: I/DEBUG(17442):     d18 002e006300650073  d19 00700069006c0063
  01-17 10:57:55.342: I/DEBUG(17442):     d20 00720061006f0062  d21 00430049002e0064
  01-17 10:57:55.342: I/DEBUG(17442):     d22 006200700069006c  d23 006400720061006f
  01-17 10:57:55.342: I/DEBUG(17442):     d24 ff00550055005500  d25 ff00550055005500
  01-17 10:57:55.342: I/DEBUG(17442):     d26 ff00550055005500  d27 ff00550055005500
  01-17 10:57:55.342: I/DEBUG(17442):     d28 ff00550055005500  d29 ff00550055005500
  01-17 10:57:55.342: I/DEBUG(17442):     d30 0000000d000d000d  d31 0000000d000d000d
  01-17 10:57:55.352: I/DEBUG(17442):     scr 60000010
  01-17 10:57:55.352: I/DEBUG(17442): backtrace:
  01-17 10:57:55.352: I/DEBUG(17442):     #00  pc 00048970  /system/lib/libdvm.so (dvmAbort+67)
  01-17 10:57:55.352: I/DEBUG(17442):     #01  pc 0004d41b  /system/lib/libdvm.so (dvmDecodeIndirectRef(Thread*, _jobject*)+146)
  01-17 10:57:55.352: I/DEBUG(17442):     #02  pc 0004e141  /system/lib/libdvm.so
  01-17 10:57:55.352: I/DEBUG(17442):     #03  pc 00000cf3  /data/app-lib/com.example.datafeed-1/libdatafeed.so (Java_com_example_datafeed_DataFeed_decode+194)
  01-17 10:57:55.352: I/DEBUG(17442):     #04  pc 0002048c  /system/lib/libdvm.so (dvmPlatformInvoke+112)
  01-17 10:57:55.352: I/DEBUG(17442):     #05  pc 00050ff3  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+398)
  01-17 10:57:55.352: I/DEBUG(17442):     #06  pc 00052ca9  /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+256)
  01-17 10:57:55.352: I/DEBUG(17442):     #07  pc 00029920  /system/lib/libdvm.so
  01-17 10:57:55.352: I/DEBUG(17442):     #08  pc 0002e2ec  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
  01-17 10:57:55.352: I/DEBUG(17442):     #09  pc 00063179  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+292)
  01-17 10:57:55.352: I/DEBUG(17442):     #10  pc 000631a3  /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20)
  01-17 10:57:55.352: I/DEBUG(17442):     #11  pc 00057f03  /system/lib/libdvm.so
  01-17 10:57:55.352: I/DEBUG(17442):     #12  pc 0000cc60  /system/lib/libc.so (__thread_entry+72)
  01-17 10:57:55.352: I/DEBUG(17442):     #13  pc 0000cddc  /system/lib/libc.so (pthread_create+208)
  </code></pre>
  
  <p>I notice that the java method is only being called once, despite CallObjectMethod being called twice (it prints the returned output, despite not printing the debug method from the java code).  Not sure how to solve this, do I have to reset the reference ever time?  If anyone has any suggestions will be much appreciated.  </p>
  
  <p>Edit: Not sure if this will help, but I've added the java code.</p>
  
  <pre><code>public class DataFeed {
      static {
          System.loadLibrary("datafeed");
      }
      private BlockingQueue&lt;Byte&gt; inputQueue;
      public DataFeed () {
          inputQueue=new LinkedBlockingQueue&lt;Byte&gt;();
  }
  public native void decode();
  
  public byte[] getBytes (int bytes)  {
      int curbyte = 0;
      byte[] retbytes = new byte[bytes];
      Log.d("FEED", "getting " + bytes + " bytes");
      while(curbyte &lt; bytes) {
          try {
              retbytes[curbyte] = inputQueue.take();
  
          } catch (InterruptedException e) {
              e.printStackTrace();
              return null;
          }
          curbyte ++;
      }
      Log.d("FEED", "returning " + retbytes.length + " bytes  ");
      return retbytes;
  
  
      }
  
      public void playData(short[] outdata) {
          Log.d("OUTPUT", "recieved " + outdata.length + " data");
      }
  }
  </code></pre>