Path: blob/master/src/jdk.hotspot.agent/linux/native/libsaproc/LinuxDebuggerLocal.cpp
41149 views
/*1* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2019, 2021, NTT DATA.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425#include <jni.h>26#include "libproc.h"27#include "proc_service.h"2829#include <elf.h>30#include <sys/types.h>31#include <sys/stat.h>32#include <fcntl.h>33#include <stdlib.h>34#include <string.h>35#include <limits.h>36#include <cxxabi.h>3738#if defined(x86_64) && !defined(amd64)39#define amd64 140#endif4142#if defined(i386) && !defined(i586)43#define i586 144#endif4546#ifdef i58647#include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h"48#endif4950#ifdef amd6451#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"52#endif5354#if defined(ppc64) || defined(ppc64le)55#include "sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext.h"56#endif5758#ifdef aarch6459#include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h"60#endif6162class AutoJavaString {63JNIEnv* m_env;64jstring m_str;65const char* m_buf;6667public:68// check env->ExceptionOccurred() after ctor69AutoJavaString(JNIEnv* env, jstring str)70: m_env(env), m_str(str), m_buf(str == NULL ? NULL : env->GetStringUTFChars(str, NULL)) {71}7273~AutoJavaString() {74if (m_buf) {75m_env->ReleaseStringUTFChars(m_str, m_buf);76}77}7879operator const char* () const {80return m_buf;81}82};8384static jfieldID p_ps_prochandle_ID = 0;85static jfieldID threadList_ID = 0;86static jfieldID loadObjectList_ID = 0;8788static jmethodID createClosestSymbol_ID = 0;89static jmethodID createLoadObject_ID = 0;90static jmethodID getThreadForThreadId_ID = 0;91static jmethodID listAdd_ID = 0;9293/*94* SA_ALTROOT environment variable.95* This memory holds env string for putenv(3).96*/97static char *saaltroot = NULL;9899#define CHECK_EXCEPTION_(value) if (env->ExceptionOccurred()) { return value; }100#define CHECK_EXCEPTION if (env->ExceptionOccurred()) { return;}101#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }102#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}103104void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {105jclass clazz;106clazz = env->FindClass("sun/jvm/hotspot/debugger/DebuggerException");107CHECK_EXCEPTION;108env->ThrowNew(clazz, errMsg);109}110111struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {112jlong ptr = env->GetLongField(this_obj, p_ps_prochandle_ID);113return (struct ps_prochandle*)(intptr_t)ptr;114}115116/*117* Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal118* Method: init0119* Signature: ()V120*/121extern "C"122JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_init0123(JNIEnv *env, jclass cls) {124jclass listClass;125126if (init_libproc(getenv("LIBSAPROC_DEBUG") != NULL) != true) {127THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc");128}129130// fields we use131p_ps_prochandle_ID = env->GetFieldID(cls, "p_ps_prochandle", "J");132CHECK_EXCEPTION;133threadList_ID = env->GetFieldID(cls, "threadList", "Ljava/util/List;");134CHECK_EXCEPTION;135loadObjectList_ID = env->GetFieldID(cls, "loadObjectList", "Ljava/util/List;");136CHECK_EXCEPTION;137138// methods we use139createClosestSymbol_ID = env->GetMethodID(cls, "createClosestSymbol",140"(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");141CHECK_EXCEPTION;142createLoadObject_ID = env->GetMethodID(cls, "createLoadObject",143"(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;");144CHECK_EXCEPTION;145getThreadForThreadId_ID = env->GetMethodID(cls, "getThreadForThreadId",146"(J)Lsun/jvm/hotspot/debugger/ThreadProxy;");147CHECK_EXCEPTION;148// java.util.List method we call149listClass = env->FindClass("java/util/List");150CHECK_EXCEPTION;151listAdd_ID = env->GetMethodID(listClass, "add", "(Ljava/lang/Object;)Z");152CHECK_EXCEPTION;153}154155extern "C"156JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getAddressSize157(JNIEnv *env, jclass cls)158{159#ifdef _LP64160return 8;161#else162return 4;163#endif164165}166167168static void fillThreadsAndLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {169int n = 0, i = 0;170171// add threads172n = get_num_threads(ph);173for (i = 0; i < n; i++) {174jobject thread;175jobject threadList;176lwpid_t lwpid;177178lwpid = get_lwp_id(ph, i);179thread = env->CallObjectMethod(this_obj, getThreadForThreadId_ID, (jlong)lwpid);180CHECK_EXCEPTION;181threadList = env->GetObjectField(this_obj, threadList_ID);182CHECK_EXCEPTION;183env->CallBooleanMethod(threadList, listAdd_ID, thread);184CHECK_EXCEPTION;185env->DeleteLocalRef(thread);186env->DeleteLocalRef(threadList);187}188189// add load objects190n = get_num_libs(ph);191for (i = 0; i < n; i++) {192uintptr_t base, memsz;193const char* name;194jobject loadObject;195jobject loadObjectList;196jstring str;197198get_lib_addr_range(ph, i, &base, &memsz);199name = get_lib_name(ph, i);200201str = env->NewStringUTF(name);202CHECK_EXCEPTION;203loadObject = env->CallObjectMethod(this_obj, createLoadObject_ID, str, (jlong)memsz, (jlong)base);204CHECK_EXCEPTION;205loadObjectList = env->GetObjectField(this_obj, loadObjectList_ID);206CHECK_EXCEPTION;207env->CallBooleanMethod(loadObjectList, listAdd_ID, loadObject);208CHECK_EXCEPTION;209env->DeleteLocalRef(str);210env->DeleteLocalRef(loadObject);211env->DeleteLocalRef(loadObjectList);212}213}214215216/*217* Verify that a named ELF binary file (core or executable) has the same218* bitness as ourselves.219* Throw an exception if there is a mismatch or other problem.220*221* If we proceed using a mismatched debugger/debuggee, the best to hope222* for is a missing symbol, the worst is a crash searching for debug symbols.223*/224void verifyBitness(JNIEnv *env, const char *binaryName) {225int fd = open(binaryName, O_RDONLY);226if (fd < 0) {227THROW_NEW_DEBUGGER_EXCEPTION("cannot open binary file");228}229unsigned char elf_ident[EI_NIDENT];230int i = read(fd, &elf_ident, sizeof(elf_ident));231close(fd);232233if (i < 0) {234THROW_NEW_DEBUGGER_EXCEPTION("cannot read binary file");235}236#ifndef _LP64237if (elf_ident[EI_CLASS] == ELFCLASS64) {238THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 64 bit, use 64-bit java for debugger");239}240#else241if (elf_ident[EI_CLASS] != ELFCLASS64) {242THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 32 bit, use 32 bit java for debugger");243}244#endif245}246247248/*249* Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal250* Method: setSAAltRoot0251* Signature: (Ljava/lang/String;)V252*/253extern "C"254JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_setSAAltRoot0255(JNIEnv *env, jobject this_obj, jstring altroot) {256if (saaltroot != NULL) {257free(saaltroot);258}259const char *path = env->GetStringUTFChars(altroot, NULL);260if (path == NULL) { return; }261/*262* `saaltroot` is used for putenv().263* So we need to keep this memory.264*/265static const char *PREFIX = "SA_ALTROOT=";266size_t len = strlen(PREFIX) + strlen(path) + 1;267saaltroot = (char *)malloc(len);268snprintf(saaltroot, len, "%s%s", PREFIX, path);269putenv(saaltroot);270env->ReleaseStringUTFChars(altroot, path);271}272273/*274* Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal275* Method: attach0276* Signature: (I)V277*/278extern "C"279JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__I280(JNIEnv *env, jobject this_obj, jint jpid) {281282// For bitness checking, locate binary at /proc/jpid/exe283char buf[PATH_MAX];284snprintf((char *) &buf, PATH_MAX, "/proc/%d/exe", jpid);285verifyBitness(env, (char *) &buf);286CHECK_EXCEPTION;287288char err_buf[200];289struct ps_prochandle* ph;290if ((ph = Pgrab(jpid, err_buf, sizeof(err_buf))) == NULL) {291char msg[230];292snprintf(msg, sizeof(msg), "Can't attach to the process: %s", err_buf);293THROW_NEW_DEBUGGER_EXCEPTION(msg);294}295env->SetLongField(this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);296fillThreadsAndLoadObjects(env, this_obj, ph);297}298299/*300* Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal301* Method: attach0302* Signature: (Ljava/lang/String;Ljava/lang/String;)V303*/304extern "C"305JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2306(JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) {307struct ps_prochandle* ph;308AutoJavaString execName_cstr(env, execName);309CHECK_EXCEPTION;310AutoJavaString coreName_cstr(env, coreName);311CHECK_EXCEPTION;312313verifyBitness(env, execName_cstr);314CHECK_EXCEPTION;315316if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) {317THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");318}319env->SetLongField(this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);320fillThreadsAndLoadObjects(env, this_obj, ph);321}322323/*324* Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal325* Method: detach0326* Signature: ()V327*/328extern "C"329JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_detach0330(JNIEnv *env, jobject this_obj) {331struct ps_prochandle* ph = get_proc_handle(env, this_obj);332if (ph != NULL) {333Prelease(ph);334}335if (saaltroot != NULL) {336free(saaltroot);337saaltroot = NULL;338}339}340341/*342* Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal343* Method: lookupByName0344* Signature: (Ljava/lang/String;Ljava/lang/String;)J345*/346extern "C"347JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByName0348(JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) {349jlong addr;350jboolean isCopy;351struct ps_prochandle* ph = get_proc_handle(env, this_obj);352// Note, objectName is ignored, and may in fact be NULL.353// lookup_symbol will always search all objects/libs354AutoJavaString objectName_cstr(env, objectName);355CHECK_EXCEPTION_(0);356AutoJavaString symbolName_cstr(env, symbolName);357CHECK_EXCEPTION_(0);358359addr = (jlong) lookup_symbol(ph, NULL, symbolName_cstr);360return addr;361}362363/*364* Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal365* Method: lookupByAddress0366* Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;367*/368extern "C"369JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByAddress0370(JNIEnv *env, jobject this_obj, jlong addr) {371uintptr_t offset;372jobject obj;373jstring str;374const char* sym = NULL;375376struct ps_prochandle* ph = get_proc_handle(env, this_obj);377sym = symbol_for_pc(ph, (uintptr_t) addr, &offset);378if (sym == NULL) return 0;379str = env->NewStringUTF(sym);380CHECK_EXCEPTION_(NULL);381obj = env->CallObjectMethod(this_obj, createClosestSymbol_ID, str, (jlong)offset);382CHECK_EXCEPTION_(NULL);383return obj;384}385386/*387* Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal388* Method: readBytesFromProcess0389* Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;390*/391extern "C"392JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_readBytesFromProcess0393(JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) {394395jboolean isCopy;396jbyteArray array;397jbyte *bufPtr;398ps_err_e err;399400array = env->NewByteArray(numBytes);401CHECK_EXCEPTION_(0);402bufPtr = env->GetByteArrayElements(array, &isCopy);403CHECK_EXCEPTION_(0);404405err = ps_pdread(get_proc_handle(env, this_obj), (psaddr_t) (uintptr_t)addr, bufPtr, numBytes);406env->ReleaseByteArrayElements(array, bufPtr, 0);407return (err == PS_OK)? array : 0;408}409410#if defined(i586) || defined(amd64) || defined(ppc64) || defined(ppc64le) || defined(aarch64)411extern "C"412JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0413(JNIEnv *env, jobject this_obj, jint lwp_id) {414415struct user_regs_struct gregs;416jboolean isCopy;417jlongArray array;418jlong *regs;419int i;420421struct ps_prochandle* ph = get_proc_handle(env, this_obj);422if (get_lwp_regs(ph, lwp_id, &gregs) != true) {423// This is not considered fatal and does happen on occassion, usually with an424// ESRCH error. The root cause is not fully understood, but by ignoring this error425// and returning NULL, stacking walking code will get null registers and fallback426// to using the "last java frame" if setup.427fprintf(stdout, "WARNING: getThreadIntegerRegisterSet0: get_lwp_regs failed for lwp (%d)\n", lwp_id);428fflush(stdout);429return NULL;430}431432#undef NPRGREG433#ifdef i586434#define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG435#endif436#ifdef amd64437#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG438#endif439#ifdef aarch64440#define NPRGREG sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_NPRGREG441#endif442#if defined(ppc64) || defined(ppc64le)443#define NPRGREG sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_NPRGREG444#endif445446447array = env->NewLongArray(NPRGREG);448CHECK_EXCEPTION_(0);449regs = env->GetLongArrayElements(array, &isCopy);450451#undef REG_INDEX452453#ifdef i586454#define REG_INDEX(reg) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##reg455456regs[REG_INDEX(GS)] = (uintptr_t) gregs.xgs;457regs[REG_INDEX(FS)] = (uintptr_t) gregs.xfs;458regs[REG_INDEX(ES)] = (uintptr_t) gregs.xes;459regs[REG_INDEX(DS)] = (uintptr_t) gregs.xds;460regs[REG_INDEX(EDI)] = (uintptr_t) gregs.edi;461regs[REG_INDEX(ESI)] = (uintptr_t) gregs.esi;462regs[REG_INDEX(FP)] = (uintptr_t) gregs.ebp;463regs[REG_INDEX(SP)] = (uintptr_t) gregs.esp;464regs[REG_INDEX(EBX)] = (uintptr_t) gregs.ebx;465regs[REG_INDEX(EDX)] = (uintptr_t) gregs.edx;466regs[REG_INDEX(ECX)] = (uintptr_t) gregs.ecx;467regs[REG_INDEX(EAX)] = (uintptr_t) gregs.eax;468regs[REG_INDEX(PC)] = (uintptr_t) gregs.eip;469regs[REG_INDEX(CS)] = (uintptr_t) gregs.xcs;470regs[REG_INDEX(SS)] = (uintptr_t) gregs.xss;471472#endif /* i586 */473474#ifdef amd64475#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg476477regs[REG_INDEX(R15)] = gregs.r15;478regs[REG_INDEX(R14)] = gregs.r14;479regs[REG_INDEX(R13)] = gregs.r13;480regs[REG_INDEX(R12)] = gregs.r12;481regs[REG_INDEX(RBP)] = gregs.rbp;482regs[REG_INDEX(RBX)] = gregs.rbx;483regs[REG_INDEX(R11)] = gregs.r11;484regs[REG_INDEX(R10)] = gregs.r10;485regs[REG_INDEX(R9)] = gregs.r9;486regs[REG_INDEX(R8)] = gregs.r8;487regs[REG_INDEX(RAX)] = gregs.rax;488regs[REG_INDEX(RCX)] = gregs.rcx;489regs[REG_INDEX(RDX)] = gregs.rdx;490regs[REG_INDEX(RSI)] = gregs.rsi;491regs[REG_INDEX(RDI)] = gregs.rdi;492regs[REG_INDEX(RIP)] = gregs.rip;493regs[REG_INDEX(CS)] = gregs.cs;494regs[REG_INDEX(RSP)] = gregs.rsp;495regs[REG_INDEX(SS)] = gregs.ss;496regs[REG_INDEX(FSBASE)] = gregs.fs_base;497regs[REG_INDEX(GSBASE)] = gregs.gs_base;498regs[REG_INDEX(DS)] = gregs.ds;499regs[REG_INDEX(ES)] = gregs.es;500regs[REG_INDEX(FS)] = gregs.fs;501regs[REG_INDEX(GS)] = gregs.gs;502503#endif /* amd64 */504505#if defined(aarch64)506507#define REG_INDEX(reg) sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_##reg508509{510int i;511for (i = 0; i < 31; i++)512regs[i] = gregs.regs[i];513regs[REG_INDEX(SP)] = gregs.sp;514regs[REG_INDEX(PC)] = gregs.pc;515}516#endif /* aarch64 */517518#if defined(ppc64) || defined(ppc64le)519#define REG_INDEX(reg) sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_##reg520521regs[REG_INDEX(LR)] = gregs.link;522regs[REG_INDEX(NIP)] = gregs.nip;523regs[REG_INDEX(R0)] = gregs.gpr[0];524regs[REG_INDEX(R1)] = gregs.gpr[1];525regs[REG_INDEX(R2)] = gregs.gpr[2];526regs[REG_INDEX(R3)] = gregs.gpr[3];527regs[REG_INDEX(R4)] = gregs.gpr[4];528regs[REG_INDEX(R5)] = gregs.gpr[5];529regs[REG_INDEX(R6)] = gregs.gpr[6];530regs[REG_INDEX(R7)] = gregs.gpr[7];531regs[REG_INDEX(R8)] = gregs.gpr[8];532regs[REG_INDEX(R9)] = gregs.gpr[9];533regs[REG_INDEX(R10)] = gregs.gpr[10];534regs[REG_INDEX(R11)] = gregs.gpr[11];535regs[REG_INDEX(R12)] = gregs.gpr[12];536regs[REG_INDEX(R13)] = gregs.gpr[13];537regs[REG_INDEX(R14)] = gregs.gpr[14];538regs[REG_INDEX(R15)] = gregs.gpr[15];539regs[REG_INDEX(R16)] = gregs.gpr[16];540regs[REG_INDEX(R17)] = gregs.gpr[17];541regs[REG_INDEX(R18)] = gregs.gpr[18];542regs[REG_INDEX(R19)] = gregs.gpr[19];543regs[REG_INDEX(R20)] = gregs.gpr[20];544regs[REG_INDEX(R21)] = gregs.gpr[21];545regs[REG_INDEX(R22)] = gregs.gpr[22];546regs[REG_INDEX(R23)] = gregs.gpr[23];547regs[REG_INDEX(R24)] = gregs.gpr[24];548regs[REG_INDEX(R25)] = gregs.gpr[25];549regs[REG_INDEX(R26)] = gregs.gpr[26];550regs[REG_INDEX(R27)] = gregs.gpr[27];551regs[REG_INDEX(R28)] = gregs.gpr[28];552regs[REG_INDEX(R29)] = gregs.gpr[29];553regs[REG_INDEX(R30)] = gregs.gpr[30];554regs[REG_INDEX(R31)] = gregs.gpr[31];555556#endif557558env->ReleaseLongArrayElements(array, regs, JNI_COMMIT);559return array;560}561#endif562563/*564* Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal565* Method: demangle566* Signature: (Ljava/lang/String;)Ljava/lang/String;567*/568extern "C"569JNIEXPORT jstring JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_demangle570(JNIEnv *env, jobject this_obj, jstring jsym) {571int status;572jstring result = NULL;573574const char *sym = env->GetStringUTFChars(jsym, NULL);575if (sym == NULL) {576THROW_NEW_DEBUGGER_EXCEPTION_("Error getting symbol string", NULL);577}578char *demangled = abi::__cxa_demangle(sym, NULL, 0, &status);579env->ReleaseStringUTFChars(jsym, sym);580if ((demangled != NULL) && (status == 0)) {581result = env->NewStringUTF(demangled);582free(demangled);583} else if (status == -2) { // not C++ ABI mangling rules - maybe C style584result = jsym;585} else {586THROW_NEW_DEBUGGER_EXCEPTION_("Could not demangle", NULL);587}588589return result;590}591592/*593* Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal594* Method: findLibPtrByAddress0595* Signature: (J)J596*/597extern "C"598JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_findLibPtrByAddress0599(JNIEnv *env, jobject this_obj, jlong pc) {600struct ps_prochandle* ph = get_proc_handle(env, this_obj);601return reinterpret_cast<jlong>(find_lib_by_address(ph, pc));602}603604605