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