--- a/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m Fri Feb 08 10:42:24 2013 +0100
+++ b/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m Fri Feb 08 14:05:36 2013 +0100
@@ -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);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java Fri Feb 08 10:42:24 2013 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java Fri Feb 08 14:05:36 2013 +0100
@@ -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;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java Fri Feb 08 10:42:24 2013 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java Fri Feb 08 14:05:36 2013 +0100
@@ -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;
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java Fri Feb 08 10:42:24 2013 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java Fri Feb 08 14:05:36 2013 +0100
@@ -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]);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java Fri Feb 08 10:42:24 2013 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java Fri Feb 08 14:05:36 2013 +0100
@@ -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);
}
}
--- a/hotspot/src/os/bsd/vm/osThread_bsd.hpp Fri Feb 08 10:42:24 2013 +0100
+++ b/hotspot/src/os/bsd/vm/osThread_bsd.hpp Fri Feb 08 14:05:36 2013 +0100
@@ -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.
// ***************************************************************
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Fri Feb 08 10:42:24 2013 +0100
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Fri Feb 08 14:05:36 2013 +0100
@@ -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
--- a/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp Fri Feb 08 10:42:24 2013 +0100
+++ b/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp Fri Feb 08 14:05:36 2013 +0100
@@ -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)