Mercurial > hg > truffle
annotate agent/src/os/bsd/MacosxDebuggerLocal.m @ 17716:cdb71841f4bc
6498581: ThreadInterruptTest3 produces wrong output on Windows
Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set.
Reviewed-by: acorn, kvn
Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author | minqi |
---|---|
date | Wed, 26 Feb 2014 15:20:41 -0800 |
parents | e4614b063fe1 |
children | f2294a37e723 |
rev | line source |
---|---|
4006 | 1 /* |
8750 | 2 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. |
4006 | 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 it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 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 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 * | |
23 */ | |
24 | |
25 #include <objc/objc-runtime.h> | |
26 #import <Foundation/Foundation.h> | |
27 #import <JavaNativeFoundation/JavaNativeFoundation.h> | |
28 | |
29 #include <JavaVM/jni.h> | |
30 | |
31 #import <mach/mach.h> | |
32 #import <mach/mach_types.h> | |
33 #import <sys/sysctl.h> | |
6782 | 34 #import <stdio.h> |
35 #import <stdarg.h> | |
4006 | 36 #import <stdlib.h> |
6782 | 37 #import <strings.h> |
38 #import <dlfcn.h> | |
39 #import <limits.h> | |
40 #import <errno.h> | |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
41 #import <sys/types.h> |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
42 #import <sys/ptrace.h> |
8750 | 43 #include "libproc_impl.h" |
4006 | 44 |
8750 | 45 #define UNSUPPORTED_ARCH "Unsupported architecture!" |
46 | |
47 #if defined(x86_64) && !defined(amd64) | |
48 #define amd64 1 | |
49 #endif | |
50 | |
51 #if amd64 | |
52 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h" | |
53 #else | |
54 #error UNSUPPORTED_ARCH | |
55 #endif | |
4006 | 56 |
57 static jfieldID symbolicatorID = 0; // set in _init0 | |
58 static jfieldID taskID = 0; // set in _init0 | |
59 | |
8750 | 60 static jfieldID p_ps_prochandle_ID = 0; |
61 static jfieldID loadObjectList_ID = 0; | |
62 static jmethodID listAdd_ID = 0; | |
63 | |
64 static jmethodID createClosestSymbol_ID = 0; | |
65 static jmethodID createLoadObject_ID = 0; | |
66 static jmethodID getJavaThreadsInfo_ID = 0; | |
67 | |
68 // indicator if thread id (lwpid_t) was set | |
69 static bool _threads_filled = false; | |
70 | |
4006 | 71 static void putSymbolicator(JNIEnv *env, jobject this_obj, id symbolicator) { |
72 (*env)->SetLongField(env, this_obj, symbolicatorID, (jlong)(intptr_t)symbolicator); | |
73 } | |
74 | |
75 static id getSymbolicator(JNIEnv *env, jobject this_obj) { | |
76 jlong ptr = (*env)->GetLongField(env, this_obj, symbolicatorID); | |
77 return (id)(intptr_t)ptr; | |
78 } | |
79 | |
80 static void putTask(JNIEnv *env, jobject this_obj, task_t task) { | |
81 (*env)->SetLongField(env, this_obj, taskID, (jlong)task); | |
82 } | |
83 | |
84 static task_t getTask(JNIEnv *env, jobject this_obj) { | |
85 jlong ptr = (*env)->GetLongField(env, this_obj, taskID); | |
86 return (task_t)ptr; | |
87 } | |
88 | |
89 #define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; } | |
90 #define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;} | |
91 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; } | |
92 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;} | |
6782 | 93 #define CHECK_EXCEPTION_CLEAR if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); } |
94 #define CHECK_EXCEPTION_CLEAR_VOID if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); return; } | |
95 #define CHECK_EXCEPTION_CLEAR_(value) if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); return value; } | |
4006 | 96 |
97 static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) { | |
98 (*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg); | |
99 } | |
100 | |
8750 | 101 static struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) { |
102 jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID); | |
103 return (struct ps_prochandle*)(intptr_t)ptr; | |
104 } | |
105 | |
4006 | 106 #if defined(__i386__) |
107 #define hsdb_thread_state_t x86_thread_state32_t | |
108 #define hsdb_float_state_t x86_float_state32_t | |
109 #define HSDB_THREAD_STATE x86_THREAD_STATE32 | |
110 #define HSDB_FLOAT_STATE x86_FLOAT_STATE32 | |
111 #define HSDB_THREAD_STATE_COUNT x86_THREAD_STATE32_COUNT | |
112 #define HSDB_FLOAT_STATE_COUNT x86_FLOAT_STATE32_COUNT | |
113 #elif defined(__x86_64__) | |
114 #define hsdb_thread_state_t x86_thread_state64_t | |
115 #define hsdb_float_state_t x86_float_state64_t | |
116 #define HSDB_THREAD_STATE x86_THREAD_STATE64 | |
117 #define HSDB_FLOAT_STATE x86_FLOAT_STATE64 | |
118 #define HSDB_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT | |
119 #define HSDB_FLOAT_STATE_COUNT x86_FLOAT_STATE64_COUNT | |
120 #else | |
8750 | 121 #error UNSUPPORTED_ARCH |
4006 | 122 #endif |
123 | |
124 /* | |
125 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal | |
126 * Method: init0 | |
127 * Signature: ()V | |
128 */ | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
129 JNIEXPORT void JNICALL |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
130 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0(JNIEnv *env, jclass cls) { |
4006 | 131 symbolicatorID = (*env)->GetFieldID(env, cls, "symbolicator", "J"); |
132 taskID = (*env)->GetFieldID(env, cls, "task", "J"); | |
133 CHECK_EXCEPTION; | |
8750 | 134 |
135 // for core file | |
136 p_ps_prochandle_ID = (*env)->GetFieldID(env, cls, "p_ps_prochandle", "J"); | |
137 CHECK_EXCEPTION; | |
138 loadObjectList_ID = (*env)->GetFieldID(env, cls, "loadObjectList", "Ljava/util/List;"); | |
139 CHECK_EXCEPTION; | |
140 | |
141 // methods we use | |
142 createClosestSymbol_ID = (*env)->GetMethodID(env, cls, "createClosestSymbol", | |
143 "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;"); | |
144 CHECK_EXCEPTION; | |
145 createLoadObject_ID = (*env)->GetMethodID(env, cls, "createLoadObject", | |
146 "(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;"); | |
147 CHECK_EXCEPTION; | |
148 | |
149 // java.util.List method we call | |
150 jclass listClass = (*env)->FindClass(env, "java/util/List"); | |
151 CHECK_EXCEPTION; | |
152 listAdd_ID = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z"); | |
153 CHECK_EXCEPTION; | |
154 getJavaThreadsInfo_ID = (*env)->GetMethodID(env, cls, "getJavaThreadsInfo", | |
155 "()[J"); | |
156 CHECK_EXCEPTION; | |
157 | |
158 init_libproc(getenv("LIBSAPROC_DEBUG") != NULL); | |
159 } | |
160 | |
161 JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize | |
162 (JNIEnv *env, jclass cls) | |
163 { | |
164 #ifdef _LP64 | |
165 return 8; | |
166 #else | |
167 #error UNSUPPORTED_ARCH | |
168 #endif | |
169 } | |
170 | |
171 /** called by Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0 */ | |
172 jlong lookupByNameIncore( | |
173 JNIEnv *env, struct ps_prochandle *ph, jobject this_obj, jstring objectName, jstring symbolName) | |
174 { | |
175 const char *objectName_cstr, *symbolName_cstr; | |
176 jlong addr; | |
177 jboolean isCopy; | |
178 objectName_cstr = NULL; | |
179 if (objectName != NULL) { | |
180 objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy); | |
181 CHECK_EXCEPTION_(0); | |
182 } | |
183 symbolName_cstr = (*env)->GetStringUTFChars(env, symbolName, &isCopy); | |
184 CHECK_EXCEPTION_(0); | |
185 | |
186 print_debug("look for %s \n", symbolName_cstr); | |
187 addr = (jlong) lookup_symbol(ph, objectName_cstr, symbolName_cstr); | |
188 | |
189 if (objectName_cstr != NULL) { | |
190 (*env)->ReleaseStringUTFChars(env, objectName, objectName_cstr); | |
191 } | |
192 (*env)->ReleaseStringUTFChars(env, symbolName, symbolName_cstr); | |
193 return addr; | |
4006 | 194 } |
195 | |
196 /* | |
197 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal | |
198 * Method: lookupByName0 | |
199 * Signature: (Ljava/lang/String;Ljava/lang/String;)J | |
200 */ | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
201 JNIEXPORT jlong JNICALL |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
202 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0( |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
203 JNIEnv *env, jobject this_obj, |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
204 jstring objectName, jstring symbolName) |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
205 { |
8750 | 206 struct ps_prochandle* ph = get_proc_handle(env, this_obj); |
10158
9f96b7a853bc
8013466: SA crashes when attaching to a process on OS X
sla
parents:
8750
diff
changeset
|
207 if (ph != NULL && ph->core != NULL) { |
8750 | 208 return lookupByNameIncore(env, ph, this_obj, objectName, symbolName); |
209 } | |
210 | |
4006 | 211 jlong address = 0; |
212 | |
213 JNF_COCOA_ENTER(env); | |
214 NSString *symbolNameString = JNFJavaToNSString(env, symbolName); | |
215 | |
8750 | 216 print_debug("lookupInProcess called for %s\n", [symbolNameString UTF8String]); |
4006 | 217 |
218 id symbolicator = getSymbolicator(env, this_obj); | |
219 if (symbolicator != nil) { | |
220 uint64_t (*dynamicCall)(id, SEL, NSString *) = (uint64_t (*)(id, SEL, NSString *))&objc_msgSend; | |
221 address = (jlong) dynamicCall(symbolicator, @selector(addressForSymbol:), symbolNameString); | |
222 } | |
223 | |
8750 | 224 print_debug("address of symbol %s = %llx\n", [symbolNameString UTF8String], address); |
4006 | 225 JNF_COCOA_EXIT(env); |
226 | |
227 return address; | |
228 } | |
229 | |
230 /* | |
231 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal | |
8750 | 232 * Method: lookupByAddress0 |
233 * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol; | |
234 */ | |
235 JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0 | |
236 (JNIEnv *env, jobject this_obj, jlong addr) { | |
237 uintptr_t offset; | |
238 const char* sym = NULL; | |
239 | |
240 struct ps_prochandle* ph = get_proc_handle(env, this_obj); | |
10158
9f96b7a853bc
8013466: SA crashes when attaching to a process on OS X
sla
parents:
8750
diff
changeset
|
241 if (ph != NULL && ph->core != NULL) { |
9f96b7a853bc
8013466: SA crashes when attaching to a process on OS X
sla
parents:
8750
diff
changeset
|
242 sym = symbol_for_pc(ph, (uintptr_t) addr, &offset); |
9f96b7a853bc
8013466: SA crashes when attaching to a process on OS X
sla
parents:
8750
diff
changeset
|
243 if (sym == NULL) return 0; |
9f96b7a853bc
8013466: SA crashes when attaching to a process on OS X
sla
parents:
8750
diff
changeset
|
244 return (*env)->CallObjectMethod(env, this_obj, createClosestSymbol_ID, |
8750 | 245 (*env)->NewStringUTF(env, sym), (jlong)offset); |
10158
9f96b7a853bc
8013466: SA crashes when attaching to a process on OS X
sla
parents:
8750
diff
changeset
|
246 } |
9f96b7a853bc
8013466: SA crashes when attaching to a process on OS X
sla
parents:
8750
diff
changeset
|
247 return 0; |
8750 | 248 } |
249 | |
250 /** called from Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0 */ | |
251 jbyteArray readBytesFromCore( | |
252 JNIEnv *env, struct ps_prochandle *ph, jobject this_obj, jlong addr, jlong numBytes) | |
253 { | |
254 jboolean isCopy; | |
255 jbyteArray array; | |
256 jbyte *bufPtr; | |
257 ps_err_e err; | |
258 | |
259 array = (*env)->NewByteArray(env, numBytes); | |
260 CHECK_EXCEPTION_(0); | |
261 bufPtr = (*env)->GetByteArrayElements(env, array, &isCopy); | |
262 CHECK_EXCEPTION_(0); | |
263 | |
264 err = ps_pread(ph, (psaddr_t) (uintptr_t)addr, bufPtr, numBytes); | |
265 (*env)->ReleaseByteArrayElements(env, array, bufPtr, 0); | |
266 return (err == PS_OK)? array : 0; | |
267 } | |
268 | |
269 /* | |
270 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal | |
4006 | 271 * Method: readBytesFromProcess0 |
272 * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult; | |
273 */ | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
274 JNIEXPORT jbyteArray JNICALL |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
275 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0( |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
276 JNIEnv *env, jobject this_obj, |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
277 jlong addr, jlong numBytes) |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
278 { |
8750 | 279 print_debug("readBytesFromProcess called. addr = %llx numBytes = %lld\n", addr, numBytes); |
4006 | 280 |
281 // must allocate storage instead of using former parameter buf | |
282 jbyteArray array; | |
8750 | 283 |
284 struct ps_prochandle* ph = get_proc_handle(env, this_obj); | |
10158
9f96b7a853bc
8013466: SA crashes when attaching to a process on OS X
sla
parents:
8750
diff
changeset
|
285 if (ph != NULL && ph->core != NULL) { |
8750 | 286 return readBytesFromCore(env, ph, this_obj, addr, numBytes); |
287 } | |
4006 | 288 |
289 array = (*env)->NewByteArray(env, numBytes); | |
290 CHECK_EXCEPTION_(0); | |
291 | |
292 unsigned long alignedAddress; | |
8688
40b7c6b800ab
8008327: [parfait] Unitialized variable in hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m
morris
parents:
8062
diff
changeset
|
293 unsigned long alignedLength = 0; |
4006 | 294 kern_return_t result; |
295 vm_offset_t *pages; | |
296 int *mapped; | |
297 long pageCount; | |
298 uint byteCount; | |
299 int i; | |
300 unsigned long remaining; | |
301 | |
302 alignedAddress = trunc_page(addr); | |
303 if (addr != alignedAddress) { | |
304 alignedLength += addr - alignedAddress; | |
305 } | |
306 alignedLength = round_page(numBytes); | |
307 pageCount = alignedLength/vm_page_size; | |
308 | |
309 // Allocate storage for pages and flags. | |
310 pages = malloc(pageCount * sizeof(vm_offset_t)); | |
311 mapped = calloc(pageCount, sizeof(int)); | |
312 | |
313 task_t gTask = getTask(env, this_obj); | |
314 // Try to read each of the pages. | |
315 for (i = 0; i < pageCount; i++) { | |
316 result = vm_read(gTask, alignedAddress + i*vm_page_size, vm_page_size, | |
317 &pages[i], &byteCount); | |
318 mapped[i] = (result == KERN_SUCCESS); | |
319 // assume all failures are unmapped pages | |
320 } | |
321 | |
8750 | 322 print_debug("%ld pages\n", pageCount); |
4006 | 323 |
324 remaining = numBytes; | |
325 | |
326 for (i = 0; i < pageCount; i++) { | |
327 unsigned long len = vm_page_size; | |
328 unsigned long start = 0; | |
329 | |
330 if (i == 0) { | |
331 start = addr - alignedAddress; | |
332 len = vm_page_size - start; | |
333 } | |
334 | |
335 if (i == (pageCount - 1)) { | |
336 len = remaining; | |
337 } | |
338 | |
339 if (mapped[i]) { | |
8750 | 340 print_debug("page %d mapped (len %ld start %ld)\n", i, len, start); |
4006 | 341 (*env)->SetByteArrayRegion(env, array, 0, len, ((jbyte *) pages[i] + start)); |
342 vm_deallocate(mach_task_self(), pages[i], vm_page_size); | |
343 } | |
344 | |
345 remaining -= len; | |
346 } | |
347 | |
348 free (pages); | |
349 free (mapped); | |
350 return array; | |
351 } | |
352 | |
8750 | 353 /** Only used for core file reading, set thread_id for threads which is got after core file parsed. |
354 * Thread context is available in Mach-O core file but thread id is not. We can get thread id | |
355 * from Threads which store all java threads information when they are created. Here we can identify | |
356 * them as java threads by checking if a thread's rsp or rbp within a java thread's stack. | |
357 * Note Macosx uses unique_thread_id which is different from other platforms though printed ids | |
358 * are still pthread id. Function BsdDebuggerLocal.getJavaThreadsInfo returns an array of long | |
359 * integers to host all java threads' id, stack_start, stack_end as: | |
360 * [uid0, stack_start0, stack_end0, uid1, stack_start1, stack_end1, ...] | |
361 * | |
362 * The work cannot be done at init0 since Threads is not available yet(VM not initialized yet). | |
363 * This function should be called only once if succeeded | |
364 */ | |
365 bool fill_java_threads(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) { | |
366 int n = 0, i = 0, j; | |
367 struct reg regs; | |
368 | |
369 jlongArray thrinfos = (*env)->CallObjectMethod(env, this_obj, getJavaThreadsInfo_ID); | |
370 CHECK_EXCEPTION_(false); | |
371 int len = (int)(*env)->GetArrayLength(env, thrinfos); | |
372 uint64_t* cinfos = (uint64_t *)(*env)->GetLongArrayElements(env, thrinfos, NULL); | |
373 CHECK_EXCEPTION_(false); | |
374 n = get_num_threads(ph); | |
375 print_debug("fill_java_threads called, num_of_thread = %d\n", n); | |
376 for (i = 0; i < n; i++) { | |
377 if (!get_nth_lwp_regs(ph, i, ®s)) { | |
378 print_debug("Could not get regs of thread %d, already set!\n", i); | |
379 return false; | |
380 } | |
381 for (j = 0; j < len; j += 3) { | |
382 lwpid_t uid = cinfos[j]; | |
383 uint64_t beg = cinfos[j + 1]; | |
384 uint64_t end = cinfos[j + 2]; | |
385 if ((regs.r_rsp < end && regs.r_rsp >= beg) || | |
386 (regs.r_rbp < end && regs.r_rbp >= beg)) { | |
387 set_lwp_id(ph, i, uid); | |
388 break; | |
389 } | |
390 } | |
391 } | |
392 (*env)->ReleaseLongArrayElements(env, thrinfos, (jlong*)cinfos, 0); | |
393 CHECK_EXCEPTION_(false); | |
394 return true; | |
395 } | |
396 | |
397 /* For core file only, called from | |
398 * Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0 | |
399 */ | |
10158
9f96b7a853bc
8013466: SA crashes when attaching to a process on OS X
sla
parents:
8750
diff
changeset
|
400 jlongArray getThreadIntegerRegisterSetFromCore(JNIEnv *env, jobject this_obj, long lwp_id, struct ps_prochandle* ph) { |
8750 | 401 if (!_threads_filled) { |
10158
9f96b7a853bc
8013466: SA crashes when attaching to a process on OS X
sla
parents:
8750
diff
changeset
|
402 if (!fill_java_threads(env, this_obj, ph)) { |
8750 | 403 throw_new_debugger_exception(env, "Failed to fill in threads"); |
404 return 0; | |
405 } else { | |
406 _threads_filled = true; | |
407 } | |
408 } | |
409 | |
410 struct reg gregs; | |
411 jboolean isCopy; | |
412 jlongArray array; | |
413 jlong *regs; | |
414 | |
415 if (get_lwp_regs(ph, lwp_id, &gregs) != true) { | |
416 THROW_NEW_DEBUGGER_EXCEPTION_("get_thread_regs failed for a lwp", 0); | |
417 } | |
418 | |
419 #undef NPRGREG | |
420 #undef REG_INDEX | |
421 #if amd64 | |
422 #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG | |
423 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg | |
424 | |
425 array = (*env)->NewLongArray(env, NPRGREG); | |
426 CHECK_EXCEPTION_(0); | |
427 regs = (*env)->GetLongArrayElements(env, array, &isCopy); | |
428 | |
429 regs[REG_INDEX(R15)] = gregs.r_r15; | |
430 regs[REG_INDEX(R14)] = gregs.r_r14; | |
431 regs[REG_INDEX(R13)] = gregs.r_r13; | |
432 regs[REG_INDEX(R12)] = gregs.r_r12; | |
433 regs[REG_INDEX(RBP)] = gregs.r_rbp; | |
434 regs[REG_INDEX(RBX)] = gregs.r_rbx; | |
435 regs[REG_INDEX(R11)] = gregs.r_r11; | |
436 regs[REG_INDEX(R10)] = gregs.r_r10; | |
437 regs[REG_INDEX(R9)] = gregs.r_r9; | |
438 regs[REG_INDEX(R8)] = gregs.r_r8; | |
439 regs[REG_INDEX(RAX)] = gregs.r_rax; | |
440 regs[REG_INDEX(RCX)] = gregs.r_rcx; | |
441 regs[REG_INDEX(RDX)] = gregs.r_rdx; | |
442 regs[REG_INDEX(RSI)] = gregs.r_rsi; | |
443 regs[REG_INDEX(RDI)] = gregs.r_rdi; | |
444 regs[REG_INDEX(RIP)] = gregs.r_rip; | |
445 regs[REG_INDEX(CS)] = gregs.r_cs; | |
446 regs[REG_INDEX(RSP)] = gregs.r_rsp; | |
447 regs[REG_INDEX(SS)] = gregs.r_ss; | |
448 regs[REG_INDEX(FSBASE)] = 0; | |
449 regs[REG_INDEX(GSBASE)] = 0; | |
450 regs[REG_INDEX(DS)] = gregs.r_ds; | |
451 regs[REG_INDEX(ES)] = gregs.r_es; | |
452 regs[REG_INDEX(FS)] = gregs.r_fs; | |
453 regs[REG_INDEX(GS)] = gregs.r_gs; | |
454 regs[REG_INDEX(TRAPNO)] = gregs.r_trapno; | |
455 regs[REG_INDEX(RFL)] = gregs.r_rflags; | |
456 | |
457 #endif /* amd64 */ | |
458 (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT); | |
459 return array; | |
460 } | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
461 |
4006 | 462 /* |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
463 * Lookup the thread_t that corresponds to the given thread_id. |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
464 * The thread_id should be the result from calling thread_info() with THREAD_IDENTIFIER_INFO |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
465 * and reading the m_ident_info.thread_id returned. |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
466 * The returned thread_t is the mach send right to the kernel port for the corresponding thread. |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
467 * |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
468 * We cannot simply use the OSThread._thread_id field in the JVM. This is set to ::mach_thread_self() |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
469 * in the VM, but that thread port is not valid for a remote debugger to access the thread. |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
470 */ |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
471 thread_t |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
472 lookupThreadFromThreadId(task_t task, jlong thread_id) { |
8750 | 473 print_debug("lookupThreadFromThreadId thread_id=0x%llx\n", thread_id); |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
474 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
475 thread_array_t thread_list = NULL; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
476 mach_msg_type_number_t thread_list_count = 0; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
477 thread_t result_thread = 0; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
478 int i; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
479 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
480 // get the list of all the send rights |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
481 kern_return_t result = task_threads(task, &thread_list, &thread_list_count); |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
482 if (result != KERN_SUCCESS) { |
8750 | 483 print_debug("task_threads returned 0x%x\n", result); |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
484 return 0; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
485 } |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
486 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
487 for(i = 0 ; i < thread_list_count; i++) { |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
488 thread_identifier_info_data_t m_ident_info; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
489 mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
490 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
491 // get the THREAD_IDENTIFIER_INFO for the send right |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
492 result = thread_info(thread_list[i], THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count); |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
493 if (result != KERN_SUCCESS) { |
8750 | 494 print_debug("thread_info returned 0x%x\n", result); |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
495 break; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
496 } |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
497 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
498 // if this is the one we're looking for, return the send right |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
499 if (thread_id == m_ident_info.thread_id) |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
500 { |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
501 result_thread = thread_list[i]; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
502 break; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
503 } |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
504 } |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
505 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
506 vm_size_t thread_list_size = (vm_size_t) (thread_list_count * sizeof (thread_t)); |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
507 vm_deallocate(mach_task_self(), (vm_address_t) thread_list, thread_list_count); |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
508 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
509 return result_thread; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
510 } |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
511 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
512 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
513 /* |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
514 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal |
4006 | 515 * Method: getThreadIntegerRegisterSet0 |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
516 * Signature: (J)[J |
4006 | 517 */ |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
518 JNIEXPORT jlongArray JNICALL |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
519 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0( |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
520 JNIEnv *env, jobject this_obj, |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
521 jlong thread_id) |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
522 { |
8750 | 523 print_debug("getThreadRegisterSet0 called\n"); |
524 | |
525 struct ps_prochandle* ph = get_proc_handle(env, this_obj); | |
10158
9f96b7a853bc
8013466: SA crashes when attaching to a process on OS X
sla
parents:
8750
diff
changeset
|
526 if (ph != NULL && ph->core != NULL) { |
9f96b7a853bc
8013466: SA crashes when attaching to a process on OS X
sla
parents:
8750
diff
changeset
|
527 return getThreadIntegerRegisterSetFromCore(env, this_obj, thread_id, ph); |
8750 | 528 } |
4006 | 529 |
530 kern_return_t result; | |
531 thread_t tid; | |
532 mach_msg_type_number_t count = HSDB_THREAD_STATE_COUNT; | |
533 hsdb_thread_state_t state; | |
534 jlongArray registerArray; | |
535 jlong *primitiveArray; | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
536 task_t gTask = getTask(env, this_obj); |
4006 | 537 |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
538 tid = lookupThreadFromThreadId(gTask, thread_id); |
4006 | 539 |
540 result = thread_get_state(tid, HSDB_THREAD_STATE, (thread_state_t)&state, &count); | |
541 | |
542 if (result != KERN_SUCCESS) { | |
8750 | 543 print_error("getregs: thread_get_state(%d) failed (%d)\n", tid, result); |
4006 | 544 return NULL; |
545 } | |
546 | |
8750 | 547 #if amd64 |
548 #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG | |
549 #undef REG_INDEX | |
550 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg | |
551 | |
552 // 64 bit | |
553 print_debug("Getting threads for a 64-bit process\n"); | |
554 registerArray = (*env)->NewLongArray(env, NPRGREG); | |
555 CHECK_EXCEPTION_(0); | |
556 primitiveArray = (*env)->GetLongArrayElements(env, registerArray, NULL); | |
4006 | 557 |
8750 | 558 primitiveArray[REG_INDEX(R15)] = state.__r15; |
559 primitiveArray[REG_INDEX(R14)] = state.__r14; | |
560 primitiveArray[REG_INDEX(R13)] = state.__r13; | |
561 primitiveArray[REG_INDEX(R12)] = state.__r12; | |
562 primitiveArray[REG_INDEX(R11)] = state.__r11; | |
563 primitiveArray[REG_INDEX(R10)] = state.__r10; | |
564 primitiveArray[REG_INDEX(R9)] = state.__r9; | |
565 primitiveArray[REG_INDEX(R8)] = state.__r8; | |
566 primitiveArray[REG_INDEX(RDI)] = state.__rdi; | |
567 primitiveArray[REG_INDEX(RSI)] = state.__rsi; | |
568 primitiveArray[REG_INDEX(RBP)] = state.__rbp; | |
569 primitiveArray[REG_INDEX(RBX)] = state.__rbx; | |
570 primitiveArray[REG_INDEX(RDX)] = state.__rdx; | |
571 primitiveArray[REG_INDEX(RCX)] = state.__rcx; | |
572 primitiveArray[REG_INDEX(RAX)] = state.__rax; | |
573 primitiveArray[REG_INDEX(TRAPNO)] = 0; // trapno, not used | |
574 primitiveArray[REG_INDEX(ERR)] = 0; // err, not used | |
575 primitiveArray[REG_INDEX(RIP)] = state.__rip; | |
576 primitiveArray[REG_INDEX(CS)] = state.__cs; | |
577 primitiveArray[REG_INDEX(RFL)] = state.__rflags; | |
578 primitiveArray[REG_INDEX(RSP)] = state.__rsp; | |
579 primitiveArray[REG_INDEX(SS)] = 0; // We don't have SS | |
580 primitiveArray[REG_INDEX(FS)] = state.__fs; | |
581 primitiveArray[REG_INDEX(GS)] = state.__gs; | |
582 primitiveArray[REG_INDEX(ES)] = 0; | |
583 primitiveArray[REG_INDEX(DS)] = 0; | |
584 primitiveArray[REG_INDEX(FSBASE)] = 0; | |
585 primitiveArray[REG_INDEX(GSBASE)] = 0; | |
586 print_debug("set registers\n"); | |
4006 | 587 |
8750 | 588 (*env)->ReleaseLongArrayElements(env, registerArray, primitiveArray, 0); |
4006 | 589 |
590 #else | |
8750 | 591 #error UNSUPPORTED_ARCH |
592 #endif /* amd64 */ | |
4006 | 593 |
594 return registerArray; | |
595 } | |
596 | |
597 /* | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
598 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal |
4006 | 599 * Method: translateTID0 |
600 * Signature: (I)I | |
601 */ | |
602 JNIEXPORT jint JNICALL | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
603 Java_sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal_translateTID0( |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
604 JNIEnv *env, jobject this_obj, jint tid) |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
605 { |
8750 | 606 print_debug("translateTID0 called on tid = 0x%x\n", (int)tid); |
4006 | 607 |
608 kern_return_t result; | |
609 thread_t foreign_tid, usable_tid; | |
610 mach_msg_type_name_t type; | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
611 |
4006 | 612 foreign_tid = tid; |
613 | |
614 task_t gTask = getTask(env, this_obj); | |
615 result = mach_port_extract_right(gTask, foreign_tid, | |
616 MACH_MSG_TYPE_COPY_SEND, | |
617 &usable_tid, &type); | |
618 if (result != KERN_SUCCESS) | |
619 return -1; | |
620 | |
8750 | 621 print_debug("translateTID0: 0x%x -> 0x%x\n", foreign_tid, usable_tid); |
4006 | 622 |
623 return (jint) usable_tid; | |
624 } | |
625 | |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
626 |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
627 static bool ptrace_continue(pid_t pid, int signal) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
628 // pass the signal to the process so we don't swallow it |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
629 int res; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
630 if ((res = ptrace(PT_CONTINUE, pid, (caddr_t)1, signal)) < 0) { |
8750 | 631 print_error("attach: ptrace(PT_CONTINUE, %d) failed with %d\n", pid, res); |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
632 return false; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
633 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
634 return true; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
635 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
636 |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
637 // waits until the ATTACH has stopped the process |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
638 // by signal SIGSTOP |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
639 static bool ptrace_waitpid(pid_t pid) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
640 int ret; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
641 int status; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
642 while (true) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
643 // Wait for debuggee to stop. |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
644 ret = waitpid(pid, &status, 0); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
645 if (ret >= 0) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
646 if (WIFSTOPPED(status)) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
647 // Any signal will stop the thread, make sure it is SIGSTOP. Otherwise SIGSTOP |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
648 // will still be pending and delivered when the process is DETACHED and the process |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
649 // will go to sleep. |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
650 if (WSTOPSIG(status) == SIGSTOP) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
651 // Debuggee stopped by SIGSTOP. |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
652 return true; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
653 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
654 if (!ptrace_continue(pid, WSTOPSIG(status))) { |
8750 | 655 print_error("attach: Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status)); |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
656 return false; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
657 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
658 } else { |
8750 | 659 print_error("attach: waitpid(): Child process exited/terminated (status = 0x%x)\n", status); |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
660 return false; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
661 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
662 } else { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
663 switch (errno) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
664 case EINTR: |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
665 continue; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
666 break; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
667 case ECHILD: |
8750 | 668 print_error("attach: waitpid() failed. Child process pid (%d) does not exist \n", pid); |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
669 break; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
670 case EINVAL: |
8750 | 671 print_error("attach: waitpid() failed. Invalid options argument.\n"); |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
672 break; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
673 default: |
8750 | 674 print_error("attach: waitpid() failed. Unexpected error %d\n",errno); |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
675 break; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
676 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
677 return false; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
678 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
679 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
680 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
681 |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
682 // attach to a process/thread specified by "pid" |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
683 static bool ptrace_attach(pid_t pid) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
684 int res; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
685 if ((res = ptrace(PT_ATTACH, pid, 0, 0)) < 0) { |
8750 | 686 print_error("ptrace(PT_ATTACH, %d) failed with %d\n", pid, res); |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
687 return false; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
688 } else { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
689 return ptrace_waitpid(pid); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
690 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
691 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
692 |
4006 | 693 /* |
694 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal | |
695 * Method: attach0 | |
696 * Signature: (I)V | |
697 */ | |
8750 | 698 JNIEXPORT void JNICALL |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
699 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I( |
8750 | 700 JNIEnv *env, jobject this_obj, jint jpid) |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
701 { |
8750 | 702 print_debug("attach0 called for jpid=%d\n", (int)jpid); |
703 | |
4006 | 704 JNF_COCOA_ENTER(env); |
8750 | 705 |
4006 | 706 kern_return_t result; |
707 task_t gTask = 0; | |
708 result = task_for_pid(mach_task_self(), jpid, &gTask); | |
709 if (result != KERN_SUCCESS) { | |
10162
e4614b063fe1
8013364: SA-JDI exceptions caused by lack of permissions on OSX should be more verbose about issue cause
sla
parents:
10158
diff
changeset
|
710 print_error("attach: task_for_pid(%d) failed: '%s' (%d)\n", (int)jpid, mach_error_string(result), result); |
e4614b063fe1
8013364: SA-JDI exceptions caused by lack of permissions on OSX should be more verbose about issue cause
sla
parents:
10158
diff
changeset
|
711 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process. Could be caused by an incorrect pid or lack of privileges."); |
4006 | 712 } |
713 putTask(env, this_obj, gTask); | |
714 | |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
715 // use ptrace to stop the process |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
716 // on os x, ptrace only needs to be called on the process, not the individual threads |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
717 if (ptrace_attach(jpid) != true) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
718 mach_port_deallocate(mach_task_self(), gTask); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
719 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process"); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
720 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
721 |
4006 | 722 id symbolicator = nil; |
723 id jrsSymbolicator = objc_lookUpClass("JRSSymbolicator"); | |
724 if (jrsSymbolicator != nil) { | |
725 id (*dynamicCall)(id, SEL, pid_t) = (id (*)(id, SEL, pid_t))&objc_msgSend; | |
726 symbolicator = dynamicCall(jrsSymbolicator, @selector(symbolicatorForPid:), (pid_t)jpid); | |
727 } | |
728 if (symbolicator != nil) { | |
729 CFRetain(symbolicator); // pin symbolicator while in java heap | |
730 } | |
731 | |
732 putSymbolicator(env, this_obj, symbolicator); | |
733 if (symbolicator == nil) { | |
734 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach symbolicator to the process"); | |
735 } | |
736 | |
737 JNF_COCOA_EXIT(env); | |
738 } | |
739 | |
8750 | 740 /** For core file, |
741 called from Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2 */ | |
742 static void fillLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) { | |
743 int n = 0, i = 0; | |
744 | |
745 // add load objects | |
746 n = get_num_libs(ph); | |
747 for (i = 0; i < n; i++) { | |
748 uintptr_t base; | |
749 const char* name; | |
750 jobject loadObject; | |
751 jobject loadObjectList; | |
752 | |
753 base = get_lib_base(ph, i); | |
754 name = get_lib_name(ph, i); | |
755 loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID, | |
756 (*env)->NewStringUTF(env, name), (jlong)0, (jlong)base); | |
757 CHECK_EXCEPTION; | |
758 loadObjectList = (*env)->GetObjectField(env, this_obj, loadObjectList_ID); | |
759 CHECK_EXCEPTION; | |
760 (*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject); | |
761 CHECK_EXCEPTION; | |
762 } | |
763 } | |
764 | |
765 /* | |
766 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal | |
767 * Method: attach0 | |
768 * Signature: (Ljava/lang/String;Ljava/lang/String;)V | |
769 */ | |
770 JNIEXPORT void JNICALL | |
771 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2( | |
772 JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) | |
773 { | |
774 const char *execName_cstr; | |
775 const char *coreName_cstr; | |
776 jboolean isCopy; | |
777 struct ps_prochandle* ph; | |
778 | |
779 execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy); | |
780 CHECK_EXCEPTION; | |
781 coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy); | |
782 CHECK_EXCEPTION; | |
783 | |
784 print_debug("attach: %s %s\n", execName_cstr, coreName_cstr); | |
785 | |
786 if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) { | |
787 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr); | |
788 (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr); | |
789 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file"); | |
790 } | |
791 (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph); | |
792 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr); | |
793 (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr); | |
794 fillLoadObjects(env, this_obj, ph); | |
795 } | |
796 | |
4006 | 797 /* |
798 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal | |
799 * Method: detach0 | |
800 * Signature: ()V | |
801 */ | |
8750 | 802 JNIEXPORT void JNICALL |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
803 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0( |
8750 | 804 JNIEnv *env, jobject this_obj) |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
805 { |
8750 | 806 print_debug("detach0 called\n"); |
807 struct ps_prochandle* ph = get_proc_handle(env, this_obj); | |
808 if (ph != NULL && ph->core != NULL) { | |
809 Prelease(ph); | |
810 return; | |
811 } | |
4006 | 812 JNF_COCOA_ENTER(env); |
813 task_t gTask = getTask(env, this_obj); | |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
814 |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
815 // detach from the ptraced process causing it to resume execution |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
816 int pid; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
817 kern_return_t k_res; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
818 k_res = pid_for_task(gTask, &pid); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
819 if (k_res != KERN_SUCCESS) { |
8750 | 820 print_error("detach: pid_for_task(%d) failed (%d)\n", pid, k_res); |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
821 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
822 else { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
823 int res = ptrace(PT_DETACH, pid, 0, 0); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
824 if (res < 0) { |
8750 | 825 print_error("detach: ptrace(PT_DETACH, %d) failed (%d)\n", pid, res); |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
826 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
827 } |
8750 | 828 |
4006 | 829 mach_port_deallocate(mach_task_self(), gTask); |
830 id symbolicator = getSymbolicator(env, this_obj); | |
831 if (symbolicator != nil) { | |
832 CFRelease(symbolicator); | |
833 } | |
834 JNF_COCOA_EXIT(env); | |
835 } |