static void clear_libthread_db_ptrs(JNIEnv* env, jobject this_obj) { // release libthread_db agent, if we had created p_td_ta_delete_t p_td_ta_delete = 0; p_td_ta_delete = (p_td_ta_delete_t) env->GetLongField(this_obj, p_td_ta_delete_ID); td_thragent_t *p_td_thragent_t = 0; p_td_thragent_t = (td_thragent_t*) env->GetLongField(this_obj, p_td_thragent_t_ID); if (p_td_thragent_t != 0 && p_td_ta_delete != 0) { p_td_ta_delete(p_td_thragent_t); } // dlclose libthread_db.so void* libthread_db_handle = (void*) env->GetLongField(this_obj, libthread_db_handle_ID); if (libthread_db_handle != 0) { dlclose(libthread_db_handle); } env->SetLongField(this_obj, libthread_db_handle_ID, (jlong)0); env->SetLongField(this_obj, p_td_init_ID, (jlong)0); env->SetLongField(this_obj, p_td_ta_new_ID, (jlong)0); env->SetLongField(this_obj, p_td_ta_delete_ID, (jlong)0); env->SetLongField(this_obj, p_td_ta_thr_iter_ID, (jlong)0); env->SetLongField(this_obj, p_td_thr_get_info_ID, (jlong)0); env->SetLongField(this_obj, p_td_ta_map_id2thr_ID, (jlong)0); env->SetLongField(this_obj, p_td_thr_getgregs_ID, (jlong)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)); }