Mercurial > hg > truffle
annotate agent/src/os/bsd/MacosxDebuggerLocal.m @ 8158:53bc01380011
Fix client build.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Thu, 07 Mar 2013 23:24:05 +0100 |
parents | 5d5c577296fd |
children | 40b7c6b800ab |
rev | line source |
---|---|
4006 | 1 /* |
6782 | 2 * Copyright (c) 2002, 2012, 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> |
4006 | 43 |
44 jboolean debug = JNI_FALSE; | |
45 | |
46 static jfieldID symbolicatorID = 0; // set in _init0 | |
47 static jfieldID taskID = 0; // set in _init0 | |
48 | |
49 static void putSymbolicator(JNIEnv *env, jobject this_obj, id symbolicator) { | |
50 (*env)->SetLongField(env, this_obj, symbolicatorID, (jlong)(intptr_t)symbolicator); | |
51 } | |
52 | |
53 static id getSymbolicator(JNIEnv *env, jobject this_obj) { | |
54 jlong ptr = (*env)->GetLongField(env, this_obj, symbolicatorID); | |
55 return (id)(intptr_t)ptr; | |
56 } | |
57 | |
58 static void putTask(JNIEnv *env, jobject this_obj, task_t task) { | |
59 (*env)->SetLongField(env, this_obj, taskID, (jlong)task); | |
60 } | |
61 | |
62 static task_t getTask(JNIEnv *env, jobject this_obj) { | |
63 jlong ptr = (*env)->GetLongField(env, this_obj, taskID); | |
64 return (task_t)ptr; | |
65 } | |
66 | |
67 #define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; } | |
68 #define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;} | |
69 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; } | |
70 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;} | |
6782 | 71 #define CHECK_EXCEPTION_CLEAR if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); } |
72 #define CHECK_EXCEPTION_CLEAR_VOID if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); return; } | |
73 #define CHECK_EXCEPTION_CLEAR_(value) if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); return value; } | |
4006 | 74 |
75 static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) { | |
76 (*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg); | |
77 } | |
78 | |
79 #if defined(__i386__) | |
80 #define hsdb_thread_state_t x86_thread_state32_t | |
81 #define hsdb_float_state_t x86_float_state32_t | |
82 #define HSDB_THREAD_STATE x86_THREAD_STATE32 | |
83 #define HSDB_FLOAT_STATE x86_FLOAT_STATE32 | |
84 #define HSDB_THREAD_STATE_COUNT x86_THREAD_STATE32_COUNT | |
85 #define HSDB_FLOAT_STATE_COUNT x86_FLOAT_STATE32_COUNT | |
86 #elif defined(__x86_64__) | |
87 #define hsdb_thread_state_t x86_thread_state64_t | |
88 #define hsdb_float_state_t x86_float_state64_t | |
89 #define HSDB_THREAD_STATE x86_THREAD_STATE64 | |
90 #define HSDB_FLOAT_STATE x86_FLOAT_STATE64 | |
91 #define HSDB_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT | |
92 #define HSDB_FLOAT_STATE_COUNT x86_FLOAT_STATE64_COUNT | |
93 #else | |
94 #error "Unsupported architecture" | |
95 #endif | |
96 | |
97 /* | |
98 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal | |
99 * Method: init0 | |
100 * Signature: ()V | |
101 */ | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
102 JNIEXPORT void JNICALL |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
103 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0(JNIEnv *env, jclass cls) { |
4006 | 104 symbolicatorID = (*env)->GetFieldID(env, cls, "symbolicator", "J"); |
105 taskID = (*env)->GetFieldID(env, cls, "task", "J"); | |
106 CHECK_EXCEPTION; | |
107 } | |
108 | |
109 /* | |
110 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal | |
111 * Method: lookupByName0 | |
112 * Signature: (Ljava/lang/String;Ljava/lang/String;)J | |
113 */ | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
114 JNIEXPORT jlong JNICALL |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
115 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
|
116 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
|
117 jstring objectName, jstring symbolName) |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
118 { |
4006 | 119 jlong address = 0; |
120 | |
121 JNF_COCOA_ENTER(env); | |
122 NSString *symbolNameString = JNFJavaToNSString(env, symbolName); | |
123 | |
124 if (debug) { | |
125 printf("lookupInProcess called for %s\n", [symbolNameString UTF8String]); | |
126 } | |
127 | |
128 id symbolicator = getSymbolicator(env, this_obj); | |
129 if (symbolicator != nil) { | |
130 uint64_t (*dynamicCall)(id, SEL, NSString *) = (uint64_t (*)(id, SEL, NSString *))&objc_msgSend; | |
131 address = (jlong) dynamicCall(symbolicator, @selector(addressForSymbol:), symbolNameString); | |
132 } | |
133 | |
134 if (debug) { | |
135 printf("address of symbol %s = %llx\n", [symbolNameString UTF8String], address); | |
136 } | |
137 JNF_COCOA_EXIT(env); | |
138 | |
139 return address; | |
140 } | |
141 | |
142 /* | |
143 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal | |
144 * Method: readBytesFromProcess0 | |
145 * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult; | |
146 */ | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
147 JNIEXPORT jbyteArray JNICALL |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
148 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
|
149 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
|
150 jlong addr, jlong numBytes) |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
151 { |
4006 | 152 if (debug) printf("readBytesFromProcess called. addr = %llx numBytes = %lld\n", addr, numBytes); |
153 | |
154 // must allocate storage instead of using former parameter buf | |
155 jboolean isCopy; | |
156 jbyteArray array; | |
157 jbyte *bufPtr; | |
158 | |
159 array = (*env)->NewByteArray(env, numBytes); | |
160 CHECK_EXCEPTION_(0); | |
161 | |
162 unsigned long alignedAddress; | |
163 unsigned long alignedLength; | |
164 kern_return_t result; | |
165 vm_offset_t *pages; | |
166 int *mapped; | |
167 long pageCount; | |
168 uint byteCount; | |
169 int i; | |
170 unsigned long remaining; | |
171 | |
172 alignedAddress = trunc_page(addr); | |
173 if (addr != alignedAddress) { | |
174 alignedLength += addr - alignedAddress; | |
175 } | |
176 alignedLength = round_page(numBytes); | |
177 pageCount = alignedLength/vm_page_size; | |
178 | |
179 // Allocate storage for pages and flags. | |
180 pages = malloc(pageCount * sizeof(vm_offset_t)); | |
181 mapped = calloc(pageCount, sizeof(int)); | |
182 | |
183 task_t gTask = getTask(env, this_obj); | |
184 // Try to read each of the pages. | |
185 for (i = 0; i < pageCount; i++) { | |
186 result = vm_read(gTask, alignedAddress + i*vm_page_size, vm_page_size, | |
187 &pages[i], &byteCount); | |
188 mapped[i] = (result == KERN_SUCCESS); | |
189 // assume all failures are unmapped pages | |
190 } | |
191 | |
192 if (debug) fprintf(stderr, "%ld pages\n", pageCount); | |
193 | |
194 remaining = numBytes; | |
195 | |
196 for (i = 0; i < pageCount; i++) { | |
197 unsigned long len = vm_page_size; | |
198 unsigned long start = 0; | |
199 | |
200 if (i == 0) { | |
201 start = addr - alignedAddress; | |
202 len = vm_page_size - start; | |
203 } | |
204 | |
205 if (i == (pageCount - 1)) { | |
206 len = remaining; | |
207 } | |
208 | |
209 if (mapped[i]) { | |
210 if (debug) fprintf(stderr, "page %d mapped (len %ld start %ld)\n", i, len, start); | |
211 (*env)->SetByteArrayRegion(env, array, 0, len, ((jbyte *) pages[i] + start)); | |
212 vm_deallocate(mach_task_self(), pages[i], vm_page_size); | |
213 } | |
214 | |
215 remaining -= len; | |
216 } | |
217 | |
218 free (pages); | |
219 free (mapped); | |
220 return array; | |
221 } | |
222 | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
223 |
4006 | 224 /* |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
225 * 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
|
226 * 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
|
227 * 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
|
228 * 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
|
229 * |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
230 * 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
|
231 * 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
|
232 */ |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
233 thread_t |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
234 lookupThreadFromThreadId(task_t task, jlong thread_id) { |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
235 if (debug) { |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
236 printf("lookupThreadFromThreadId thread_id=0x%llx\n", thread_id); |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
237 } |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
238 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
239 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
|
240 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
|
241 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
|
242 int i; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
243 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
244 // 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
|
245 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
|
246 if (result != KERN_SUCCESS) { |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
247 if (debug) { |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
248 printf("task_threads returned 0x%x\n", result); |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
249 } |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
250 return 0; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
251 } |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
252 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
253 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
|
254 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
|
255 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
|
256 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
257 // 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
|
258 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
|
259 if (result != KERN_SUCCESS) { |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
260 if (debug) { |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
261 printf("thread_info returned 0x%x\n", result); |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
262 } |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
263 break; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
264 } |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
265 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
266 // 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
|
267 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
|
268 { |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
269 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
|
270 break; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
271 } |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
272 } |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
273 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
274 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
|
275 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
|
276 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
277 return result_thread; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
278 } |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
279 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
280 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
281 /* |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
282 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal |
4006 | 283 * Method: getThreadIntegerRegisterSet0 |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
284 * Signature: (J)[J |
4006 | 285 */ |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
286 JNIEXPORT jlongArray JNICALL |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
287 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
|
288 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
|
289 jlong thread_id) |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
290 { |
4006 | 291 if (debug) |
292 printf("getThreadRegisterSet0 called\n"); | |
293 | |
294 kern_return_t result; | |
295 thread_t tid; | |
296 mach_msg_type_number_t count = HSDB_THREAD_STATE_COUNT; | |
297 hsdb_thread_state_t state; | |
298 unsigned int *r; | |
299 int i; | |
300 jlongArray registerArray; | |
301 jlong *primitiveArray; | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
302 task_t gTask = getTask(env, this_obj); |
4006 | 303 |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
304 tid = lookupThreadFromThreadId(gTask, thread_id); |
4006 | 305 |
306 result = thread_get_state(tid, HSDB_THREAD_STATE, (thread_state_t)&state, &count); | |
307 | |
308 if (result != KERN_SUCCESS) { | |
309 if (debug) | |
310 printf("getregs: thread_get_state(%d) failed (%d)\n", tid, result); | |
311 return NULL; | |
312 } | |
313 | |
314 // 40 32-bit registers on ppc, 16 on x86. | |
315 // Output order is the same as the order in the ppc_thread_state/i386_thread_state struct. | |
316 #if defined(__i386__) | |
317 r = (unsigned int *)&state; | |
318 registerArray = (*env)->NewLongArray(env, 8); | |
319 primitiveArray = (*env)->GetLongArrayElements(env, registerArray, NULL); | |
320 primitiveArray[0] = r[0]; // eax | |
321 primitiveArray[1] = r[2]; // ecx | |
322 primitiveArray[2] = r[3]; // edx | |
323 primitiveArray[3] = r[1]; // ebx | |
324 primitiveArray[4] = r[7]; // esp | |
325 primitiveArray[5] = r[6]; // ebp | |
326 primitiveArray[6] = r[5]; // esi | |
327 primitiveArray[7] = r[4]; // edi | |
328 (*env)->ReleaseLongArrayElements(env, registerArray, primitiveArray, 0); | |
329 #elif defined(__x86_64__) | |
330 /* From AMD64ThreadContext.java | |
331 public static final int R15 = 0; | |
332 public static final int R14 = 1; | |
333 public static final int R13 = 2; | |
334 public static final int R12 = 3; | |
335 public static final int R11 = 4; | |
336 public static final int R10 = 5; | |
337 public static final int R9 = 6; | |
338 public static final int R8 = 7; | |
339 public static final int RDI = 8; | |
340 public static final int RSI = 9; | |
341 public static final int RBP = 10; | |
342 public static final int RBX = 11; | |
343 public static final int RDX = 12; | |
344 public static final int RCX = 13; | |
345 public static final int RAX = 14; | |
346 public static final int TRAPNO = 15; | |
347 public static final int ERR = 16; | |
348 public static final int RIP = 17; | |
349 public static final int CS = 18; | |
350 public static final int RFL = 19; | |
351 public static final int RSP = 20; | |
352 public static final int SS = 21; | |
353 public static final int FS = 22; | |
354 public static final int GS = 23; | |
355 public static final int ES = 24; | |
356 public static final int DS = 25; | |
357 public static final int FSBASE = 26; | |
358 public static final int GSBASE = 27; | |
359 */ | |
360 // 64 bit | |
361 if (debug) printf("Getting threads for a 64-bit process\n"); | |
362 registerArray = (*env)->NewLongArray(env, 28); | |
363 primitiveArray = (*env)->GetLongArrayElements(env, registerArray, NULL); | |
364 | |
365 primitiveArray[0] = state.__r15; | |
366 primitiveArray[1] = state.__r14; | |
367 primitiveArray[2] = state.__r13; | |
368 primitiveArray[3] = state.__r12; | |
369 primitiveArray[4] = state.__r11; | |
370 primitiveArray[5] = state.__r10; | |
371 primitiveArray[6] = state.__r9; | |
372 primitiveArray[7] = state.__r8; | |
373 primitiveArray[8] = state.__rdi; | |
374 primitiveArray[9] = state.__rsi; | |
375 primitiveArray[10] = state.__rbp; | |
376 primitiveArray[11] = state.__rbx; | |
377 primitiveArray[12] = state.__rdx; | |
378 primitiveArray[13] = state.__rcx; | |
379 primitiveArray[14] = state.__rax; | |
380 primitiveArray[15] = 0; // trapno ? | |
381 primitiveArray[16] = 0; // err ? | |
382 primitiveArray[17] = state.__rip; | |
383 primitiveArray[18] = state.__cs; | |
384 primitiveArray[19] = state.__rflags; | |
385 primitiveArray[20] = state.__rsp; | |
386 primitiveArray[21] = 0; // We don't have SS | |
387 primitiveArray[22] = state.__fs; | |
388 primitiveArray[23] = state.__gs; | |
389 primitiveArray[24] = 0; | |
390 primitiveArray[25] = 0; | |
391 primitiveArray[26] = 0; | |
392 primitiveArray[27] = 0; | |
393 | |
394 if (debug) printf("set registers\n"); | |
395 | |
396 (*env)->ReleaseLongArrayElements(env, registerArray, primitiveArray, 0); | |
397 #else | |
398 #error Unsupported architecture | |
399 #endif | |
400 | |
401 return registerArray; | |
402 } | |
403 | |
404 /* | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
405 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal |
4006 | 406 * Method: translateTID0 |
407 * Signature: (I)I | |
408 */ | |
409 JNIEXPORT jint JNICALL | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
410 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
|
411 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
|
412 { |
4006 | 413 if (debug) |
414 printf("translateTID0 called on tid = 0x%x\n", (int)tid); | |
415 | |
416 kern_return_t result; | |
417 thread_t foreign_tid, usable_tid; | |
418 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
|
419 |
4006 | 420 foreign_tid = tid; |
421 | |
422 task_t gTask = getTask(env, this_obj); | |
423 result = mach_port_extract_right(gTask, foreign_tid, | |
424 MACH_MSG_TYPE_COPY_SEND, | |
425 &usable_tid, &type); | |
426 if (result != KERN_SUCCESS) | |
427 return -1; | |
428 | |
429 if (debug) | |
430 printf("translateTID0: 0x%x -> 0x%x\n", foreign_tid, usable_tid); | |
431 | |
432 return (jint) usable_tid; | |
433 } | |
434 | |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
435 |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
436 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
|
437 // 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
|
438 int res; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
439 if ((res = ptrace(PT_CONTINUE, pid, (caddr_t)1, signal)) < 0) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
440 fprintf(stderr, "attach: ptrace(PT_CONTINUE, %d) failed with %d\n", pid, res); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
441 return false; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
442 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
443 return true; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
444 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
445 |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
446 // 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
|
447 // by signal SIGSTOP |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
448 static bool ptrace_waitpid(pid_t pid) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
449 int ret; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
450 int status; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
451 while (true) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
452 // Wait for debuggee to stop. |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
453 ret = waitpid(pid, &status, 0); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
454 if (ret >= 0) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
455 if (WIFSTOPPED(status)) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
456 // 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
|
457 // 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
|
458 // will go to sleep. |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
459 if (WSTOPSIG(status) == SIGSTOP) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
460 // Debuggee stopped by SIGSTOP. |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
461 return true; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
462 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
463 if (!ptrace_continue(pid, WSTOPSIG(status))) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
464 fprintf(stderr, "attach: Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status)); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
465 return false; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
466 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
467 } else { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
468 fprintf(stderr, "attach: waitpid(): Child process exited/terminated (status = 0x%x)\n", status); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
469 return false; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
470 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
471 } else { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
472 switch (errno) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
473 case EINTR: |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
474 continue; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
475 break; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
476 case ECHILD: |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
477 fprintf(stderr, "attach: waitpid() failed. Child process pid (%d) does not exist \n", pid); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
478 break; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
479 case EINVAL: |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
480 fprintf(stderr, "attach: waitpid() failed. Invalid options argument.\n"); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
481 break; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
482 default: |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
483 fprintf(stderr, "attach: waitpid() failed. Unexpected error %d\n",errno); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
484 break; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
485 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
486 return false; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
487 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
488 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
489 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
490 |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
491 // 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
|
492 static bool ptrace_attach(pid_t pid) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
493 int res; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
494 if ((res = ptrace(PT_ATTACH, pid, 0, 0)) < 0) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
495 fprintf(stderr, "ptrace(PT_ATTACH, %d) failed with %d\n", pid, res); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
496 return false; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
497 } else { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
498 return ptrace_waitpid(pid); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
499 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
500 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
501 |
4006 | 502 /* |
503 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal | |
504 * Method: attach0 | |
505 * Signature: (I)V | |
506 */ | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
507 JNIEXPORT void JNICALL |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
508 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I( |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
509 JNIEnv *env, jobject this_obj, jint jpid) |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
510 { |
4006 | 511 JNF_COCOA_ENTER(env); |
512 if (getenv("JAVA_SAPROC_DEBUG") != NULL) | |
513 debug = JNI_TRUE; | |
514 else | |
515 debug = JNI_FALSE; | |
516 if (debug) printf("attach0 called for jpid=%d\n", (int)jpid); | |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
517 |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
518 // get the task from the pid |
4006 | 519 kern_return_t result; |
520 task_t gTask = 0; | |
521 result = task_for_pid(mach_task_self(), jpid, &gTask); | |
522 if (result != KERN_SUCCESS) { | |
523 fprintf(stderr, "attach: task_for_pid(%d) failed (%d)\n", (int)jpid, result); | |
524 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process"); | |
525 } | |
526 putTask(env, this_obj, gTask); | |
527 | |
8062
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
528 // use ptrace to stop the process |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
529 // 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
|
530 if (ptrace_attach(jpid) != true) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
531 mach_port_deallocate(mach_task_self(), gTask); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
532 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
|
533 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
534 |
4006 | 535 id symbolicator = nil; |
536 id jrsSymbolicator = objc_lookUpClass("JRSSymbolicator"); | |
537 if (jrsSymbolicator != nil) { | |
538 id (*dynamicCall)(id, SEL, pid_t) = (id (*)(id, SEL, pid_t))&objc_msgSend; | |
539 symbolicator = dynamicCall(jrsSymbolicator, @selector(symbolicatorForPid:), (pid_t)jpid); | |
540 } | |
541 if (symbolicator != nil) { | |
542 CFRetain(symbolicator); // pin symbolicator while in java heap | |
543 } | |
544 | |
545 putSymbolicator(env, this_obj, symbolicator); | |
546 if (symbolicator == nil) { | |
547 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach symbolicator to the process"); | |
548 } | |
549 | |
550 JNF_COCOA_EXIT(env); | |
551 } | |
552 | |
553 /* | |
554 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal | |
555 * Method: detach0 | |
556 * Signature: ()V | |
557 */ | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
558 JNIEXPORT void JNICALL |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
559 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0( |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
560 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
|
561 { |
4006 | 562 JNF_COCOA_ENTER(env); |
563 if (debug) printf("detach0 called\n"); | |
564 | |
565 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
|
566 |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
567 // 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
|
568 int pid; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
569 kern_return_t k_res; |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
570 k_res = pid_for_task(gTask, &pid); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
571 if (k_res != KERN_SUCCESS) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
572 fprintf(stderr, "detach: pid_for_task(%d) failed (%d)\n", pid, k_res); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
573 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
574 else { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
575 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
|
576 if (res < 0) { |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
577 fprintf(stderr, "detach: ptrace(PT_DETACH, %d) failed (%d)\n", pid, res); |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
578 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
579 } |
5d5c577296fd
8008102: SA on OS X does not stop the attached process
sla
parents:
8023
diff
changeset
|
580 |
4006 | 581 mach_port_deallocate(mach_task_self(), gTask); |
582 id symbolicator = getSymbolicator(env, this_obj); | |
583 if (symbolicator != nil) { | |
584 CFRelease(symbolicator); | |
585 } | |
586 JNF_COCOA_EXIT(env); | |
587 } | |
6782 | 588 |
589 /* | |
590 * Class: sun_jvm_hotspot_asm_Disassembler | |
591 * Method: load_library | |
592 * Signature: (Ljava/lang/String;)L | |
593 */ | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
594 JNIEXPORT jlong JNICALL |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
595 Java_sun_jvm_hotspot_asm_Disassembler_load_1library( |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
596 JNIEnv * env, |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
597 jclass disclass, |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
598 jstring jrepath_s, |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
599 jstring libname_s) |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
600 { |
6782 | 601 uintptr_t func = 0; |
602 const char* error_message = NULL; | |
603 const char* java_home; | |
604 jboolean isCopy; | |
605 uintptr_t *handle = NULL; | |
606 | |
607 const char * jrepath = (*env)->GetStringUTFChars(env, jrepath_s, &isCopy); // like $JAVA_HOME/jre/lib/sparc/ | |
608 const char * libname = (*env)->GetStringUTFChars(env, libname_s, &isCopy); | |
609 char buffer[128]; | |
610 | |
611 /* Load the hsdis library */ | |
612 void* hsdis_handle; | |
613 hsdis_handle = dlopen(libname, RTLD_LAZY | RTLD_GLOBAL); | |
614 if (hsdis_handle == NULL) { | |
615 snprintf(buffer, sizeof(buffer), "%s%s", jrepath, libname); | |
616 hsdis_handle = dlopen(buffer, RTLD_LAZY | RTLD_GLOBAL); | |
617 } | |
618 if (hsdis_handle != NULL) { | |
619 func = (uintptr_t)dlsym(hsdis_handle, "decode_instructions_virtual"); | |
620 } | |
621 if (func == 0) { | |
622 error_message = dlerror(); | |
623 fprintf(stderr, "%s\n", error_message); | |
624 } | |
625 | |
626 (*env)->ReleaseStringUTFChars(env, libname_s, libname); | |
627 (*env)->ReleaseStringUTFChars(env, jrepath_s, jrepath); | |
628 | |
629 if (func == 0) { | |
630 /* Couldn't find entry point. error_message should contain some | |
631 * platform dependent error message. | |
632 */ | |
633 THROW_NEW_DEBUGGER_EXCEPTION(error_message); | |
634 } | |
635 return (jlong)func; | |
636 } | |
637 | |
638 /* signature of decode_instructions_virtual from hsdis.h */ | |
639 typedef void* (*decode_func)(uintptr_t start_va, uintptr_t end_va, | |
640 unsigned char* start, uintptr_t length, | |
641 void* (*event_callback)(void*, const char*, void*), | |
642 void* event_stream, | |
643 int (*printf_callback)(void*, const char*, ...), | |
644 void* printf_stream, | |
645 const char* options); | |
646 | |
647 /* container for call back state when decoding instructions */ | |
648 typedef struct { | |
649 JNIEnv* env; | |
650 jobject dis; | |
651 jobject visitor; | |
652 jmethodID handle_event; | |
653 jmethodID raw_print; | |
654 char buffer[4096]; | |
655 } decode_env; | |
656 | |
657 | |
658 /* event callback binding to Disassembler.handleEvent */ | |
659 static void* event_to_env(void* env_pv, const char* event, void* arg) { | |
660 decode_env* denv = (decode_env*)env_pv; | |
661 JNIEnv* env = denv->env; | |
662 jstring event_string = (*env)->NewStringUTF(env, event); | |
663 jlong result = (*env)->CallLongMethod(env, denv->dis, denv->handle_event, denv->visitor, | |
664 event_string, (jlong) (uintptr_t)arg); | |
665 /* ignore exceptions for now */ | |
666 CHECK_EXCEPTION_CLEAR_((void *)0); | |
667 return (void*)(uintptr_t)result; | |
668 } | |
669 | |
670 /* printing callback binding to Disassembler.rawPrint */ | |
671 static int printf_to_env(void* env_pv, const char* format, ...) { | |
672 jstring output; | |
673 va_list ap; | |
674 int cnt; | |
675 decode_env* denv = (decode_env*)env_pv; | |
676 JNIEnv* env = denv->env; | |
677 size_t flen = strlen(format); | |
678 const char* raw = NULL; | |
679 | |
680 if (flen == 0) return 0; | |
681 if (flen < 2 || | |
682 strchr(format, '%') == NULL) { | |
683 raw = format; | |
684 } else if (format[0] == '%' && format[1] == '%' && | |
685 strchr(format+2, '%') == NULL) { | |
686 // happens a lot on machines with names like %foo | |
687 flen--; | |
688 raw = format+1; | |
689 } | |
690 if (raw != NULL) { | |
691 jstring output = (*env)->NewStringUTF(env, raw); | |
692 (*env)->CallVoidMethod(env, denv->dis, denv->raw_print, denv->visitor, output); | |
693 CHECK_EXCEPTION_CLEAR; | |
694 return (int) flen; | |
695 } | |
696 va_start(ap, format); | |
697 cnt = vsnprintf(denv->buffer, sizeof(denv->buffer), format, ap); | |
698 va_end(ap); | |
699 | |
700 output = (*env)->NewStringUTF(env, denv->buffer); | |
701 (*env)->CallVoidMethod(env, denv->dis, denv->raw_print, denv->visitor, output); | |
702 CHECK_EXCEPTION_CLEAR; | |
703 return cnt; | |
704 } | |
705 | |
706 /* | |
707 * Class: sun_jvm_hotspot_asm_Disassembler | |
708 * Method: decode | |
709 * Signature: (Lsun/jvm/hotspot/asm/InstructionVisitor;J[BLjava/lang/String;J)V | |
710 */ | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
711 JNIEXPORT void JNICALL |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
712 Java_sun_jvm_hotspot_asm_Disassembler_decode( |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
713 JNIEnv * env, |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
714 jobject dis, |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
715 jobject visitor, |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
716 jlong startPc, |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
717 jbyteArray code, |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
718 jstring options_s, |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
719 jlong decode_instructions_virtual) |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
6782
diff
changeset
|
720 { |
6782 | 721 jboolean isCopy; |
722 jbyte* start = (*env)->GetByteArrayElements(env, code, &isCopy); | |
723 jbyte* end = start + (*env)->GetArrayLength(env, code); | |
724 const char * options = (*env)->GetStringUTFChars(env, options_s, &isCopy); | |
725 jclass disclass = (*env)->GetObjectClass(env, dis); | |
726 | |
727 decode_env denv; | |
728 denv.env = env; | |
729 denv.dis = dis; | |
730 denv.visitor = visitor; | |
731 | |
732 /* find Disassembler.handleEvent callback */ | |
733 denv.handle_event = (*env)->GetMethodID(env, disclass, "handleEvent", | |
734 "(Lsun/jvm/hotspot/asm/InstructionVisitor;Ljava/lang/String;J)J"); | |
735 CHECK_EXCEPTION_CLEAR_VOID | |
736 | |
737 /* find Disassembler.rawPrint callback */ | |
738 denv.raw_print = (*env)->GetMethodID(env, disclass, "rawPrint", | |
739 "(Lsun/jvm/hotspot/asm/InstructionVisitor;Ljava/lang/String;)V"); | |
740 CHECK_EXCEPTION_CLEAR_VOID | |
741 | |
742 /* decode the buffer */ | |
743 (*(decode_func)(uintptr_t)decode_instructions_virtual)(startPc, | |
744 startPc + end - start, | |
745 (unsigned char*)start, | |
746 end - start, | |
747 &event_to_env, (void*) &denv, | |
748 &printf_to_env, (void*) &denv, | |
749 options); | |
750 | |
751 /* cleanup */ | |
752 (*env)->ReleaseByteArrayElements(env, code, start, JNI_ABORT); | |
753 (*env)->ReleaseStringUTFChars(env, options_s, options); | |
754 } |