1 /*
2 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
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 *
49 #include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h"
50 #endif
51
52 #if defined(ppc64) || defined(ppc64le)
53 #include "sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext.h"
54 #endif
55
56 #ifdef aarch64
57 #include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h"
58 #endif
59
60 static jfieldID p_ps_prochandle_ID = 0;
61 static jfieldID threadList_ID = 0;
62 static jfieldID loadObjectList_ID = 0;
63
64 static jmethodID createClosestSymbol_ID = 0;
65 static jmethodID createLoadObject_ID = 0;
66 static jmethodID getThreadForThreadId_ID = 0;
67 static jmethodID listAdd_ID = 0;
68
69 #define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; }
70 #define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;}
71 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }
72 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}
73
74 void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
75 jclass clazz;
76 clazz = (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException");
77 CHECK_EXCEPTION;
78 (*env)->ThrowNew(env, clazz, errMsg);
79 }
80
81 struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {
82 jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID);
83 return (struct ps_prochandle*)(intptr_t)ptr;
84 }
85
86 /*
87 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
88 * Method: init0
194 int i = read(fd, &elf_ident, sizeof(elf_ident));
195 close(fd);
196
197 if (i < 0) {
198 THROW_NEW_DEBUGGER_EXCEPTION("cannot read binary file");
199 }
200 #ifndef _LP64
201 if (elf_ident[EI_CLASS] == ELFCLASS64) {
202 THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 64 bit, use 64-bit java for debugger");
203 }
204 #else
205 if (elf_ident[EI_CLASS] != ELFCLASS64) {
206 THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 32 bit, use 32 bit java for debugger");
207 }
208 #endif
209 }
210
211
212 /*
213 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
214 * Method: attach0
215 * Signature: (I)V
216 */
217 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__I
218 (JNIEnv *env, jobject this_obj, jint jpid) {
219
220 // For bitness checking, locate binary at /proc/jpid/exe
221 char buf[PATH_MAX];
222 snprintf((char *) &buf, PATH_MAX, "/proc/%d/exe", jpid);
223 verifyBitness(env, (char *) &buf);
224 CHECK_EXCEPTION;
225
226 char err_buf[200];
227 struct ps_prochandle* ph;
228 if ( (ph = Pgrab(jpid, err_buf, sizeof(err_buf))) == NULL) {
229 char msg[230];
230 snprintf(msg, sizeof(msg), "Can't attach to the process: %s", err_buf);
231 THROW_NEW_DEBUGGER_EXCEPTION(msg);
232 }
233 (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
234 fillThreadsAndLoadObjects(env, this_obj, ph);
235 }
236
237 /*
238 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
239 * Method: attach0
240 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
241 */
242 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2
243 (JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) {
244 const char *execName_cstr;
245 const char *coreName_cstr;
246 jboolean isCopy;
247 struct ps_prochandle* ph;
248
258 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
259 (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
260 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");
261 }
262 (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
263 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
264 (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
265 fillThreadsAndLoadObjects(env, this_obj, ph);
266 }
267
268 /*
269 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
270 * Method: detach0
271 * Signature: ()V
272 */
273 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_detach0
274 (JNIEnv *env, jobject this_obj) {
275 struct ps_prochandle* ph = get_proc_handle(env, this_obj);
276 if (ph != NULL) {
277 Prelease(ph);
278 }
279 }
280
281 /*
282 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
283 * Method: lookupByName0
284 * Signature: (Ljava/lang/String;Ljava/lang/String;)J
285 */
286 JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByName0
287 (JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) {
288 const char *objectName_cstr, *symbolName_cstr;
289 jlong addr;
290 jboolean isCopy;
291 struct ps_prochandle* ph = get_proc_handle(env, this_obj);
292
293 objectName_cstr = NULL;
294 if (objectName != NULL) {
295 objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy);
296 CHECK_EXCEPTION_(0);
297 }
|
1 /*
2 * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
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 *
49 #include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h"
50 #endif
51
52 #if defined(ppc64) || defined(ppc64le)
53 #include "sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext.h"
54 #endif
55
56 #ifdef aarch64
57 #include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h"
58 #endif
59
60 static jfieldID p_ps_prochandle_ID = 0;
61 static jfieldID threadList_ID = 0;
62 static jfieldID loadObjectList_ID = 0;
63
64 static jmethodID createClosestSymbol_ID = 0;
65 static jmethodID createLoadObject_ID = 0;
66 static jmethodID getThreadForThreadId_ID = 0;
67 static jmethodID listAdd_ID = 0;
68
69 /*
70 * SA_ALTROOT environment variable.
71 * This memory holds env string for putenv(3).
72 */
73 static char *saaltroot = NULL;
74
75 #define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; }
76 #define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;}
77 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }
78 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}
79
80 void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
81 jclass clazz;
82 clazz = (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException");
83 CHECK_EXCEPTION;
84 (*env)->ThrowNew(env, clazz, errMsg);
85 }
86
87 struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {
88 jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID);
89 return (struct ps_prochandle*)(intptr_t)ptr;
90 }
91
92 /*
93 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
94 * Method: init0
200 int i = read(fd, &elf_ident, sizeof(elf_ident));
201 close(fd);
202
203 if (i < 0) {
204 THROW_NEW_DEBUGGER_EXCEPTION("cannot read binary file");
205 }
206 #ifndef _LP64
207 if (elf_ident[EI_CLASS] == ELFCLASS64) {
208 THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 64 bit, use 64-bit java for debugger");
209 }
210 #else
211 if (elf_ident[EI_CLASS] != ELFCLASS64) {
212 THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 32 bit, use 32 bit java for debugger");
213 }
214 #endif
215 }
216
217
218 /*
219 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
220 * Method: setSAAltRoot0
221 * Signature: (Ljava/lang/String;)V
222 */
223 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_setSAAltRoot0
224 (JNIEnv *env, jobject this_obj, jstring altroot) {
225 if (saaltroot != NULL) {
226 free(saaltroot);
227 }
228 const char *path = (*env)->GetStringUTFChars(env, altroot, JNI_FALSE);
229 /*
230 * `saaltroot` is used for putenv().
231 * So we need to keep this memory.
232 */
233 static const char *PREFIX = "SA_ALTROOT=";
234 size_t len = strlen(PREFIX) + strlen(path) + 1;
235 saaltroot = (char *)malloc(len);
236 snprintf(saaltroot, len, "%s%s", PREFIX, path);
237 putenv(saaltroot);
238 (*env)->ReleaseStringUTFChars(env, altroot, path);
239 }
240
241 /*
242 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
243 * Method: attach0
244 * Signature: (IZ)V
245 */
246 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__IZ
247 (JNIEnv *env, jobject this_obj, jint jpid, jboolean is_in_container) {
248
249 // For bitness checking, locate binary at /proc/jpid/exe
250 char buf[PATH_MAX];
251 snprintf((char *) &buf, PATH_MAX, "/proc/%d/exe", jpid);
252 verifyBitness(env, (char *) &buf);
253 CHECK_EXCEPTION;
254
255 char err_buf[200];
256 struct ps_prochandle* ph;
257 if ((ph = Pgrab(jpid, err_buf, sizeof(err_buf), is_in_container)) == NULL) {
258 char msg[230];
259 snprintf(msg, sizeof(msg), "Can't attach to the process: %s", err_buf);
260 THROW_NEW_DEBUGGER_EXCEPTION(msg);
261 }
262 (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
263 fillThreadsAndLoadObjects(env, this_obj, ph);
264 }
265
266 /*
267 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
268 * Method: attach0
269 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
270 */
271 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2
272 (JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) {
273 const char *execName_cstr;
274 const char *coreName_cstr;
275 jboolean isCopy;
276 struct ps_prochandle* ph;
277
287 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
288 (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
289 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");
290 }
291 (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
292 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
293 (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
294 fillThreadsAndLoadObjects(env, this_obj, ph);
295 }
296
297 /*
298 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
299 * Method: detach0
300 * Signature: ()V
301 */
302 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_detach0
303 (JNIEnv *env, jobject this_obj) {
304 struct ps_prochandle* ph = get_proc_handle(env, this_obj);
305 if (ph != NULL) {
306 Prelease(ph);
307 }
308 if (saaltroot != NULL) {
309 free(saaltroot);
310 saaltroot = NULL;
311 }
312 }
313
314 /*
315 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
316 * Method: lookupByName0
317 * Signature: (Ljava/lang/String;Ljava/lang/String;)J
318 */
319 JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByName0
320 (JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) {
321 const char *objectName_cstr, *symbolName_cstr;
322 jlong addr;
323 jboolean isCopy;
324 struct ps_prochandle* ph = get_proc_handle(env, this_obj);
325
326 objectName_cstr = NULL;
327 if (objectName != NULL) {
328 objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy);
329 CHECK_EXCEPTION_(0);
330 }
|