agent/src/os/solaris/proc/saproc.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/agent/src/os/solaris/proc/saproc.cpp	Wed Aug 26 18:19:56 2009
--- new/agent/src/os/solaris/proc/saproc.cpp	Wed Aug 26 18:19:56 2009

*** 22,31 **** --- 22,32 ---- * */ #include "salibproc.h" #include "sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal.h" + #include "sun_jvm_hotspot_asm_Disassembler.h" #include <thread_db.h> #include <strings.h> #include <limits.h> #include <demangle.h> #include <stdarg.h>
*** 1295,1300 **** --- 1296,1425 ---- // 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; + } + + + /* + * Class: sun_jvm_hotspot_asm_Disassembler + * Method: load_library + * Signature: (Ljava/lang/String;)L + */ + JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_asm_Disassembler_load_1library(JNIEnv * env, + jclass disclass, + jstring libname_s) { + jboolean isCopy; + const char * libname = env->GetStringUTFChars(libname_s, &isCopy); + char buffer[PATH_MAX+1]; + snprintf(buffer, PATH_MAX, "%s.so", libname); + void* hsdis_handle = dlopen(buffer, RTLD_LAZY | RTLD_GLOBAL); + if (hsdis_handle != NULL) { + return (jlong)dlsym(hsdis_handle, "decode_instructions_virtual"); + } + return 0; + } + + struct decode_env { + JNIEnv* env; + jobject dis; + jobject visitor; + jmethodID handle_event; + jmethodID raw_print; + char buffer[4096]; + }; + + typedef void* (*decode_func)(void* start_va, + void* start, void* end, + void* (*event_callback)(void*, const char*, void*), + void* event_stream, + int (*printf_callback)(void*, const char*, ...), + void* printf_stream, + const char* options); + + static void* event_to_env(void* env_pv, const char* event, void* arg) { + decode_env* denv = (decode_env*)env_pv; + JNIEnv* env = denv->env; + jstring event_string = env->NewStringUTF(event); + jlong result = env->CallLongMethod(denv->dis, denv->handle_event, denv->visitor, event_string, (jlong) arg); + jthrowable exception = env->ExceptionOccurred(); + if (exception) { + env->ExceptionClear(); + result = 0; + } + return (void*)result; + } + + static int printf_to_env(void* env_pv, const char* format, ...) { + decode_env* denv = (decode_env*)env_pv; + JNIEnv* env = denv->env; + size_t flen = strlen(format); + const char* raw = NULL; + if (flen == 0) return 0; + if (flen < 2 || + strchr(format, '%') == NULL) { + raw = format; + } else if (format[0] == '%' && format[1] == '%' && + strchr(format+2, '%') == NULL) { + // happens a lot on machines with names like %foo + flen--; + raw = format+1; + } + if (raw != NULL) { + jstring output = env->NewStringUTF(raw); + env->CallVoidMethod(denv->dis, denv->raw_print, denv->visitor, output); + jthrowable exception = env->ExceptionOccurred(); + if (exception) { + env->ExceptionClear(); + } + return (int) flen; + } + va_list ap; + va_start(ap, format); + int cnt = vsnprintf(denv->buffer, sizeof(denv->buffer), format, ap); + va_end(ap); + + jstring output = env->NewStringUTF(denv->buffer); + env->CallVoidMethod(denv->dis, denv->raw_print, denv->visitor, output); + jthrowable exception = env->ExceptionOccurred(); + if (exception) { + env->ExceptionClear(); + } + return cnt; + } + + + /* + * Class: sun_jvm_hotspot_asm_Disassembler + * Method: decode + * Signature: (Lsun/jvm/hotspot/asm/InstructionVisitor;J[BLjava/lang/String;J)V + */ + JNIEXPORT void JNICALL Java_sun_jvm_hotspot_asm_Disassembler_decode(JNIEnv * env, + jobject dis, + jobject visitor, + jlong startPc, + jbyteArray code, + jstring options_s, + jlong decode_instructions_virtual) { + jboolean isCopy; + jbyte* start = env->GetByteArrayElements(code, &isCopy); + jbyte* end = start + env->GetArrayLength(code); + const char * options = env->GetStringUTFChars(options_s, &isCopy); + + decode_env denv; + denv.env = env; + denv.dis = dis; + denv.visitor = visitor; + jclass disclass = env->GetObjectClass(dis); + denv.handle_event = env->GetMethodID(disclass, "handle_event", "(Lsun/jvm/hotspot/asm/InstructionVisitor;Ljava/lang/String;J)J"); + CHECK_EXCEPTION; + + denv.raw_print = env->GetMethodID(disclass, "raw_print", "(Lsun/jvm/hotspot/asm/InstructionVisitor;Ljava/lang/String;)V"); + CHECK_EXCEPTION; + + + (*(decode_func)decode_instructions_virtual)((void*)startPc, start, end, + &event_to_env, (void*) &denv, + &printf_to_env, (void*) &denv, + options); }

agent/src/os/solaris/proc/saproc.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File