/*
 * Class:     sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
 * Method:    init0
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_init0
  (JNIEnv *env, jclass cls) {
  jclass listClass;

  if (init_libproc(getenv("LIBSAPROC_DEBUG")) != true) {
     THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc");
  }

  // fields we use
  p_ps_prochandle_ID = (*env)->GetFieldID(env, cls, "p_ps_prochandle", "J");
  CHECK_EXCEPTION;
  threadList_ID = (*env)->GetFieldID(env, cls, "threadList", "Ljava/util/List;");
  CHECK_EXCEPTION;
  loadObjectList_ID = (*env)->GetFieldID(env, cls, "loadObjectList", "Ljava/util/List;");
  CHECK_EXCEPTION;

  // methods we use
  createClosestSymbol_ID = (*env)->GetMethodID(env, cls, "createClosestSymbol",
                    "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");
  CHECK_EXCEPTION;
  createLoadObject_ID = (*env)->GetMethodID(env, cls, "createLoadObject",
                    "(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;");
  CHECK_EXCEPTION;
  getThreadForThreadId_ID = (*env)->GetMethodID(env, cls, "getThreadForThreadId",
                                                     "(J)Lsun/jvm/hotspot/debugger/ThreadProxy;");
  CHECK_EXCEPTION;
  // java.util.List method we call
  listClass = (*env)->FindClass(env, "java/util/List");
  CHECK_EXCEPTION;
  listAdd_ID = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z");
  CHECK_EXCEPTION;
}
/*
 * Class:     sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
 * Method:    attach0
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__I
  (JNIEnv *env, jobject this_obj, jint jpid) {

  struct ps_prochandle* ph;
  if ( (ph = Pgrab(jpid)) == NULL) {
    THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
  }
  (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
  fillThreadsAndLoadObjects(env, this_obj, ph);
}
示例#3
0
文件: saproc.cpp 项目: mearvk/JVM
/*
 * Class:       sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
 * Method:      writeBytesToProcess0
 * Signature:   (JJ[B)V
 * Description: write bytes into debugger process
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_writeBytesToProcess0
  (JNIEnv *env, jobject this_obj, jlong address, jlong numBytes, jbyteArray data) {
  jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
  jboolean isCopy;
  jbyte* ptr = env->GetByteArrayElements(data, &isCopy);
  CHECK_EXCEPTION;

  if (ps_pwrite((struct ps_prochandle*) p_ps_prochandle, address, ptr, numBytes) != PS_OK) {
     env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
     THROW_NEW_DEBUGGER_EXCEPTION("Process write failed!");
  }

  env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
}
示例#4
0
/*
 * Class:     sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
 * Method:    initIDs
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_initIDs
  (JNIEnv *env, jclass clazz) { 

  void* libproc_handle = dlopen("libproc.so", RTLD_LAZY | RTLD_GLOBAL);
  if (libproc_handle == 0) 
     THROW_NEW_DEBUGGER_EXCEPTION("Can't load libproc.so, if you are using Solaris 5.7 or below, copy libproc.so from 5.8!");

  ps_prochandle_ptr_ID = env->GetFieldID(clazz, "ps_prochandle_ptr", "J");
  CHECK_EXCEPTION;

  tdb_handle_ID = env->GetFieldID(clazz, "tdb_handle", "J");
  CHECK_EXCEPTION;

  p_td_init_ID = env->GetFieldID(clazz, "p_td_init", "J");
  CHECK_EXCEPTION;

  p_td_ta_new_ID = env->GetFieldID(clazz, "p_td_ta_new", "J");
  CHECK_EXCEPTION;

  p_td_ta_delete_ID = env->GetFieldID(clazz, "p_td_ta_delete", "J");
  CHECK_EXCEPTION;

  p_td_ta_thr_iter_ID = env->GetFieldID(clazz, "p_td_ta_thr_iter", "J");
  CHECK_EXCEPTION;

  p_td_thr_get_info_ID = env->GetFieldID(clazz, "p_td_thr_get_info", "J");
  CHECK_EXCEPTION;

  p_td_thr_getgregs_ID = env->GetFieldID(clazz, "p_td_thr_getgregs", "J");
  CHECK_EXCEPTION;

  setThreadIntegerRegisterSet_ID = env->GetMethodID(clazz, 
                                      "setThreadIntegerRegisterSet", "(I[J)V");
  CHECK_EXCEPTION;

  // Part of workaround for 4705086.

  // libjvm file descriptor
  libjvm_fd_ID = env->GetFieldID(clazz, "libjvm_fd", "I");
  CHECK_EXCEPTION;

  // libjvm start virtual address
  libjvm_text_start_ID = env->GetFieldID(clazz, "libjvm_text_start", "J");
  CHECK_EXCEPTION;

  // size of text in libjvm[_g].so.
  libjvm_text_size_ID = env->GetFieldID(clazz, "libjvm_text_size", "J");
  CHECK_EXCEPTION;
}
/*
 * Class:     sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
 * Method:    attach0
 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2
  (JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) {
  const char *execName_cstr;
  const char *coreName_cstr;
  jboolean isCopy;
  struct ps_prochandle* ph;

  execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy);
  CHECK_EXCEPTION;
  coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy);
  CHECK_EXCEPTION;

  if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) {
    (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
    (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
    THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");
  }
  (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
  (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
  (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
  fillThreadsAndLoadObjects(env, this_obj, ph);
}
示例#6
0
文件: saproc.cpp 项目: mearvk/JVM
static void attach_internal(JNIEnv* env, jobject this_obj, jstring cmdLine, jboolean isProcess) {
  jboolean isCopy;
  int gcode;
  const char* cmdLine_cstr = env->GetStringUTFChars(cmdLine, &isCopy);
  CHECK_EXCEPTION;

  // some older versions of libproc.so crash when trying to attach 32 bit
  // debugger to 64 bit core file. check and throw error.
#ifndef _LP64
  atoi(cmdLine_cstr);
  if (errno) {
     // core file
     int core_fd;
     if ((core_fd = open64(cmdLine_cstr, O_RDONLY)) >= 0) {
        Elf32_Ehdr e32;
        if (pread64(core_fd, &e32, sizeof (e32), 0) == sizeof (e32) &&
            memcmp(&e32.e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0 &&
            e32.e_type == ET_CORE && e32.e_ident[EI_CLASS] == ELFCLASS64) {
              close(core_fd);
              THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 64 bit, use java -d64 for debugger");
        }
        close(core_fd);
     }
     // all other conditions are handled by libproc.so.
  }
#endif

  // connect to process/core
  ps_prochandle_t* ph = proc_arg_grab(cmdLine_cstr, (isProcess? PR_ARG_PIDS : PR_ARG_CORES), PGRAB_FORCE, &gcode, NULL);

  env->ReleaseStringUTFChars(cmdLine, cmdLine_cstr);
  if (! ph) {
     if (gcode > 0 && gcode < sizeof(proc_arg_grab_errmsgs)/sizeof(const char*)) {
        char errMsg[ERR_MSG_SIZE];
        sprintf(errMsg, "Attach failed : %s", proc_arg_grab_errmsgs[gcode]);
        THROW_NEW_DEBUGGER_EXCEPTION(errMsg);
    } else {
        if (_libsaproc_debug && gcode == G_STRANGE) {
           perror("libsaproc DEBUG: ");
        }
        if (isProcess) {
           THROW_NEW_DEBUGGER_EXCEPTION("Not able to attach to process!");
        } else {
           THROW_NEW_DEBUGGER_EXCEPTION("Not able to attach to core file!");
        }
     }
  }

  // even though libproc.so supports 64 bit debugger and 32 bit debuggee, we don't
  // support such cross-bit-debugging. check for that combination and throw error.
#ifdef _LP64
  int data_model;
  if (ps_pdmodel(ph, &data_model) != PS_OK) {
     Prelease(ph, PRELEASE_CLEAR);
     THROW_NEW_DEBUGGER_EXCEPTION("can't determine debuggee data model (ILP32? or LP64?)");
  }
  if (data_model == PR_MODEL_ILP32) {
     Prelease(ph, PRELEASE_CLEAR);
     THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 32 bit, use 32 bit java for debugger");
  }
#endif

  env->SetLongField(this_obj, p_ps_prochandle_ID, (jlong)(uintptr_t)ph);

  Debugger dbg;
  dbg.env = env;
  dbg.this_obj = this_obj;
  jthrowable exception = 0;
  if (! isProcess) {
    /*
     * With class sharing, shared perm. gen heap is allocated in with MAP_SHARED|PROT_READ.
     * These pages are mapped from the file "classes.jsa". MAP_SHARED pages are not dumped
     * in Solaris core.To read shared heap pages, we have to read classes.jsa file.
     */
    Pobject_iter(ph, init_classsharing_workaround, &dbg);
    exception = env->ExceptionOccurred();
    if (exception) {
      env->ExceptionClear();
      detach_internal(env, this_obj);
      env->Throw(exception);
      return;
    }
  }

  /*
   * Iterate over the process mappings looking
   * for libthread and then dlopen the appropriate
   * libthread_db and get function pointers.
   */
  Pobject_iter(ph, init_libthread_db_ptrs, &dbg);
  exception = env->ExceptionOccurred();
  if (exception) {
    env->ExceptionClear();
    if (!sa_ignore_threaddb) {
      detach_internal(env, this_obj);
      env->Throw(exception);
    }
    return;
  }

  // init libthread_db and create thread_db agent
  p_td_init_t p_td_init = (p_td_init_t) env->GetLongField(this_obj, p_td_init_ID);
  if (p_td_init == 0) {
    if (!sa_ignore_threaddb) {
      detach_internal(env, this_obj);
    }
    HANDLE_THREADDB_FAILURE("Did not find libthread in target process/core!");
  }

  if (p_td_init() != TD_OK) {
    if (!sa_ignore_threaddb) {
      detach_internal(env, this_obj);
    }
    HANDLE_THREADDB_FAILURE("Can't initialize thread_db!");
  }

  p_td_ta_new_t p_td_ta_new = (p_td_ta_new_t) env->GetLongField(this_obj, p_td_ta_new_ID);

  td_thragent_t *p_td_thragent_t = 0;
  if (p_td_ta_new(ph, &p_td_thragent_t) != TD_OK) {
    if (!sa_ignore_threaddb) {
      detach_internal(env, this_obj);
    }
    HANDLE_THREADDB_FAILURE("Can't create thread_db agent!");
  }
  env->SetLongField(this_obj, p_td_thragent_t_ID, (jlong)(uintptr_t) p_td_thragent_t);

}
示例#7
0
文件: saproc.cpp 项目: mearvk/JVM
/*
 * Class:       sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
 * Method:      initIDs
 * Signature:   ()V
 * Description: get JNI ids for fields and methods of ProcDebuggerLocal class
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_initIDs
  (JNIEnv *env, jclass clazz) {
  _libsaproc_debug = getenv("LIBSAPROC_DEBUG") != NULL;
  if (_libsaproc_debug) {
     // propagate debug mode to libproc.so
     static const char* var = "LIBPROC_DEBUG=1";
     putenv((char*)var);
  }

  void* libproc_handle = dlopen("libproc.so", RTLD_LAZY | RTLD_GLOBAL);
  if (libproc_handle == 0)
     THROW_NEW_DEBUGGER_EXCEPTION("can't load libproc.so, if you are using Solaris 5.7 or below, copy libproc.so from 5.8!");

  p_ps_prochandle_ID = env->GetFieldID(clazz, "p_ps_prochandle", "J");
  CHECK_EXCEPTION;

  libthread_db_handle_ID = env->GetFieldID(clazz, "libthread_db_handle", "J");
  CHECK_EXCEPTION;

  p_td_thragent_t_ID = env->GetFieldID(clazz, "p_td_thragent_t", "J");
  CHECK_EXCEPTION;

  p_td_init_ID = env->GetFieldID(clazz, "p_td_init", "J");
  CHECK_EXCEPTION;

  p_td_ta_new_ID = env->GetFieldID(clazz, "p_td_ta_new", "J");
  CHECK_EXCEPTION;

  p_td_ta_delete_ID = env->GetFieldID(clazz, "p_td_ta_delete", "J");
  CHECK_EXCEPTION;

  p_td_ta_thr_iter_ID = env->GetFieldID(clazz, "p_td_ta_thr_iter", "J");
  CHECK_EXCEPTION;

  p_td_thr_get_info_ID = env->GetFieldID(clazz, "p_td_thr_get_info", "J");
  CHECK_EXCEPTION;

  p_td_ta_map_id2thr_ID = env->GetFieldID(clazz, "p_td_ta_map_id2thr", "J");
  CHECK_EXCEPTION;

  p_td_thr_getgregs_ID = env->GetFieldID(clazz, "p_td_thr_getgregs", "J");
  CHECK_EXCEPTION;

  getThreadForThreadId_ID = env->GetMethodID(clazz,
                            "getThreadForThreadId", "(J)Lsun/jvm/hotspot/debugger/ThreadProxy;");
  CHECK_EXCEPTION;

  pcRegIndex_ID = env->GetFieldID(clazz, "pcRegIndex", "I");
  CHECK_EXCEPTION;

  fpRegIndex_ID = env->GetFieldID(clazz, "fpRegIndex", "I");
  CHECK_EXCEPTION;

  createSenderFrame_ID = env->GetMethodID(clazz,
                            "createSenderFrame", "(Lsun/jvm/hotspot/debugger/proc/ProcCFrame;JJ)Lsun/jvm/hotspot/debugger/proc/ProcCFrame;");
  CHECK_EXCEPTION;

  createLoadObject_ID = env->GetMethodID(clazz,
                            "createLoadObject", "(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;");
  CHECK_EXCEPTION;

  createClosestSymbol_ID = env->GetMethodID(clazz,
                            "createClosestSymbol", "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");
  CHECK_EXCEPTION;

  jclass list_clazz = env->FindClass("java/util/List");
  CHECK_EXCEPTION;
  listAdd_ID = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z");
  CHECK_EXCEPTION;

  // part of the class sharing workaround
  classes_jsa_fd_ID = env->GetFieldID(clazz, "classes_jsa_fd", "I");
  CHECK_EXCEPTION;
  p_file_map_header_ID = env->GetFieldID(clazz, "p_file_map_header", "J");
  CHECK_EXCEPTION;
}
示例#8
0
/*
 * Class:     sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
 * Method:    attach0
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_attach0
  (JNIEnv *env, jobject this_obj, jstring cmdLine) {
  jboolean isCopy;
  int gcode;
  const char* cmdLine_cstr = env->GetStringUTFChars(cmdLine, &isCopy);
  CHECK_EXCEPTION;

  struct ps_prochandle* Pr = proc_arg_grab(cmdLine_cstr, PR_ARG_ANY, PGRAB_FORCE, &gcode);
  env->ReleaseStringUTFChars(cmdLine, cmdLine_cstr);
  if(! Pr) 
    THROW_NEW_DEBUGGER_EXCEPTION("Not able to attach to process/core file!");

  env->SetLongField(this_obj, ps_prochandle_ptr_ID, (jlong) Pr);

  // initialize libthread_db pointers
  
  /*
   * Iterate over the process mappings looking
   * for libthread and then dlopen the appropriate
   * libthread_db and get pointers to functions.
   */

  Debugger dbg;
  dbg.env = env;
  dbg.obj = this_obj;
  (void) Pobject_iter(Pr, object_iter, &dbg);
  CHECK_EXCEPTION;
  
  // get the user level threads info
  td_thragent_t *Tap = 0;
  p_td_init_t p_td_init = (p_td_init_t) env->GetLongField(this_obj, p_td_init_ID);

  if (p_td_init == 0)
     return;

  p_td_ta_new_t p_td_ta_new = (p_td_ta_new_t) env->GetLongField(this_obj, p_td_ta_new_ID);

  if (p_td_init() != TD_OK) 
     THROW_NEW_DEBUGGER_EXCEPTION("Can't initialize thread_db!");

  if (p_td_ta_new(Pr, &Tap) != TD_OK)
     THROW_NEW_DEBUGGER_EXCEPTION("Can't create thread_db agent!");
 
  /*
   * Iterate over all threads, calling:
   *   thr_stack(td_thrhandle_t *Thp, NULL);
   * for each one to generate the list of threads.
   */

  p_td_ta_thr_iter_t p_td_ta_thr_iter = (p_td_ta_thr_iter_t)
                                     env->GetLongField(this_obj, p_td_ta_thr_iter_ID);

  (void) p_td_ta_thr_iter(Tap, thr_stack, &dbg,
                          TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
                           TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
  CHECK_EXCEPTION;

  p_td_ta_delete_t p_td_ta_delete = (p_td_ta_delete_t)
                                     env->GetLongField(this_obj, p_td_ta_delete_ID);
  (void) p_td_ta_delete(Tap);
  
  // Part of workaround for 4705086.

  /* 
   * iterate over maps of the process/core to get first
   * libjvm[_g].so mapping.
   */

  Pmapping_iter(Pr, iterate_map, &dbg);
  CHECK_EXCEPTION;

  /*
   * Get libjvm[_g].so text size. First location after the end of text segment
   * is marked by the global reserved symbol '_etext' in any ELF file.
   * Please refer to page 53 of "Linkers and Libraries Guide - 816-0559".
   */

  psaddr_t etext_addr;
  if (ps_pglobal_lookup(Pr, "libjvm.so", "_etext", &etext_addr) != PS_OK) {
      // try the debug version
      if (ps_pglobal_lookup(Pr, "libjvm_g.so", "_etext", &etext_addr) != PS_OK) 
         THROW_NEW_DEBUGGER_EXCEPTION("Can't get end of text address of libjvm!");
  }

  // now calculate and set libjvm text size.
  jlong libjvm_text_start = env->GetLongField(this_obj, libjvm_text_start_ID);
  env->SetLongField(this_obj, libjvm_text_size_ID, (jlong) (etext_addr - libjvm_text_start));
}