title: Fatal signal 11 when opening files using fopen(), fread() in NDK, but AAsset_read works fine
body: <p>I'm trying to read wav files off the SD card for a audio sampler app I'm building using the NDK and 100% native code. I have a method which iterates through a predefined array containing the sample paths and streams each individually into a data buffer to be later played by OpenSL. </p>
  
  <p>When I loaded the files as assets, using the following method:</p>
  
  <pre><code>int open_asset(AAssetManager* mgr, char* filename, int samp)
  {
  
      assert(NULL != mgr);
      AAsset *asset = AAssetManager_open(mgr, filename, AASSET_MODE_BUFFER);
  
      __android_log_write(ANDROID_LOG_DEBUG, "ASSET", "AAssetManager_open");
  
      if (NULL == asset)
      {
          __android_log_write(ANDROID_LOG_DEBUG, "ASSET", "Asset not found, loading aborted.");
          return JNI_FALSE;
      }
  
      oneshot_samples[samp].buffer_header = (unsigned short*) malloc(HEADER_SIZE);
      AAsset_read(asset, oneshot_samples[samp].buffer_header, HEADER_SIZE);
  
      unsigned short* fmttype;
      unsigned long* databytes;
  
      fmttype = (oneshot_samples[samp].buffer_header + 10);
  
      if (*fmttype != 0x1)
      {
          __android_log_write(ANDROID_LOG_DEBUG, "ASSET", "*fmttype not PCM, loading aborted.");
          return JNI_FALSE;
      }
  
      databytes = (oneshot_samples[samp].buffer_header + 20);
  
      oneshot_samples[samp].data_size = *databytes;
  
      oneshot_samples[samp].buffer_data = (unsigned short*) malloc(*databytes);
      AAsset_seek(asset, HEADER_SIZE, SEEK_SET);
      AAsset_read(asset, oneshot_samples[samp].buffer_data, oneshot_samples[samp].data_size);
  
      __android_log_print(ANDROID_LOG_DEBUG, "ASSET", "*fmttype: %x", *fmttype);
      __android_log_print(ANDROID_LOG_DEBUG, "ASSET", "*databytes: %x", *databytes);
  
      AAsset_close(asset);
  
      __android_log_write(ANDROID_LOG_DEBUG, "ASSET", "AAsset_close(asset)");
  
      return JNI_TRUE;
  }
  </code></pre>
  
  <p>They load without a problem. But for my app, I want the user to be able to read samples from the SD Card too. I changed the file paths to a hard coded location on the SD Card (just for testing), and tried the following method using fopen() and fread():</p>
  
  <pre><code>void open_external_file(char* filepath, int samp)
  {
  
      FILE* fp;
      oneshot_samples[samp].buffer_header = (unsigned short*) malloc(HEADER_SIZE);
  
      __android_log_print(ANDROID_LOG_DEBUG, "open_external_file",
                          "filepath: %s", filepath);
  
      __android_log_print(ANDROID_LOG_DEBUG, "open_external_file",
                          "size of filepath: %d", sizeof filepath);
  
      if ((fp = fopen(filepath, "r")) != NULL)
      {
          __android_log_write(ANDROID_LOG_DEBUG, "open_external_file", "fopen()");
  
          fread(oneshot_samples[samp].buffer_header, sizeof(unsigned short), HEADER_SIZE, fp);
      }
  
      unsigned short* fmttype;
      unsigned long* databytes;
  
      fmttype = (oneshot_samples[samp].buffer_header + 10);
  
      if (*fmttype != 0x1)
      {
          __android_log_write(ANDROID_LOG_DEBUG, "open_external_file", "*fmttype not PCM, loading aborted.");
      }
  
      databytes = (oneshot_samples[samp].buffer_header + 20);
      oneshot_samples[samp].data_size = *databytes;
      oneshot_samples[samp].buffer_data = (unsigned short*) malloc(*databytes);
  
      __android_log_print(ANDROID_LOG_DEBUG, "open_external_file", "*fmttype: %x", *fmttype);
      __android_log_print(ANDROID_LOG_DEBUG, "open_external_file", "*databytes: %x", *databytes);
  
  
      fseek(fp , HEADER_SIZE , SEEK_SET);
      fread(oneshot_samples[samp].buffer_data, sizeof(unsigned short), oneshot_samples[samp].data_size, fp);
  
      fclose(fp);
      __android_log_write(ANDROID_LOG_DEBUG, "open_external_file", "fclose(fp);");
  }
  </code></pre>
  
  <p>Which gives me the dreaded ANR and inevitable crash:</p>
  
  <blockquote>
    <p>06-06 11:42:30.915: I/dalvikvm(7222): threadid=3: reacting to signal 3
    06-06 11:42:30.915: A/libc(7222): Fatal signal 11 (SIGSEGV) at 0x0000000c (code=1)</p>
  </blockquote>
  
  <p>But the weird thing is that it happens seemingly quite randomly - there are 36 odd samples, and sometimes the error appears after just the 4th, and sometimes after 20 or so. After reading this <a href="https://stackoverflow.com/questions/13016057/android-ndk-crash-when-reading-writing-files">thread</a>, it appears it could be a segmentation fault, but I'm at a loss as to how it could be caused - or what the difference between the two methods is. </p>
  
  <p>The values from the file header *fmttype and *databytes are returned 100% correctly every time.</p>
  
  <p>I'm very new to C so it's quite possible I'm doing something obviously wrong - would really appreciate if someone more experienced could shed some light onto what the cause may be.</p>
  
  <p>Update: I switched back using AAsset_read(), and am still getting:</p>
  
  <blockquote>
    <p>06-06 12:33:50.393: I/dalvikvm(9755): threadid=3: reacting to signal 3
    06-06 12:33:50.393: I/dalvikvm(9755): Wrote stack traces to '/data/anr/traces.txt'</p>
  </blockquote>
  
  <p>But the files still load fine every time, and the app does not crash. The total size of my test samples is 48.4 MB for a 512 MB test tablet - could this be causing the issue? Still, if it was I don't see how using AAsset_read() would make a difference.</p>