# HG changeset patch # User zgu # Date 1360360541 28800 # Node ID 3f11b37f047c0ce2b8fcb20ff4b1f15945f47bd6 # Parent 41d73c9b30a83de69ef0739d802ac98d20fe0164# Parent 7194f764221cb69095aa8e5571ea7cb8b663f8dd Merge diff -r 41d73c9b30a8 -r 3f11b37f047c agent/src/os/bsd/MacosxDebuggerLocal.m --- a/agent/src/os/bsd/MacosxDebuggerLocal.m Fri Feb 08 16:31:48 2013 -0500 +++ b/agent/src/os/bsd/MacosxDebuggerLocal.m Fri Feb 08 13:55:41 2013 -0800 @@ -97,7 +97,8 @@ * Method: init0 * Signature: ()V */ -JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0(JNIEnv *env, jclass cls) { +JNIEXPORT void JNICALL +Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0(JNIEnv *env, jclass cls) { symbolicatorID = (*env)->GetFieldID(env, cls, "symbolicator", "J"); taskID = (*env)->GetFieldID(env, cls, "task", "J"); CHECK_EXCEPTION; @@ -108,7 +109,11 @@ * Method: lookupByName0 * Signature: (Ljava/lang/String;Ljava/lang/String;)J */ -JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0(JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) { +JNIEXPORT jlong JNICALL +Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0( + JNIEnv *env, jobject this_obj, + jstring objectName, jstring symbolName) +{ jlong address = 0; JNF_COCOA_ENTER(env); @@ -137,7 +142,11 @@ * Method: readBytesFromProcess0 * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult; */ -JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0(JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) { +JNIEXPORT jbyteArray JNICALL +Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0( + JNIEnv *env, jobject this_obj, + jlong addr, jlong numBytes) +{ if (debug) printf("readBytesFromProcess called. addr = %llx numBytes = %lld\n", addr, numBytes); // must allocate storage instead of using former parameter buf @@ -209,12 +218,74 @@ return array; } + /* - * Class: sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal + * Lookup the thread_t that corresponds to the given thread_id. + * The thread_id should be the result from calling thread_info() with THREAD_IDENTIFIER_INFO + * and reading the m_ident_info.thread_id returned. + * The returned thread_t is the mach send right to the kernel port for the corresponding thread. + * + * We cannot simply use the OSThread._thread_id field in the JVM. This is set to ::mach_thread_self() + * in the VM, but that thread port is not valid for a remote debugger to access the thread. + */ +thread_t +lookupThreadFromThreadId(task_t task, jlong thread_id) { + if (debug) { + printf("lookupThreadFromThreadId thread_id=0x%llx\n", thread_id); + } + + thread_array_t thread_list = NULL; + mach_msg_type_number_t thread_list_count = 0; + thread_t result_thread = 0; + int i; + + // get the list of all the send rights + kern_return_t result = task_threads(task, &thread_list, &thread_list_count); + if (result != KERN_SUCCESS) { + if (debug) { + printf("task_threads returned 0x%x\n", result); + } + return 0; + } + + for(i = 0 ; i < thread_list_count; i++) { + thread_identifier_info_data_t m_ident_info; + mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT; + + // get the THREAD_IDENTIFIER_INFO for the send right + result = thread_info(thread_list[i], THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count); + if (result != KERN_SUCCESS) { + if (debug) { + printf("thread_info returned 0x%x\n", result); + } + break; + } + + // if this is the one we're looking for, return the send right + if (thread_id == m_ident_info.thread_id) + { + result_thread = thread_list[i]; + break; + } + } + + vm_size_t thread_list_size = (vm_size_t) (thread_list_count * sizeof (thread_t)); + vm_deallocate(mach_task_self(), (vm_address_t) thread_list, thread_list_count); + + return result_thread; +} + + +/* + * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal * Method: getThreadIntegerRegisterSet0 - * Signature: (I)[J + * Signature: (J)[J */ -JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0(JNIEnv *env, jobject this_obj, jint lwp_id) { +JNIEXPORT jlongArray JNICALL +Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0( + JNIEnv *env, jobject this_obj, + jlong thread_id) +{ if (debug) printf("getThreadRegisterSet0 called\n"); @@ -226,8 +297,9 @@ int i; jlongArray registerArray; jlong *primitiveArray; + task_t gTask = getTask(env, this_obj); - tid = lwp_id; + tid = lookupThreadFromThreadId(gTask, thread_id); result = thread_get_state(tid, HSDB_THREAD_STATE, (thread_state_t)&state, &count); @@ -328,19 +400,21 @@ } /* - * Class: sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal + * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal * Method: translateTID0 * Signature: (I)I */ JNIEXPORT jint JNICALL -Java_sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal_translateTID0(JNIEnv *env, jobject this_obj, jint tid) { +Java_sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal_translateTID0( + JNIEnv *env, jobject this_obj, jint tid) +{ if (debug) printf("translateTID0 called on tid = 0x%x\n", (int)tid); kern_return_t result; thread_t foreign_tid, usable_tid; mach_msg_type_name_t type; - + foreign_tid = tid; task_t gTask = getTask(env, this_obj); @@ -361,7 +435,10 @@ * Method: attach0 * Signature: (I)V */ -JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I(JNIEnv *env, jobject this_obj, jint jpid) { +JNIEXPORT void JNICALL +Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I( + JNIEnv *env, jobject this_obj, jint jpid) +{ JNF_COCOA_ENTER(env); if (getenv("JAVA_SAPROC_DEBUG") != NULL) debug = JNI_TRUE; @@ -401,7 +478,10 @@ * Method: detach0 * Signature: ()V */ -JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0(JNIEnv *env, jobject this_obj) { +JNIEXPORT void JNICALL +Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0( + JNIEnv *env, jobject this_obj) +{ JNF_COCOA_ENTER(env); if (debug) printf("detach0 called\n"); @@ -419,10 +499,13 @@ * Method: load_library * Signature: (Ljava/lang/String;)L */ -JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_asm_Disassembler_load_1library(JNIEnv * env, - jclass disclass, - jstring jrepath_s, - jstring libname_s) { +JNIEXPORT jlong JNICALL +Java_sun_jvm_hotspot_asm_Disassembler_load_1library( + JNIEnv * env, + jclass disclass, + jstring jrepath_s, + jstring libname_s) +{ uintptr_t func = 0; const char* error_message = NULL; const char* java_home; @@ -533,13 +616,16 @@ * 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) { +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(env, code, &isCopy); jbyte* end = start + (*env)->GetArrayLength(env, code); diff -r 41d73c9b30a8 -r 3f11b37f047c agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java --- a/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java Fri Feb 08 16:31:48 2013 -0500 +++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java Fri Feb 08 13:55:41 2013 -0800 @@ -49,7 +49,7 @@ public BsdAddress readCompKlassAddress(long address) throws DebuggerException; public BsdOopHandle readOopHandle(long address) throws DebuggerException; public BsdOopHandle readCompOopHandle(long address) throws DebuggerException; - public long[] getThreadIntegerRegisterSet(int lwp_id) throws DebuggerException; + public long[] getThreadIntegerRegisterSet(long unique_thread_id) throws DebuggerException; public long getAddressValue(Address addr) throws DebuggerException; public Address newAddress(long value) throws DebuggerException; diff -r 41d73c9b30a8 -r 3f11b37f047c agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java --- a/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java Fri Feb 08 16:31:48 2013 -0500 +++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java Fri Feb 08 13:55:41 2013 -0800 @@ -90,7 +90,7 @@ throws DebuggerException; private native ClosestSymbol lookupByAddress0(long address) throws DebuggerException; - private native long[] getThreadIntegerRegisterSet0(int lwp_id) + private native long[] getThreadIntegerRegisterSet0(long unique_thread_id) throws DebuggerException; private native byte[] readBytesFromProcess0(long address, long numBytes) throws DebuggerException; @@ -400,10 +400,15 @@ // /** From the ThreadAccess interface via Debugger and JVMDebugger */ + public ThreadProxy getThreadForIdentifierAddress(Address threadIdAddr, Address uniqueThreadIdAddr) { + return new BsdThread(this, threadIdAddr, uniqueThreadIdAddr); + } + @Override public ThreadProxy getThreadForIdentifierAddress(Address addr) { - return new BsdThread(this, addr); + throw new RuntimeException("unimplemented"); } + /** From the ThreadAccess interface via Debugger and JVMDebugger */ public ThreadProxy getThreadForThreadId(long id) { return new BsdThread(this, id); @@ -455,22 +460,22 @@ // Thread context access // - public synchronized long[] getThreadIntegerRegisterSet(int lwp_id) + public synchronized long[] getThreadIntegerRegisterSet(long unique_thread_id) throws DebuggerException { requireAttach(); if (isCore) { - return getThreadIntegerRegisterSet0(lwp_id); + return getThreadIntegerRegisterSet0(unique_thread_id); } else { class GetThreadIntegerRegisterSetTask implements WorkerThreadTask { - int lwp_id; + long unique_thread_id; long[] result; public void doit(BsdDebuggerLocal debugger) { - result = debugger.getThreadIntegerRegisterSet0(lwp_id); + result = debugger.getThreadIntegerRegisterSet0(unique_thread_id); } } GetThreadIntegerRegisterSetTask task = new GetThreadIntegerRegisterSetTask(); - task.lwp_id = lwp_id; + task.unique_thread_id = unique_thread_id; workerThread.execute(task); return task.result; } diff -r 41d73c9b30a8 -r 3f11b37f047c agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java --- a/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java Fri Feb 08 16:31:48 2013 -0500 +++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java Fri Feb 08 13:55:41 2013 -0800 @@ -28,21 +28,23 @@ class BsdThread implements ThreadProxy { private BsdDebugger debugger; - private int lwp_id; + private int thread_id; + private long unique_thread_id; /** The address argument must be the address of the _thread_id in the OSThread. It's value is result ::gettid() call. */ - BsdThread(BsdDebugger debugger, Address addr) { + BsdThread(BsdDebugger debugger, Address threadIdAddr, Address uniqueThreadIdAddr) { this.debugger = debugger; // FIXME: size of data fetched here should be configurable. // However, making it so would produce a dependency on the "types" // package from the debugger package, which is not desired. - this.lwp_id = (int) addr.getCIntegerAt(0, 4, true); + this.thread_id = (int) threadIdAddr.getCIntegerAt(0, 4, true); + this.unique_thread_id = uniqueThreadIdAddr.getCIntegerAt(0, 8, true); } BsdThread(BsdDebugger debugger, long id) { this.debugger = debugger; - this.lwp_id = (int) id; + this.thread_id = (int) id; } public boolean equals(Object obj) { @@ -50,19 +52,19 @@ return false; } - return (((BsdThread) obj).lwp_id == lwp_id); + return (((BsdThread) obj).thread_id == thread_id); } public int hashCode() { - return lwp_id; + return thread_id; } public String toString() { - return Integer.toString(lwp_id); + return Integer.toString(thread_id); } public ThreadContext getContext() throws IllegalThreadStateException { - long[] data = debugger.getThreadIntegerRegisterSet(lwp_id); + long[] data = debugger.getThreadIntegerRegisterSet(unique_thread_id); ThreadContext context = BsdThreadContextFactory.createThreadContext(debugger); for (int i = 0; i < data.length; i++) { context.setRegister(i, data[i]); diff -r 41d73c9b30a8 -r 3f11b37f047c agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java Fri Feb 08 16:31:48 2013 -0500 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java Fri Feb 08 13:55:41 2013 -0800 @@ -28,6 +28,8 @@ import java.util.*; import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.debugger.amd64.*; +import sun.jvm.hotspot.debugger.bsd.BsdDebugger; +import sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal; import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.runtime.amd64.*; import sun.jvm.hotspot.runtime.x86.*; @@ -38,8 +40,9 @@ private static AddressField lastJavaFPField; private static AddressField osThreadField; - // Field from OSThread + // Fields from OSThread private static CIntegerField osThreadThreadIDField; + private static CIntegerField osThreadUniqueThreadIDField; // This is currently unneeded but is being kept in case we change // the currentFrameGuess algorithm @@ -61,7 +64,8 @@ lastJavaFPField = anchorType.getAddressField("_last_Java_fp"); Type osThreadType = db.lookupType("OSThread"); - osThreadThreadIDField = osThreadType.getCIntegerField("_thread_id"); + osThreadThreadIDField = osThreadType.getCIntegerField("_thread_id"); + osThreadUniqueThreadIDField = osThreadType.getCIntegerField("_unique_thread_id"); } public Address getLastJavaFP(Address addr) { @@ -125,8 +129,9 @@ Address osThreadAddr = osThreadField.getValue(addr); // Get the address of the _thread_id from the OSThread Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset()); + Address uniqueThreadIdAddr = osThreadAddr.addOffsetTo(osThreadUniqueThreadIDField.getOffset()); - JVMDebugger debugger = VM.getVM().getDebugger(); - return debugger.getThreadForIdentifierAddress(threadIdAddr); + BsdDebuggerLocal debugger = (BsdDebuggerLocal) VM.getVM().getDebugger(); + return debugger.getThreadForIdentifierAddress(threadIdAddr, uniqueThreadIdAddr); } } diff -r 41d73c9b30a8 -r 3f11b37f047c src/os/bsd/vm/osThread_bsd.hpp --- a/src/os/bsd/vm/osThread_bsd.hpp Fri Feb 08 16:31:48 2013 -0500 +++ b/src/os/bsd/vm/osThread_bsd.hpp Fri Feb 08 13:55:41 2013 -0800 @@ -49,6 +49,11 @@ // (e.g. pthread_kill). pthread_t _pthread_id; + // This is the "thread_id" from struct thread_identifier_info. According to a + // comment in thread_info.h, this is a "system-wide unique 64-bit thread id". + // The value is used by SA to correlate threads. + uint64_t _unique_thread_id; + sigset_t _caller_sigmask; // Caller's signal mask public: @@ -77,6 +82,10 @@ _pthread_id = tid; } + void set_unique_thread_id(uint64_t id) { + _unique_thread_id = id; + } + // *************************************************************** // suspension support. // *************************************************************** diff -r 41d73c9b30a8 -r 3f11b37f047c src/os/bsd/vm/os_bsd.cpp --- a/src/os/bsd/vm/os_bsd.cpp Fri Feb 08 16:31:48 2013 -0500 +++ b/src/os/bsd/vm/os_bsd.cpp Fri Feb 08 13:55:41 2013 -0800 @@ -657,6 +657,18 @@ objc_registerThreadWithCollector_t objc_registerThreadWithCollectorFunction = NULL; #endif +#ifdef __APPLE__ +static uint64_t locate_unique_thread_id() { + // Additional thread_id used to correlate threads in SA + thread_identifier_info_data_t m_ident_info; + mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT; + + thread_info(::mach_thread_self(), THREAD_IDENTIFIER_INFO, + (thread_info_t) &m_ident_info, &count); + return m_ident_info.thread_id; +} +#endif + // Thread start routine for all newly created threads static void *java_start(Thread *thread) { // Try to randomize the cache line index of hot stack frames. @@ -685,6 +697,7 @@ #ifdef __APPLE__ // thread_id is mach thread on macos osthread->set_thread_id(::mach_thread_self()); + osthread->set_unique_thread_id(locate_unique_thread_id()); #else // thread_id is pthread_id on BSD osthread->set_thread_id(::pthread_self()); @@ -847,6 +860,7 @@ // Store pthread info into the OSThread #ifdef __APPLE__ osthread->set_thread_id(::mach_thread_self()); + osthread->set_unique_thread_id(locate_unique_thread_id()); #else osthread->set_thread_id(::pthread_self()); #endif diff -r 41d73c9b30a8 -r 3f11b37f047c src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp --- a/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp Fri Feb 08 16:31:48 2013 -0500 +++ b/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp Fri Feb 08 13:55:41 2013 -0800 @@ -35,17 +35,16 @@ /* Threads (NOTE: incomplete) */ \ /******************************/ \ nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \ - nonstatic_field(OSThread, _pthread_id, pthread_t) + nonstatic_field(OSThread, _unique_thread_id, uint64_t) #define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \ \ /**********************/ \ - /* Posix Thread IDs */ \ + /* Thread IDs */ \ /**********************/ \ \ - declare_unsigned_integer_type(OSThread::thread_id_t) \ - declare_unsigned_integer_type(pthread_t) + declare_unsigned_integer_type(OSThread::thread_id_t) #define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)