/* * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal * Method: lookupByName0 * Signature: (Ljava/lang/String;Ljava/lang/String;)J * Description: symbol lookup by name */ JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_lookupByName0 (JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) { jlong p_ps_prochandle; p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID); jboolean isCopy; const char* objectName_cstr = NULL; if (objectName != NULL) { objectName_cstr = env->GetStringUTFChars(objectName, &isCopy); CHECK_EXCEPTION_(0); } else { objectName_cstr = PR_OBJ_EVERY; } const char* symbolName_cstr = env->GetStringUTFChars(symbolName, &isCopy); CHECK_EXCEPTION_(0); psaddr_t symbol_addr = (psaddr_t) 0; ps_pglobal_lookup((struct ps_prochandle*) p_ps_prochandle, objectName_cstr, symbolName_cstr, &symbol_addr); if (symbol_addr == 0) { print_debug("lookup for %s in %s failed\n", symbolName_cstr, objectName_cstr); } if (objectName_cstr != PR_OBJ_EVERY) { env->ReleaseStringUTFChars(objectName, objectName_cstr); } env->ReleaseStringUTFChars(symbolName, symbolName_cstr); return (jlong) (uintptr_t) symbol_addr; }
/* * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal * Method: readBytesFromProcess0 * Signature: (JJ)[B */ JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_readBytesFromProcess0 (JNIEnv *env, jobject obj, jlong address, jlong numBytes) { jbyteArray byteArray = env->NewByteArray((long) numBytes); CHECK_EXCEPTION_(0); jboolean isCopy = JNI_FALSE; jbyte* bytePtr = env->GetByteArrayElements(byteArray, &isCopy); CHECK_EXCEPTION_(0); IDebugDataSpaces* ptrIDebugDataSpaces = (IDebugDataSpaces*) env->GetLongField(obj, ptrIDebugDataSpaces_ID); CHECK_EXCEPTION_(0); ULONG bytesRead; if (ptrIDebugDataSpaces->ReadVirtual((ULONG64) address, (PVOID) bytePtr, (ULONG)numBytes, &bytesRead) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: ReadVirtual failed!", 0); } if (bytesRead != numBytes) { return 0; } env->ReleaseByteArrayElements(byteArray, bytePtr, 0); CHECK_EXCEPTION_(0); return byteArray; }
/* * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal * Method: getThreadIntegerRegisterSet0 * Signature: (J)[J * Description: get gregset for a given thread specified by thread id */ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_getThreadIntegerRegisterSet0 (JNIEnv *env, jobject this_obj, jlong tid) { // map the thread id to thread handle p_td_ta_map_id2thr_t p_td_ta_map_id2thr = (p_td_ta_map_id2thr_t) env->GetLongField(this_obj, p_td_ta_map_id2thr_ID); td_thragent_t* p_td_thragent_t = (td_thragent_t*) env->GetLongField(this_obj, p_td_thragent_t_ID); if (p_td_thragent_t == 0) { return 0; } td_thrhandle_t thr_handle; if (p_td_ta_map_id2thr(p_td_thragent_t, (thread_t) tid, &thr_handle) != TD_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("can't map thread id to thread handle!", 0); } p_td_thr_getgregs_t p_td_thr_getgregs = (p_td_thr_getgregs_t) env->GetLongField(this_obj, p_td_thr_getgregs_ID); prgregset_t gregs; p_td_thr_getgregs(&thr_handle, gregs); jlongArray res = env->NewLongArray(NPRGREG); CHECK_EXCEPTION_(0); jboolean isCopy; jlong* ptr = env->GetLongArrayElements(res, &isCopy); CHECK_EXCEPTION_(NULL); for (int i = 0; i < NPRGREG; i++) { ptr[i] = (jlong) (uintptr_t) gregs[i]; } env->ReleaseLongArrayElements(res, ptr, JNI_COMMIT); return res; }
static bool openDumpFile(JNIEnv* env, jobject obj, jstring coreFileName) { // open the dump file jboolean isCopy; const char* buf = env->GetStringUTFChars(coreFileName, &isCopy); CHECK_EXCEPTION_(false); AutoJavaString coreFile(env, coreFileName, buf); if (setImageAndSymbolPath(env, obj) == false) { return false; } IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, ptrIDebugClient_ID); CHECK_EXCEPTION_(false); if (ptrIDebugClient->OpenDumpFile(coreFile) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: OpenDumpFile failed!", false); } IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj, ptrIDebugControl_ID); CHECK_EXCEPTION_(false); if (ptrIDebugControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: WaitForEvent failed!", false); } return true; }
/* * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal * Method: fillCFrameList0 * Signature: ([J)Lsun/jvm/hotspot/debugger/proc/ProcCFrame; * Description: fills CFrame list for a given thread */ JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_fillCFrameList0 (JNIEnv *env, jobject this_obj, jlongArray regsArray) { jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID); DebuggerWith2Objects dbgo2; dbgo2.env = env; dbgo2.this_obj = this_obj; dbgo2.obj = NULL; dbgo2.obj2 = NULL; jboolean isCopy; jlong* ptr = env->GetLongArrayElements(regsArray, &isCopy); CHECK_EXCEPTION_(0); prgregset_t gregs; for (int i = 0; i < NPRGREG; i++) { gregs[i] = (uintptr_t) ptr[i]; } env->ReleaseLongArrayElements(regsArray, ptr, JNI_ABORT); CHECK_EXCEPTION_(0); Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs, wrapper_fill_cframe_list, &dbgo2); return dbgo2.obj; }
/* * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal * Method: readBytesFromProcess0 * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult; */ JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_readBytesFromProcess0 (JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) { jboolean isCopy; jbyteArray array; jbyte *bufPtr; ps_err_e err; array = (*env)->NewByteArray(env, numBytes); CHECK_EXCEPTION_(0); bufPtr = (*env)->GetByteArrayElements(env, array, &isCopy); CHECK_EXCEPTION_(0); err = ps_pdread(get_proc_handle(env, this_obj), (psaddr_t) (uintptr_t)addr, bufPtr, numBytes); (*env)->ReleaseByteArrayElements(env, array, bufPtr, 0); return (err == PS_OK)? array : 0; }
/* * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal * Method: lookup0 * Signature: (Ljava/lang/String;Ljava/lang/String;)J */ JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_lookup0 (JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) { jlong ps_prochandle_ptr; ps_prochandle_ptr = env->GetLongField(this_obj, ps_prochandle_ptr_ID); jboolean isCopy; const char* objectName_cstr = env->GetStringUTFChars(objectName, &isCopy); CHECK_EXCEPTION_(0); const char* symbolName_cstr = env->GetStringUTFChars(symbolName, &isCopy); CHECK_EXCEPTION_(0); psaddr_t symbol_addr = (psaddr_t) 0; ps_pglobal_lookup((struct ps_prochandle*) ps_prochandle_ptr, objectName_cstr, symbolName_cstr, &symbol_addr); env->ReleaseStringUTFChars(objectName, objectName_cstr); env->ReleaseStringUTFChars(symbolName, symbolName_cstr); return (jlong) symbol_addr; }
/* * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal * Method: consoleExecuteCommand0 * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_consoleExecuteCommand0 (JNIEnv *env, jobject obj, jstring cmd) { jboolean isCopy = JNI_FALSE; const char* buf = env->GetStringUTFChars(cmd, &isCopy); CHECK_EXCEPTION_(0); AutoJavaString command(env, cmd, buf); IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, ptrIDebugClient_ID); CHECK_EXCEPTION_(0); IDebugClient* tmpClientPtr = 0; if (ptrIDebugClient->CreateClient(&tmpClientPtr) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: CreateClient failed!", 0); } AutoCOMPtr<IDebugClient> tmpClient(tmpClientPtr); IDebugControl* tmpControlPtr = 0; if (tmpClient->QueryInterface(__uuidof(IDebugControl), (PVOID*) &tmpControlPtr) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: QueryInterface (IDebugControl) failed", 0); } AutoCOMPtr<IDebugControl> tmpControl(tmpControlPtr); SAOutputCallbacks* saOutputCallbacks = (SAOutputCallbacks*) env->GetLongField(obj, ptrIDebugOutputCallbacks_ID); CHECK_EXCEPTION_(0); saOutputCallbacks->clearBuffer(); if (tmpClient->SetOutputCallbacks(saOutputCallbacks) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: SetOutputCallbacks failed!", 0); } tmpControl->Execute(DEBUG_OUTPUT_VERBOSE, command, DEBUG_EXECUTE_DEFAULT); const char* output = saOutputCallbacks->getBuffer(); if (output == 0) { output = ""; } jstring res = env->NewStringUTF(output); saOutputCallbacks->clearBuffer(); return res; }
static int fill_thread_list(const td_thrhandle_t *p_td_thragent_t, void* cd) { DebuggerWithObject* dbgo = (DebuggerWithObject*) cd; JNIEnv* env = dbgo->env; jobject this_obj = dbgo->this_obj; jobject list = dbgo->obj; td_thrinfo_t thrinfo; p_td_thr_get_info_t p_td_thr_get_info = (p_td_thr_get_info_t) env->GetLongField(this_obj, p_td_thr_get_info_ID); if (p_td_thr_get_info(p_td_thragent_t, &thrinfo) != TD_OK) return (0); jobject threadProxy = env->CallObjectMethod(this_obj, getThreadForThreadId_ID, (jlong)(uintptr_t) thrinfo.ti_tid); CHECK_EXCEPTION_(1); env->CallBooleanMethod(list, listAdd_ID, threadProxy); CHECK_EXCEPTION_(1); return 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; }
/* * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal * Method: lookupByAddress0 * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol; */ JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_lookupByAddress0 (JNIEnv *env, jobject obj, jlong address) { IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, ptrIDebugSymbols_ID); CHECK_EXCEPTION_(0); ULONG64 disp = 0L; char buf[SYMBOL_BUFSIZE]; memset(buf, 0, sizeof(buf)); if (ptrIDebugSymbols->GetNameByOffset(address, buf, sizeof(buf),0,&disp) != S_OK) { return 0; } jstring sym = env->NewStringUTF(buf); CHECK_EXCEPTION_(0); jobject res = env->CallObjectMethod(obj, createClosestSymbol_ID, sym, disp); CHECK_EXCEPTION_(0); return res; }
/* * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal * Method: getThreadIdFromSysId0 * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_getThreadIdFromSysId0 (JNIEnv *env, jobject obj, jlong sysId) { IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj, ptrIDebugSystemObjects_ID); CHECK_EXCEPTION_(0); ULONG id = 0; if (ptrIDebugSystemObjects->GetThreadIdBySystemId((ULONG)sysId, &id) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetThreadIdBySystemId failed!", 0); } return (jlong) id; }
static bool attachToProcess(JNIEnv* env, jobject obj, jint pid) { if (setImageAndSymbolPath(env, obj) == false) { return false; } IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, ptrIDebugClient_ID); CHECK_EXCEPTION_(false); /*********************************************************************************** We are attaching to a process in 'read-only' mode. i.e., we do not want to put breakpoints, suspend/resume threads etc. For read-only JDI and HSDB kind of usage this should suffice. We are not intending to use this for full-fledged ProcessControl implementation to be used with BugSpotAgent. Please refer to DEBUG_ATTACH_NONINVASIVE mode source comments from dbgeng.h. In this mode, debug engine does not call DebugActiveProrcess. i.e., we are not actually debugging at all. We can safely 'detach' from the process anytime we want and debuggee process is left as is on all Windows variants. This also makes JDI-on-SA installation/usage simpler because with this we would not need a tool like ServiceInstaller from http://www.kcmultimedia.com/smaster. ***********************************************************************************/ if (ptrIDebugClient->AttachProcess(0, pid, DEBUG_ATTACH_NONINVASIVE) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: AttachProcess failed!", false); } IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj, ptrIDebugControl_ID); CHECK_EXCEPTION_(false); if (ptrIDebugControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: WaitForEvent failed!", false); } return true; }
JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_lookupByName0 (JNIEnv *env, jobject obj, jstring objName, jstring sym) { IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, ptrIDebugSymbols_ID); CHECK_EXCEPTION_(0); jboolean isCopy; const char* buf = env->GetStringUTFChars(sym, &isCopy); CHECK_EXCEPTION_(0); AutoJavaString name(env, sym, buf); ULONG64 offset = 0L; if (strstr(name, "::") != 0) { ptrIDebugSymbols->AddSymbolOptions(SYMOPT_UNDNAME); } else { ptrIDebugSymbols->RemoveSymbolOptions(SYMOPT_UNDNAME); } if (ptrIDebugSymbols->GetOffsetByName(name, &offset) != S_OK) { return (jlong) 0; } return (jlong) offset; }
static int thr_stack(const td_thrhandle_t *Thp, void *cd) { Debugger* pDebugger = (Debugger*) cd; JNIEnv* env = pDebugger->env; jobject this_obj = pDebugger->obj; td_thrinfo_t thrinfo; p_td_thr_get_info_t p_td_thr_get_info = (p_td_thr_get_info_t) env->GetLongField(this_obj, p_td_thr_get_info_ID); if (p_td_thr_get_info(Thp, &thrinfo) != TD_OK) return (0); prgregset_t regs; (void) memset(regs, 0, sizeof (prgregset_t)); p_td_thr_getgregs_t p_td_thr_getgregs = (p_td_thr_getgregs_t) env->GetLongField(this_obj, p_td_thr_getgregs_ID); (void) p_td_thr_getgregs(Thp, regs); jlongArray regSetArray = env->NewLongArray(NPRGREG); CHECK_EXCEPTION_(0); jboolean isCopy; jlong* ptrRes = env->GetLongArrayElements(regSetArray, &isCopy); CHECK_EXCEPTION_(0); // copy the reg set for(int c = 0; c < NPRGREG; c++) ptrRes[c] = (jlong) (uintptr_t) regs[c]; env->ReleaseLongArrayElements(regSetArray, ptrRes, JNI_COMMIT); env->CallVoidMethod(pDebugger->obj, setThreadIntegerRegisterSet_ID, thrinfo.ti_tid, regSetArray); CHECK_EXCEPTION_(0); return (0); }
static int fill_load_object_list(void *cd, const prmap_t* pmp, const char* obj_name) { if (obj_name) { DebuggerWithObject* dbgo = (DebuggerWithObject*) cd; JNIEnv* env = dbgo->env; jobject this_obj = dbgo->this_obj; jobject list = dbgo->obj; jstring objectName = env->NewStringUTF(obj_name); CHECK_EXCEPTION_(1); jlong mapSize = (jlong) pmp->pr_size; jobject sharedObject = env->CallObjectMethod(this_obj, createLoadObject_ID, objectName, mapSize, (jlong)(uintptr_t)pmp->pr_vaddr); CHECK_EXCEPTION_(1); env->CallBooleanMethod(list, listAdd_ID, sharedObject); CHECK_EXCEPTION_(1); } return 0; }
static bool getWindbgInterfaces(JNIEnv* env, jobject obj) { // get windbg interfaces .. IDebugClient* ptrIDebugClient = 0; if (DebugCreate(__uuidof(IDebugClient), (PVOID*) &ptrIDebugClient) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to create IDebugClient object!", false); } env->SetLongField(obj, ptrIDebugClient_ID, (jlong) ptrIDebugClient); IDebugControl* ptrIDebugControl = 0; if (ptrIDebugClient->QueryInterface(__uuidof(IDebugControl), (PVOID*) &ptrIDebugControl) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugControl", false); } env->SetLongField(obj, ptrIDebugControl_ID, (jlong) ptrIDebugControl); IDebugDataSpaces* ptrIDebugDataSpaces = 0; if (ptrIDebugClient->QueryInterface(__uuidof(IDebugDataSpaces), (PVOID*) &ptrIDebugDataSpaces) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugDataSpaces object!", false); } env->SetLongField(obj, ptrIDebugDataSpaces_ID, (jlong) ptrIDebugDataSpaces); SAOutputCallbacks* ptrIDebugOutputCallbacks = new SAOutputCallbacks(); ptrIDebugOutputCallbacks->AddRef(); env->SetLongField(obj, ptrIDebugOutputCallbacks_ID, (jlong) ptrIDebugOutputCallbacks); CHECK_EXCEPTION_(false); IDebugAdvanced* ptrIDebugAdvanced = 0; if (ptrIDebugClient->QueryInterface(__uuidof(IDebugAdvanced), (PVOID*) &ptrIDebugAdvanced) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugAdvanced object!", false); } env->SetLongField(obj, ptrIDebugAdvanced_ID, (jlong) ptrIDebugAdvanced); IDebugSymbols* ptrIDebugSymbols = 0; if (ptrIDebugClient->QueryInterface(__uuidof(IDebugSymbols), (PVOID*) &ptrIDebugSymbols) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugSymbols object!", false); } env->SetLongField(obj, ptrIDebugSymbols_ID, (jlong) ptrIDebugSymbols); IDebugSystemObjects* ptrIDebugSystemObjects = 0; if (ptrIDebugClient->QueryInterface(__uuidof(IDebugSystemObjects), (PVOID*) &ptrIDebugSystemObjects) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugSystemObjects object!", false); } env->SetLongField(obj, ptrIDebugSystemObjects_ID, (jlong) ptrIDebugSystemObjects); return true; }
static bool releaseWindbgInterfaces(JNIEnv* env, jobject obj) { IDebugDataSpaces* ptrIDebugDataSpaces = (IDebugDataSpaces*) env->GetLongField(obj, ptrIDebugDataSpaces_ID); CHECK_EXCEPTION_(false); if (ptrIDebugDataSpaces != 0) { ptrIDebugDataSpaces->Release(); } IDebugOutputCallbacks* ptrIDebugOutputCallbacks = (IDebugOutputCallbacks*) env->GetLongField(obj, ptrIDebugOutputCallbacks_ID); CHECK_EXCEPTION_(false); if (ptrIDebugOutputCallbacks != 0) { ptrIDebugOutputCallbacks->Release(); } IDebugAdvanced* ptrIDebugAdvanced = (IDebugAdvanced*) env->GetLongField(obj, ptrIDebugAdvanced_ID); CHECK_EXCEPTION_(false); if (ptrIDebugAdvanced != 0) { ptrIDebugAdvanced->Release(); } IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, ptrIDebugSymbols_ID); CHECK_EXCEPTION_(false); if (ptrIDebugSymbols != 0) { ptrIDebugSymbols->Release(); } IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj, ptrIDebugSystemObjects_ID); CHECK_EXCEPTION_(false); if (ptrIDebugSystemObjects != 0) { ptrIDebugSystemObjects->Release(); } IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj, ptrIDebugControl_ID); CHECK_EXCEPTION_(false); if (ptrIDebugControl != 0) { ptrIDebugControl->Release(); } IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, ptrIDebugClient_ID); CHECK_EXCEPTION_(false); if (ptrIDebugClient != 0) { ptrIDebugClient->Release(); } return true; }
/* * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal * Method: lookupByName0 * Signature: (Ljava/lang/String;Ljava/lang/String;)J */ JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByName0 (JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) { const char *objectName_cstr, *symbolName_cstr; jlong addr; jboolean isCopy; struct ps_prochandle* ph = get_proc_handle(env, this_obj); objectName_cstr = NULL; if (objectName != NULL) { objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy); CHECK_EXCEPTION_(0); } symbolName_cstr = (*env)->GetStringUTFChars(env, symbolName, &isCopy); CHECK_EXCEPTION_(0); addr = (jlong) lookup_symbol(ph, objectName_cstr, symbolName_cstr); if (objectName_cstr != NULL) { (*env)->ReleaseStringUTFChars(env, objectName, objectName_cstr); } (*env)->ReleaseStringUTFChars(env, symbolName, symbolName_cstr); return addr; }
static bool setImageAndSymbolPath(JNIEnv* env, jobject obj) { jboolean isCopy; jclass clazz = env->GetObjectClass(obj); jstring path; const char* buf; path = (jstring) env->GetStaticObjectField(clazz, imagePath_ID); buf = env->GetStringUTFChars(path, &isCopy); CHECK_EXCEPTION_(false); AutoJavaString imagePath(env, path, buf); path = (jstring) env->GetStaticObjectField(clazz, symbolPath_ID); buf = env->GetStringUTFChars(path, &isCopy); CHECK_EXCEPTION_(false); AutoJavaString symbolPath(env, path, buf); IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, ptrIDebugSymbols_ID); CHECK_EXCEPTION_(false); ptrIDebugSymbols->SetImagePath(imagePath); ptrIDebugSymbols->SetSymbolPath(symbolPath); return true; }
static bool addLoadObjects(JNIEnv* env, jobject obj) { IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, ptrIDebugSymbols_ID); CHECK_EXCEPTION_(false); ULONG loaded = 0, unloaded = 0; if (ptrIDebugSymbols->GetNumberModules(&loaded, &unloaded) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetNumberModules failed!", false); } AutoArrayPtr<DEBUG_MODULE_PARAMETERS> params(new DEBUG_MODULE_PARAMETERS[loaded]); if (params.asPtr() == 0) { THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate debug module params!", false); } if (ptrIDebugSymbols->GetModuleParameters(loaded, 0, NULL, params.asPtr()) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetModuleParameters failed!", false); } for (int u = 0; u < (int)loaded; u++) { TCHAR imageName[MAX_PATH]; if (ptrIDebugSymbols->GetModuleNames(DEBUG_ANY_ID, params.asPtr()[u].Base, imageName, MAX_PATH, NULL, NULL, 0, NULL, NULL, 0, NULL) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetModuleNames failed!", false); } jstring strName = env->NewStringUTF(imageName); CHECK_EXCEPTION_(false); env->CallVoidMethod(obj, addLoadObject_ID, strName, (jlong) params.asPtr()[u].Size, (jlong) params.asPtr()[u].Base); CHECK_EXCEPTION_(false); } return true; }
/* * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal * Method: demangle0 * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_demangle0 (JNIEnv *env, jobject this_object, jstring name) { jboolean isCopy; const char* ptr = env->GetStringUTFChars(name, &isCopy); CHECK_EXCEPTION_(NULL); char buf[2*SYMBOL_BUF_SIZE + 1]; jstring res = 0; if (cplus_demangle((char*) ptr, buf, sizeof(buf)) != DEMANGLE_ESPACE) { res = env->NewStringUTF(buf); } else { res = name; } env->ReleaseStringUTFChars(name, ptr); return res; }
/* * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal * Method: lookupByAddress0 * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol; * Description: lookup symbol name for a given address */ JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_lookupByAddress0 (JNIEnv *env, jobject this_obj, jlong address) { jlong p_ps_prochandle; p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID); char nameBuf[SYMBOL_BUF_SIZE + 1]; GElf_Sym sym; int res = Plookup_by_addr((struct ps_prochandle*) p_ps_prochandle, (uintptr_t) address, nameBuf, sizeof(nameBuf), &sym); if (res != 0) { // failed return 0; } jstring resSym = env->NewStringUTF(nameBuf); CHECK_EXCEPTION_(0); return env->CallObjectMethod(this_obj, createClosestSymbol_ID, resSym, (address - sym.st_value)); }
// Pstack_iter() proc_stack_f callback prior to Nevada-B159 static int fill_cframe_list(void *cd, const prgregset_t regs, uint_t argc, const long *argv) { DebuggerWith2Objects* dbgo2 = (DebuggerWith2Objects*) cd; JNIEnv* env = dbgo2->env; jobject this_obj = dbgo2->this_obj; jobject curFrame = dbgo2->obj2; jint pcRegIndex = env->GetIntField(this_obj, pcRegIndex_ID); jint fpRegIndex = env->GetIntField(this_obj, fpRegIndex_ID); jlong pc = (jlong) (uintptr_t) regs[pcRegIndex]; jlong fp = (jlong) (uintptr_t) regs[fpRegIndex]; dbgo2->obj2 = env->CallObjectMethod(this_obj, createSenderFrame_ID, curFrame, pc, fp); CHECK_EXCEPTION_(1); if (dbgo2->obj == 0) { dbgo2->obj = dbgo2->obj2; } return 0; }
JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0 (JNIEnv *env, jobject this_obj, jint lwp_id) { struct user_regs_struct gregs; jboolean isCopy; jlongArray array; jlong *regs; int i; struct ps_prochandle* ph = get_proc_handle(env, this_obj); if (get_lwp_regs(ph, lwp_id, &gregs) != true) { THROW_NEW_DEBUGGER_EXCEPTION_("get_thread_regs failed for a lwp", 0); } #undef NPRGREG #ifdef i386 #define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG #endif #ifdef ia64 #define NPRGREG IA64_REG_COUNT #endif #ifdef amd64 #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG #endif #if defined(sparc) || defined(sparcv9) #define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG #endif array = (*env)->NewLongArray(env, NPRGREG); CHECK_EXCEPTION_(0); regs = (*env)->GetLongArrayElements(env, array, &isCopy); #undef REG_INDEX #ifdef i386 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##reg regs[REG_INDEX(GS)] = (uintptr_t) gregs.xgs; regs[REG_INDEX(FS)] = (uintptr_t) gregs.xfs; regs[REG_INDEX(ES)] = (uintptr_t) gregs.xes; regs[REG_INDEX(DS)] = (uintptr_t) gregs.xds; regs[REG_INDEX(EDI)] = (uintptr_t) gregs.edi; regs[REG_INDEX(ESI)] = (uintptr_t) gregs.esi; regs[REG_INDEX(FP)] = (uintptr_t) gregs.ebp; regs[REG_INDEX(SP)] = (uintptr_t) gregs.esp; regs[REG_INDEX(EBX)] = (uintptr_t) gregs.ebx; regs[REG_INDEX(EDX)] = (uintptr_t) gregs.edx; regs[REG_INDEX(ECX)] = (uintptr_t) gregs.ecx; regs[REG_INDEX(EAX)] = (uintptr_t) gregs.eax; regs[REG_INDEX(PC)] = (uintptr_t) gregs.eip; regs[REG_INDEX(CS)] = (uintptr_t) gregs.xcs; regs[REG_INDEX(SS)] = (uintptr_t) gregs.xss; #endif /* i386 */ #if ia64 regs = (*env)->GetLongArrayElements(env, array, &isCopy); for (i = 0; i < NPRGREG; i++ ) { regs[i] = 0xDEADDEAD; } #endif /* ia64 */ #ifdef amd64 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg regs[REG_INDEX(R15)] = gregs.r15; regs[REG_INDEX(R14)] = gregs.r14; regs[REG_INDEX(R13)] = gregs.r13; regs[REG_INDEX(R12)] = gregs.r12; regs[REG_INDEX(RBP)] = gregs.rbp; regs[REG_INDEX(RBX)] = gregs.rbx; regs[REG_INDEX(R11)] = gregs.r11; regs[REG_INDEX(R10)] = gregs.r10; regs[REG_INDEX(R9)] = gregs.r9; regs[REG_INDEX(R8)] = gregs.r8; regs[REG_INDEX(RAX)] = gregs.rax; regs[REG_INDEX(RCX)] = gregs.rcx; regs[REG_INDEX(RDX)] = gregs.rdx; regs[REG_INDEX(RSI)] = gregs.rsi; regs[REG_INDEX(RDI)] = gregs.rdi; regs[REG_INDEX(RIP)] = gregs.rip; regs[REG_INDEX(CS)] = gregs.cs; regs[REG_INDEX(RSP)] = gregs.rsp; regs[REG_INDEX(SS)] = gregs.ss; regs[REG_INDEX(FSBASE)] = gregs.fs_base; regs[REG_INDEX(GSBASE)] = gregs.gs_base; regs[REG_INDEX(DS)] = gregs.ds; regs[REG_INDEX(ES)] = gregs.es; regs[REG_INDEX(FS)] = gregs.fs; regs[REG_INDEX(GS)] = gregs.gs; #endif /* amd64 */ #if defined(sparc) || defined(sparcv9) #define REG_INDEX(reg) sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_##reg #ifdef _LP64 regs[REG_INDEX(R_PSR)] = gregs.tstate; regs[REG_INDEX(R_PC)] = gregs.tpc; regs[REG_INDEX(R_nPC)] = gregs.tnpc; regs[REG_INDEX(R_Y)] = gregs.y; #else regs[REG_INDEX(R_PSR)] = gregs.psr; regs[REG_INDEX(R_PC)] = gregs.pc; regs[REG_INDEX(R_nPC)] = gregs.npc; regs[REG_INDEX(R_Y)] = gregs.y; #endif regs[REG_INDEX(R_G0)] = 0 ; regs[REG_INDEX(R_G1)] = gregs.u_regs[0]; regs[REG_INDEX(R_G2)] = gregs.u_regs[1]; regs[REG_INDEX(R_G3)] = gregs.u_regs[2]; regs[REG_INDEX(R_G4)] = gregs.u_regs[3]; regs[REG_INDEX(R_G5)] = gregs.u_regs[4]; regs[REG_INDEX(R_G6)] = gregs.u_regs[5]; regs[REG_INDEX(R_G7)] = gregs.u_regs[6]; regs[REG_INDEX(R_O0)] = gregs.u_regs[7]; regs[REG_INDEX(R_O1)] = gregs.u_regs[8]; regs[REG_INDEX(R_O2)] = gregs.u_regs[ 9]; regs[REG_INDEX(R_O3)] = gregs.u_regs[10]; regs[REG_INDEX(R_O4)] = gregs.u_regs[11]; regs[REG_INDEX(R_O5)] = gregs.u_regs[12]; regs[REG_INDEX(R_O6)] = gregs.u_regs[13]; regs[REG_INDEX(R_O7)] = gregs.u_regs[14]; #endif /* sparc */ (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT); return array; }
static bool addThreads(JNIEnv* env, jobject obj) { IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj, ptrIDebugSystemObjects_ID); CHECK_EXCEPTION_(false); ULONG numThreads = 0; if (ptrIDebugSystemObjects->GetNumberThreads(&numThreads) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetNumberThreads failed!", false); } AutoArrayPtr<ULONG> ptrSysThreadIds = new ULONG[numThreads]; if (ptrSysThreadIds.asPtr() == 0) { THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate thread ids!", false); } AutoArrayPtr<ULONG> ptrThreadIds = new ULONG[numThreads]; if (ptrThreadIds.asPtr() == 0) { THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate thread ids!", false); } if (ptrIDebugSystemObjects->GetThreadIdsByIndex(0, numThreads, ptrThreadIds.asPtr(), ptrSysThreadIds.asPtr()) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetThreadIdsByIndex failed!", false); } IDebugAdvanced* ptrIDebugAdvanced = (IDebugAdvanced*) env->GetLongField(obj, ptrIDebugAdvanced_ID); CHECK_EXCEPTION_(false); // for each thread, get register context and save it. for (ULONG t = 0; t < numThreads; t++) { if (ptrIDebugSystemObjects->SetCurrentThreadId(ptrThreadIds.asPtr()[t]) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: SetCurrentThread failed!", false); } jlongArray regs = env->NewLongArray(NPRGREG); CHECK_EXCEPTION_(false); jboolean isCopy = JNI_FALSE; jlong* ptrRegs = env->GetLongArrayElements(regs, &isCopy); CHECK_EXCEPTION_(false); // copy register values from the CONTEXT struct CONTEXT context; memset(&context, 0, sizeof(CONTEXT)); #undef REG_INDEX #ifdef _M_IA64 #define REG_INDEX(x) sun_jvm_hotspot_debugger_ia64_IA64ThreadContext_##x context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG; ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT)); ptrRegs[REG_INDEX(GR0)] = 0; // always 0 ptrRegs[REG_INDEX(GR1)] = context.IntGp; // r1 ptrRegs[REG_INDEX(GR2)] = context.IntT0; // r2-r3 ptrRegs[REG_INDEX(GR3)] = context.IntT1; ptrRegs[REG_INDEX(GR4)] = context.IntS0; // r4-r7 ptrRegs[REG_INDEX(GR5)] = context.IntS1; ptrRegs[REG_INDEX(GR6)] = context.IntS2; ptrRegs[REG_INDEX(GR7)] = context.IntS3; ptrRegs[REG_INDEX(GR8)] = context.IntV0; // r8 ptrRegs[REG_INDEX(GR9)] = context.IntT2; // r9-r11 ptrRegs[REG_INDEX(GR10)] = context.IntT3; ptrRegs[REG_INDEX(GR11)] = context.IntT4; ptrRegs[REG_INDEX(GR12)] = context.IntSp; // r12 stack pointer ptrRegs[REG_INDEX(GR13)] = context.IntTeb; // r13 teb ptrRegs[REG_INDEX(GR14)] = context.IntT5; // r14-r31 ptrRegs[REG_INDEX(GR15)] = context.IntT6; ptrRegs[REG_INDEX(GR16)] = context.IntT7; ptrRegs[REG_INDEX(GR17)] = context.IntT8; ptrRegs[REG_INDEX(GR18)] = context.IntT9; ptrRegs[REG_INDEX(GR19)] = context.IntT10; ptrRegs[REG_INDEX(GR20)] = context.IntT11; ptrRegs[REG_INDEX(GR21)] = context.IntT12; ptrRegs[REG_INDEX(GR22)] = context.IntT13; ptrRegs[REG_INDEX(GR23)] = context.IntT14; ptrRegs[REG_INDEX(GR24)] = context.IntT15; ptrRegs[REG_INDEX(GR25)] = context.IntT16; ptrRegs[REG_INDEX(GR26)] = context.IntT17; ptrRegs[REG_INDEX(GR27)] = context.IntT18; ptrRegs[REG_INDEX(GR28)] = context.IntT19; ptrRegs[REG_INDEX(GR29)] = context.IntT20; ptrRegs[REG_INDEX(GR30)] = context.IntT21; ptrRegs[REG_INDEX(GR31)] = context.IntT22; ptrRegs[REG_INDEX(INT_NATS)] = context.IntNats; ptrRegs[REG_INDEX(PREDS)] = context.Preds; ptrRegs[REG_INDEX(BR_RP)] = context.BrRp; ptrRegs[REG_INDEX(BR1)] = context.BrS0; // b1-b5 ptrRegs[REG_INDEX(BR2)] = context.BrS1; ptrRegs[REG_INDEX(BR3)] = context.BrS2; ptrRegs[REG_INDEX(BR4)] = context.BrS3; ptrRegs[REG_INDEX(BR5)] = context.BrS4; ptrRegs[REG_INDEX(BR6)] = context.BrT0; // b6-b7 ptrRegs[REG_INDEX(BR7)] = context.BrT1; ptrRegs[REG_INDEX(AP_UNAT)] = context.ApUNAT; ptrRegs[REG_INDEX(AP_LC)] = context.ApLC; ptrRegs[REG_INDEX(AP_EC)] = context.ApEC; ptrRegs[REG_INDEX(AP_CCV)] = context.ApCCV; ptrRegs[REG_INDEX(AP_DCR)] = context.ApDCR; ptrRegs[REG_INDEX(RS_PFS)] = context.RsPFS; ptrRegs[REG_INDEX(RS_BSP)] = context.RsBSP; ptrRegs[REG_INDEX(RS_BSPSTORE)] = context.RsBSPSTORE; ptrRegs[REG_INDEX(RS_RSC)] = context.RsRSC; ptrRegs[REG_INDEX(RS_RNAT)] = context.RsRNAT; ptrRegs[REG_INDEX(ST_IPSR)] = context.StIPSR; ptrRegs[REG_INDEX(ST_IIP)] = context.StIIP; ptrRegs[REG_INDEX(ST_IFS)] = context.StIFS; ptrRegs[REG_INDEX(DB_I0)] = context.DbI0; ptrRegs[REG_INDEX(DB_I1)] = context.DbI1; ptrRegs[REG_INDEX(DB_I2)] = context.DbI2; ptrRegs[REG_INDEX(DB_I3)] = context.DbI3; ptrRegs[REG_INDEX(DB_I4)] = context.DbI4; ptrRegs[REG_INDEX(DB_I5)] = context.DbI5; ptrRegs[REG_INDEX(DB_I6)] = context.DbI6; ptrRegs[REG_INDEX(DB_I7)] = context.DbI7; ptrRegs[REG_INDEX(DB_D0)] = context.DbD0; ptrRegs[REG_INDEX(DB_D1)] = context.DbD1; ptrRegs[REG_INDEX(DB_D2)] = context.DbD2; ptrRegs[REG_INDEX(DB_D3)] = context.DbD3; ptrRegs[REG_INDEX(DB_D4)] = context.DbD4; ptrRegs[REG_INDEX(DB_D5)] = context.DbD5; ptrRegs[REG_INDEX(DB_D6)] = context.DbD6; ptrRegs[REG_INDEX(DB_D7)] = context.DbD7; #elif _M_IX86 #define REG_INDEX(x) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##x context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT)); ptrRegs[REG_INDEX(GS)] = context.SegGs; ptrRegs[REG_INDEX(FS)] = context.SegFs; ptrRegs[REG_INDEX(ES)] = context.SegEs; ptrRegs[REG_INDEX(DS)] = context.SegDs; ptrRegs[REG_INDEX(EDI)] = context.Edi; ptrRegs[REG_INDEX(ESI)] = context.Esi; ptrRegs[REG_INDEX(EBX)] = context.Ebx; ptrRegs[REG_INDEX(EDX)] = context.Edx; ptrRegs[REG_INDEX(ECX)] = context.Ecx; ptrRegs[REG_INDEX(EAX)] = context.Eax; ptrRegs[REG_INDEX(FP)] = context.Ebp; ptrRegs[REG_INDEX(PC)] = context.Eip; ptrRegs[REG_INDEX(CS)] = context.SegCs; ptrRegs[REG_INDEX(EFL)] = context.EFlags; ptrRegs[REG_INDEX(SP)] = context.Esp; ptrRegs[REG_INDEX(SS)] = context.SegSs; ptrRegs[REG_INDEX(DR0)] = context.Dr0; ptrRegs[REG_INDEX(DR1)] = context.Dr1; ptrRegs[REG_INDEX(DR2)] = context.Dr2; ptrRegs[REG_INDEX(DR3)] = context.Dr3; ptrRegs[REG_INDEX(DR6)] = context.Dr6; ptrRegs[REG_INDEX(DR7)] = context.Dr7; #elif _M_AMD64 #define REG_INDEX(x) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##x context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT)); // Segment Registers and processor flags ptrRegs[REG_INDEX(CS)] = context.SegCs; ptrRegs[REG_INDEX(DS)] = context.SegDs; ptrRegs[REG_INDEX(ES)] = context.SegEs; ptrRegs[REG_INDEX(FS)] = context.SegFs; ptrRegs[REG_INDEX(GS)] = context.SegGs; ptrRegs[REG_INDEX(SS)] = context.SegSs; ptrRegs[REG_INDEX(RFL)] = context.EFlags; // Integer registers ptrRegs[REG_INDEX(RDI)] = context.Rdi; ptrRegs[REG_INDEX(RSI)] = context.Rsi; ptrRegs[REG_INDEX(RAX)] = context.Rax; ptrRegs[REG_INDEX(RCX)] = context.Rcx; ptrRegs[REG_INDEX(RDX)] = context.Rdx; ptrRegs[REG_INDEX(RBX)] = context.Rbx; ptrRegs[REG_INDEX(RBP)] = context.Rbp; ptrRegs[REG_INDEX(RSP)] = context.Rsp; ptrRegs[REG_INDEX(R8)] = context.R8; ptrRegs[REG_INDEX(R9)] = context.R9; ptrRegs[REG_INDEX(R10)] = context.R10; ptrRegs[REG_INDEX(R11)] = context.R11; ptrRegs[REG_INDEX(R12)] = context.R12; ptrRegs[REG_INDEX(R13)] = context.R13; ptrRegs[REG_INDEX(R14)] = context.R14; ptrRegs[REG_INDEX(R15)] = context.R15; // Program counter ptrRegs[REG_INDEX(RIP)] = context.Rip; #endif env->ReleaseLongArrayElements(regs, ptrRegs, JNI_COMMIT); CHECK_EXCEPTION_(false); env->CallVoidMethod(obj, setThreadIntegerRegisterSet_ID, (jlong) ptrThreadIds.asPtr()[t], regs); CHECK_EXCEPTION_(false); ULONG sysId; if (ptrIDebugSystemObjects->GetCurrentThreadSystemId(&sysId) != S_OK) { THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetCurrentThreadSystemId failed!", false); } env->CallVoidMethod(obj, addThread_ID, (jlong) sysId); CHECK_EXCEPTION_(false); } return true; }
/* * 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; } }