Mercurial > hg > truffle
annotate agent/src/os/linux/LinuxDebuggerLocal.c @ 3237:399aa66d375e
Fixed a bug in which the valueEquals method was misused. The method does only check the equality of the node data and not full GVN equality by taking inputs and successors into account.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Wed, 27 Jul 2011 14:16:38 -0700 |
parents | c18cbe5936b8 |
children | a9fed06c01d2 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 #include <jni.h> | |
26 #include "libproc.h" | |
27 | |
28 #if defined(x86_64) && !defined(amd64) | |
29 #define amd64 1 | |
30 #endif | |
31 | |
32 #ifdef i386 | |
33 #include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h" | |
34 #endif | |
35 | |
36 #ifdef amd64 | |
37 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h" | |
38 #endif | |
39 | |
40 #if defined(sparc) || defined(sparcv9) | |
41 #include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h" | |
42 #endif | |
43 | |
44 static jfieldID p_ps_prochandle_ID = 0; | |
45 static jfieldID threadList_ID = 0; | |
46 static jfieldID loadObjectList_ID = 0; | |
47 | |
48 static jmethodID createClosestSymbol_ID = 0; | |
49 static jmethodID createLoadObject_ID = 0; | |
50 static jmethodID getThreadForThreadId_ID = 0; | |
51 static jmethodID listAdd_ID = 0; | |
52 | |
53 #define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; } | |
54 #define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;} | |
55 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; } | |
56 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;} | |
57 | |
58 static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) { | |
59 (*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg); | |
60 } | |
61 | |
62 static struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) { | |
63 jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID); | |
64 return (struct ps_prochandle*)(intptr_t)ptr; | |
65 } | |
66 | |
67 /* | |
68 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal | |
69 * Method: init0 | |
70 * Signature: ()V | |
71 */ | |
72 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_init0 | |
73 (JNIEnv *env, jclass cls) { | |
74 jclass listClass; | |
75 | |
76 if (init_libproc(getenv("LIBSAPROC_DEBUG")) != true) { | |
77 THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc"); | |
78 } | |
79 | |
80 // fields we use | |
81 p_ps_prochandle_ID = (*env)->GetFieldID(env, cls, "p_ps_prochandle", "J"); | |
82 CHECK_EXCEPTION; | |
83 threadList_ID = (*env)->GetFieldID(env, cls, "threadList", "Ljava/util/List;"); | |
84 CHECK_EXCEPTION; | |
85 loadObjectList_ID = (*env)->GetFieldID(env, cls, "loadObjectList", "Ljava/util/List;"); | |
86 CHECK_EXCEPTION; | |
87 | |
88 // methods we use | |
89 createClosestSymbol_ID = (*env)->GetMethodID(env, cls, "createClosestSymbol", | |
90 "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;"); | |
91 CHECK_EXCEPTION; | |
92 createLoadObject_ID = (*env)->GetMethodID(env, cls, "createLoadObject", | |
93 "(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;"); | |
94 CHECK_EXCEPTION; | |
95 getThreadForThreadId_ID = (*env)->GetMethodID(env, cls, "getThreadForThreadId", | |
96 "(J)Lsun/jvm/hotspot/debugger/ThreadProxy;"); | |
97 CHECK_EXCEPTION; | |
98 // java.util.List method we call | |
99 listClass = (*env)->FindClass(env, "java/util/List"); | |
100 CHECK_EXCEPTION; | |
101 listAdd_ID = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z"); | |
102 CHECK_EXCEPTION; | |
103 } | |
104 | |
105 JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getAddressSize | |
106 (JNIEnv *env, jclass cls) | |
107 { | |
108 #ifdef _LP64 | |
109 return 8; | |
110 #else | |
111 return 4; | |
112 #endif | |
113 | |
114 } | |
115 | |
116 | |
117 static void fillThreadsAndLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) { | |
118 int n = 0, i = 0; | |
119 | |
120 // add threads | |
121 n = get_num_threads(ph); | |
122 for (i = 0; i < n; i++) { | |
123 jobject thread; | |
124 jobject threadList; | |
125 lwpid_t lwpid; | |
126 | |
127 lwpid = get_lwp_id(ph, i); | |
128 thread = (*env)->CallObjectMethod(env, this_obj, getThreadForThreadId_ID, | |
129 (jlong)lwpid); | |
130 CHECK_EXCEPTION; | |
131 threadList = (*env)->GetObjectField(env, this_obj, threadList_ID); | |
132 CHECK_EXCEPTION; | |
133 (*env)->CallBooleanMethod(env, threadList, listAdd_ID, thread); | |
134 CHECK_EXCEPTION; | |
135 } | |
136 | |
137 // add load objects | |
138 n = get_num_libs(ph); | |
139 for (i = 0; i < n; i++) { | |
140 uintptr_t base; | |
141 const char* name; | |
142 jobject loadObject; | |
143 jobject loadObjectList; | |
144 | |
145 base = get_lib_base(ph, i); | |
146 name = get_lib_name(ph, i); | |
147 loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID, | |
148 (*env)->NewStringUTF(env, name), (jlong)0, (jlong)base); | |
149 CHECK_EXCEPTION; | |
150 loadObjectList = (*env)->GetObjectField(env, this_obj, loadObjectList_ID); | |
151 CHECK_EXCEPTION; | |
152 (*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject); | |
153 CHECK_EXCEPTION; | |
154 } | |
155 } | |
156 | |
157 /* | |
158 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal | |
159 * Method: attach0 | |
160 * Signature: (I)V | |
161 */ | |
162 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__I | |
163 (JNIEnv *env, jobject this_obj, jint jpid) { | |
164 | |
165 struct ps_prochandle* ph; | |
166 if ( (ph = Pgrab(jpid)) == NULL) { | |
167 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process"); | |
168 } | |
169 (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph); | |
170 fillThreadsAndLoadObjects(env, this_obj, ph); | |
171 } | |
172 | |
173 /* | |
174 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal | |
175 * Method: attach0 | |
176 * Signature: (Ljava/lang/String;Ljava/lang/String;)V | |
177 */ | |
178 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2 | |
179 (JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) { | |
180 const char *execName_cstr; | |
181 const char *coreName_cstr; | |
182 jboolean isCopy; | |
183 struct ps_prochandle* ph; | |
184 | |
185 execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy); | |
186 CHECK_EXCEPTION; | |
187 coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy); | |
188 CHECK_EXCEPTION; | |
189 | |
190 if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) { | |
191 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr); | |
192 (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr); | |
193 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file"); | |
194 } | |
195 (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph); | |
196 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr); | |
197 (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr); | |
198 fillThreadsAndLoadObjects(env, this_obj, ph); | |
199 } | |
200 | |
201 /* | |
202 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal | |
203 * Method: detach0 | |
204 * Signature: ()V | |
205 */ | |
206 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_detach0 | |
207 (JNIEnv *env, jobject this_obj) { | |
208 struct ps_prochandle* ph = get_proc_handle(env, this_obj); | |
209 if (ph != NULL) { | |
210 Prelease(ph); | |
211 } | |
212 } | |
213 | |
214 /* | |
215 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal | |
216 * Method: lookupByName0 | |
217 * Signature: (Ljava/lang/String;Ljava/lang/String;)J | |
218 */ | |
219 JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByName0 | |
220 (JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) { | |
221 const char *objectName_cstr, *symbolName_cstr; | |
222 jlong addr; | |
223 jboolean isCopy; | |
224 struct ps_prochandle* ph = get_proc_handle(env, this_obj); | |
225 | |
226 objectName_cstr = NULL; | |
227 if (objectName != NULL) { | |
228 objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy); | |
229 CHECK_EXCEPTION_(0); | |
230 } | |
231 symbolName_cstr = (*env)->GetStringUTFChars(env, symbolName, &isCopy); | |
232 CHECK_EXCEPTION_(0); | |
233 | |
234 addr = (jlong) lookup_symbol(ph, objectName_cstr, symbolName_cstr); | |
235 | |
236 if (objectName_cstr != NULL) { | |
237 (*env)->ReleaseStringUTFChars(env, objectName, objectName_cstr); | |
238 } | |
239 (*env)->ReleaseStringUTFChars(env, symbolName, symbolName_cstr); | |
240 return addr; | |
241 } | |
242 | |
243 /* | |
244 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal | |
245 * Method: lookupByAddress0 | |
246 * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol; | |
247 */ | |
248 JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByAddress0 | |
249 (JNIEnv *env, jobject this_obj, jlong addr) { | |
250 uintptr_t offset; | |
251 const char* sym = NULL; | |
252 | |
253 struct ps_prochandle* ph = get_proc_handle(env, this_obj); | |
254 sym = symbol_for_pc(ph, (uintptr_t) addr, &offset); | |
255 if (sym == NULL) return 0; | |
256 return (*env)->CallObjectMethod(env, this_obj, createClosestSymbol_ID, | |
257 (*env)->NewStringUTF(env, sym), (jlong)offset); | |
258 } | |
259 | |
260 /* | |
261 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal | |
262 * Method: readBytesFromProcess0 | |
263 * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult; | |
264 */ | |
265 JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_readBytesFromProcess0 | |
266 (JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) { | |
267 | |
268 jboolean isCopy; | |
269 jbyteArray array; | |
270 jbyte *bufPtr; | |
271 ps_err_e err; | |
272 | |
273 array = (*env)->NewByteArray(env, numBytes); | |
274 CHECK_EXCEPTION_(0); | |
275 bufPtr = (*env)->GetByteArrayElements(env, array, &isCopy); | |
276 CHECK_EXCEPTION_(0); | |
277 | |
278 err = ps_pdread(get_proc_handle(env, this_obj), (psaddr_t) (uintptr_t)addr, bufPtr, numBytes); | |
279 (*env)->ReleaseByteArrayElements(env, array, bufPtr, 0); | |
280 return (err == PS_OK)? array : 0; | |
281 } | |
282 | |
283 JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0 | |
284 (JNIEnv *env, jobject this_obj, jint lwp_id) { | |
285 | |
286 struct user_regs_struct gregs; | |
287 jboolean isCopy; | |
288 jlongArray array; | |
289 jlong *regs; | |
290 int i; | |
291 | |
292 struct ps_prochandle* ph = get_proc_handle(env, this_obj); | |
293 if (get_lwp_regs(ph, lwp_id, &gregs) != true) { | |
294 THROW_NEW_DEBUGGER_EXCEPTION_("get_thread_regs failed for a lwp", 0); | |
295 } | |
296 | |
297 #undef NPRGREG | |
298 #ifdef i386 | |
299 #define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG | |
300 #endif | |
301 #ifdef ia64 | |
302 #define NPRGREG IA64_REG_COUNT | |
303 #endif | |
304 #ifdef amd64 | |
305 #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG | |
306 #endif | |
307 #if defined(sparc) || defined(sparcv9) | |
308 #define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG | |
309 #endif | |
310 | |
311 array = (*env)->NewLongArray(env, NPRGREG); | |
312 CHECK_EXCEPTION_(0); | |
313 regs = (*env)->GetLongArrayElements(env, array, &isCopy); | |
314 | |
315 #undef REG_INDEX | |
316 | |
317 #ifdef i386 | |
318 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##reg | |
319 | |
320 regs[REG_INDEX(GS)] = (uintptr_t) gregs.xgs; | |
321 regs[REG_INDEX(FS)] = (uintptr_t) gregs.xfs; | |
322 regs[REG_INDEX(ES)] = (uintptr_t) gregs.xes; | |
323 regs[REG_INDEX(DS)] = (uintptr_t) gregs.xds; | |
324 regs[REG_INDEX(EDI)] = (uintptr_t) gregs.edi; | |
325 regs[REG_INDEX(ESI)] = (uintptr_t) gregs.esi; | |
326 regs[REG_INDEX(FP)] = (uintptr_t) gregs.ebp; | |
327 regs[REG_INDEX(SP)] = (uintptr_t) gregs.esp; | |
328 regs[REG_INDEX(EBX)] = (uintptr_t) gregs.ebx; | |
329 regs[REG_INDEX(EDX)] = (uintptr_t) gregs.edx; | |
330 regs[REG_INDEX(ECX)] = (uintptr_t) gregs.ecx; | |
331 regs[REG_INDEX(EAX)] = (uintptr_t) gregs.eax; | |
332 regs[REG_INDEX(PC)] = (uintptr_t) gregs.eip; | |
333 regs[REG_INDEX(CS)] = (uintptr_t) gregs.xcs; | |
334 regs[REG_INDEX(SS)] = (uintptr_t) gregs.xss; | |
335 | |
336 #endif /* i386 */ | |
337 | |
338 #if ia64 | |
339 regs = (*env)->GetLongArrayElements(env, array, &isCopy); | |
340 for (i = 0; i < NPRGREG; i++ ) { | |
341 regs[i] = 0xDEADDEAD; | |
342 } | |
343 #endif /* ia64 */ | |
344 | |
345 #ifdef amd64 | |
346 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg | |
347 | |
348 regs[REG_INDEX(R15)] = gregs.r15; | |
349 regs[REG_INDEX(R14)] = gregs.r14; | |
350 regs[REG_INDEX(R13)] = gregs.r13; | |
351 regs[REG_INDEX(R12)] = gregs.r12; | |
352 regs[REG_INDEX(RBP)] = gregs.rbp; | |
353 regs[REG_INDEX(RBX)] = gregs.rbx; | |
354 regs[REG_INDEX(R11)] = gregs.r11; | |
355 regs[REG_INDEX(R10)] = gregs.r10; | |
356 regs[REG_INDEX(R9)] = gregs.r9; | |
357 regs[REG_INDEX(R8)] = gregs.r8; | |
358 regs[REG_INDEX(RAX)] = gregs.rax; | |
359 regs[REG_INDEX(RCX)] = gregs.rcx; | |
360 regs[REG_INDEX(RDX)] = gregs.rdx; | |
361 regs[REG_INDEX(RSI)] = gregs.rsi; | |
362 regs[REG_INDEX(RDI)] = gregs.rdi; | |
363 regs[REG_INDEX(RIP)] = gregs.rip; | |
364 regs[REG_INDEX(CS)] = gregs.cs; | |
365 regs[REG_INDEX(RSP)] = gregs.rsp; | |
366 regs[REG_INDEX(SS)] = gregs.ss; | |
367 regs[REG_INDEX(FSBASE)] = gregs.fs_base; | |
368 regs[REG_INDEX(GSBASE)] = gregs.gs_base; | |
369 regs[REG_INDEX(DS)] = gregs.ds; | |
370 regs[REG_INDEX(ES)] = gregs.es; | |
371 regs[REG_INDEX(FS)] = gregs.fs; | |
372 regs[REG_INDEX(GS)] = gregs.gs; | |
373 | |
374 #endif /* amd64 */ | |
375 | |
376 #if defined(sparc) || defined(sparcv9) | |
377 | |
378 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_##reg | |
379 | |
380 #ifdef _LP64 | |
381 regs[REG_INDEX(R_PSR)] = gregs.tstate; | |
382 regs[REG_INDEX(R_PC)] = gregs.tpc; | |
383 regs[REG_INDEX(R_nPC)] = gregs.tnpc; | |
384 regs[REG_INDEX(R_Y)] = gregs.y; | |
385 #else | |
386 regs[REG_INDEX(R_PSR)] = gregs.psr; | |
387 regs[REG_INDEX(R_PC)] = gregs.pc; | |
388 regs[REG_INDEX(R_nPC)] = gregs.npc; | |
389 regs[REG_INDEX(R_Y)] = gregs.y; | |
390 #endif | |
391 regs[REG_INDEX(R_G0)] = 0 ; | |
392 regs[REG_INDEX(R_G1)] = gregs.u_regs[0]; | |
393 regs[REG_INDEX(R_G2)] = gregs.u_regs[1]; | |
394 regs[REG_INDEX(R_G3)] = gregs.u_regs[2]; | |
395 regs[REG_INDEX(R_G4)] = gregs.u_regs[3]; | |
396 regs[REG_INDEX(R_G5)] = gregs.u_regs[4]; | |
397 regs[REG_INDEX(R_G6)] = gregs.u_regs[5]; | |
398 regs[REG_INDEX(R_G7)] = gregs.u_regs[6]; | |
399 regs[REG_INDEX(R_O0)] = gregs.u_regs[7]; | |
400 regs[REG_INDEX(R_O1)] = gregs.u_regs[8]; | |
401 regs[REG_INDEX(R_O2)] = gregs.u_regs[ 9]; | |
402 regs[REG_INDEX(R_O3)] = gregs.u_regs[10]; | |
403 regs[REG_INDEX(R_O4)] = gregs.u_regs[11]; | |
404 regs[REG_INDEX(R_O5)] = gregs.u_regs[12]; | |
405 regs[REG_INDEX(R_O6)] = gregs.u_regs[13]; | |
406 regs[REG_INDEX(R_O7)] = gregs.u_regs[14]; | |
407 #endif /* sparc */ | |
408 | |
409 | |
410 (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT); | |
411 return array; | |
412 } |