Ejemplo n.º 1
0
/*
 * Class:     sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
 * Method:    readBytesFromProcess0
 * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;
 */
JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_readBytesFromProcess0
  (JNIEnv *env, jobject this_obj, jlong address, jlong numBytes) {

  jbyteArray array = env->NewByteArray(numBytes);
  CHECK_EXCEPTION_(0);
  jboolean isCopy;
  jbyte* bufPtr = env->GetByteArrayElements(array, &isCopy);
  CHECK_EXCEPTION_(0);
 
  jlong ps_prochandle_ptr = env->GetLongField(this_obj, ps_prochandle_ptr_ID);
  ps_err_e ret = ps_pread((struct ps_prochandle*) ps_prochandle_ptr, 
                       (psaddr_t)address, bufPtr, (size_t)numBytes); 

  if(ret != PS_OK) {

     // Part of workaround for 4705086.

     jint  libjvm_fd = env->GetIntField(this_obj, libjvm_fd_ID);
     jlong libjvm_text_start = env->GetLongField(this_obj, libjvm_text_start_ID);
     jlong libjvm_text_size = env->GetLongField(this_obj, libjvm_text_size_ID);

     // get the file descriptor for libjvm.so
     jlong offset = address - libjvm_text_start;

     // do bounds check to verify that the given address is in
     // libjvm text
     if (offset >= libjvm_text_size || offset < 0) {
        env->ReleaseByteArrayElements(array, bufPtr, JNI_COMMIT);
        // the address given is not in libjvm[_g].so text
        return jbyteArray(0);
     }

     ssize_t bytes_read = pread(libjvm_fd, bufPtr, numBytes, (off_t)offset); 
     if (bytes_read != (ssize_t) numBytes) {
         env->ReleaseByteArrayElements(array, bufPtr, JNI_COMMIT);
         return jbyteArray(0);
     }
  }

  env->ReleaseByteArrayElements(array, bufPtr, JNI_COMMIT);
  return array;
}
Ejemplo n.º 2
0
/*
 * Class:       sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
 * Method:      readBytesFromProcess0
 * Signature:   (JJ)[B
 * Description: read bytes from debuggee process/core
 */
JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_readBytesFromProcess0
  (JNIEnv *env, jobject this_obj, jlong address, jlong numBytes) {

  jbyteArray array = env->NewByteArray(numBytes);
  CHECK_EXCEPTION_(0);
  jboolean isCopy;
  jbyte* bufPtr = env->GetByteArrayElements(array, &isCopy);
  CHECK_EXCEPTION_(0);

  jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
  ps_err_e ret = ps_pread((struct ps_prochandle*) p_ps_prochandle,
                       (psaddr_t)address, bufPtr, (size_t)numBytes);

  if (ret != PS_OK) {
    // part of the class sharing workaround. try shared heap area
    int classes_jsa_fd = env->GetIntField(this_obj, classes_jsa_fd_ID);
    if (classes_jsa_fd != -1 && address != (jlong)0) {
      print_debug("read failed at 0x%lx, attempting shared heap area\n", (long) address);

      struct FileMapHeader* pheader = (struct FileMapHeader*) env->GetLongField(this_obj, p_file_map_header_ID);
      // walk through the shared mappings -- we just have 4 of them.
      // so, linear walking is okay.
      for (int m = 0; m < NUM_SHARED_MAPS; m++) {

        // We can skip the non-read-only maps. These are mapped as MAP_PRIVATE
        // and hence will be read by libproc. Besides, the file copy may be
        // stale because the process might have modified those pages.
        if (pheader->_space[m]._read_only) {
          jlong baseAddress = (jlong) (uintptr_t) pheader->_space[m]._base;
          size_t usedSize = pheader->_space[m]._used;
          if (address >= baseAddress && address < (baseAddress + usedSize)) {
            // the given address falls in this shared heap area
            print_debug("found shared map at 0x%lx\n", (long) baseAddress);


            // If more data is asked than actually mapped from file, we need to zero fill
            // till the end-of-page boundary. But, java array new does that for us. we just
            // need to read as much as data available.

#define MIN2(x, y) (((x) < (y))? (x) : (y))

            jlong diff = address - baseAddress;
            jlong bytesToRead = MIN2(numBytes, usedSize - diff);
            off_t offset = pheader->_space[m]._file_offset  + off_t(diff);
            ssize_t bytesRead = pread(classes_jsa_fd, bufPtr, bytesToRead, offset);
            if (bytesRead != bytesToRead) {
              env->ReleaseByteArrayElements(array, bufPtr, JNI_ABORT);
              print_debug("shared map read failed\n");
              return jbyteArray(0);
            } else {
              print_debug("shared map read succeeded\n");
              env->ReleaseByteArrayElements(array, bufPtr, 0);
              return array;
            }
          } // is in current map
        } // is read only map
      } // for shared maps
    } // classes_jsa_fd != -1
    env->ReleaseByteArrayElements(array, bufPtr, JNI_ABORT);
    return jbyteArray(0);
  } else {
    env->ReleaseByteArrayElements(array, bufPtr, 0);
    return array;
  }
}