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 *
23 */
24
25 #include "salibproc.h"
26 #include "sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal.h"
27 #ifndef SOLARIS_11_B159_OR_LATER
28 #include <sys/utsname.h>
29 #endif
30 #include <thread_db.h>
31 #include <strings.h>
32 #include <limits.h>
33 #include <demangle.h>
34 #include <stdarg.h>
35 #include <stdlib.h>
36 #include <errno.h>
37
38 #define CHECK_EXCEPTION_(value) if(env->ExceptionOccurred()) { return value; }
39 #define CHECK_EXCEPTION if(env->ExceptionOccurred()) { return;}
40 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throwNewDebuggerException(env, str); return value; }
41 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throwNewDebuggerException(env, str); return;}
42
43 #define SYMBOL_BUF_SIZE 256
44 #define ERR_MSG_SIZE (PATH_MAX + 256)
45
46 // debug modes
47 static int _libsaproc_debug = 0;
48 #ifndef SOLARIS_11_B159_OR_LATER
49 static bool _Pstack_iter_debug = false;
50
51 static void dprintf_2(const char* format,...) {
52 if (_Pstack_iter_debug) {
53 va_list alist;
54
55 va_start(alist, format);
56 fputs("Pstack_iter DEBUG: ", stderr);
57 vfprintf(stderr, format, alist);
58 va_end(alist);
59 }
60 }
61 #endif // !SOLARIS_11_B159_OR_LATER
62
63 static void print_debug(const char* format,...) {
64 if (_libsaproc_debug) {
65 va_list alist;
66
67 va_start(alist, format);
68 fputs("libsaproc DEBUG: ", stderr);
69 vfprintf(stderr, format, alist);
70 va_end(alist);
71 }
72 }
73
74 struct Debugger {
75 JNIEnv* env;
76 jobject this_obj;
77 };
78
79 struct DebuggerWithObject : Debugger {
80 jobject obj;
81 };
738 #ifndef _LP64
739 atoi(cmdLine_cstr);
740 if (errno) {
741 // core file
742 int core_fd;
743 if ((core_fd = open64(cmdLine_cstr, O_RDONLY)) >= 0) {
744 Elf32_Ehdr e32;
745 if (pread64(core_fd, &e32, sizeof (e32), 0) == sizeof (e32) &&
746 memcmp(&e32.e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0 &&
747 e32.e_type == ET_CORE && e32.e_ident[EI_CLASS] == ELFCLASS64) {
748 close(core_fd);
749 THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 64 bit, use java -d64 for debugger");
750 }
751 close(core_fd);
752 }
753 // all other conditions are handled by libproc.so.
754 }
755 #endif
756
757 // connect to process/core
758 struct ps_prochandle* ph = proc_arg_grab(cmdLine_cstr, (isProcess? PR_ARG_PIDS : PR_ARG_CORES), PGRAB_FORCE, &gcode);
759 env->ReleaseStringUTFChars(cmdLine, cmdLine_cstr);
760 if (! ph) {
761 if (gcode > 0 && gcode < sizeof(proc_arg_grab_errmsgs)/sizeof(const char*)) {
762 char errMsg[ERR_MSG_SIZE];
763 sprintf(errMsg, "Attach failed : %s", proc_arg_grab_errmsgs[gcode]);
764 THROW_NEW_DEBUGGER_EXCEPTION(errMsg);
765 } else {
766 if (_libsaproc_debug && gcode == G_STRANGE) {
767 perror("libsaproc DEBUG: ");
768 }
769 if (isProcess) {
770 THROW_NEW_DEBUGGER_EXCEPTION("Not able to attach to process!");
771 } else {
772 THROW_NEW_DEBUGGER_EXCEPTION("Not able to attach to core file!");
773 }
774 }
775 }
776
777 // even though libproc.so supports 64 bit debugger and 32 bit debuggee, we don't
778 // support such cross-bit-debugging. check for that combination and throw error.
977 */
978 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_fillThreadList0
979 (JNIEnv *env, jobject this_obj, jobject list) {
980
981 td_thragent_t* p_td_thragent_t = (td_thragent_t*) env->GetLongField(this_obj, p_td_thragent_t_ID);
982 if (p_td_thragent_t == 0) {
983 return;
984 }
985
986 p_td_ta_thr_iter_t p_td_ta_thr_iter = (p_td_ta_thr_iter_t) env->GetLongField(this_obj, p_td_ta_thr_iter_ID);
987
988 DebuggerWithObject dbgo;
989 dbgo.env = env;
990 dbgo.this_obj = this_obj;
991 dbgo.obj = list;
992
993 p_td_ta_thr_iter(p_td_thragent_t, fill_thread_list, &dbgo,
994 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
995 }
996
997 #ifndef SOLARIS_11_B159_OR_LATER
998 // building on Nevada-B158 or earlier so more hoops to jump through
999 static bool has_newer_Pstack_iter = false; // older version by default
1000 #endif
1001
1002 /*
1003 * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
1004 * Method: fillCFrameList0
1005 * Signature: ([J)Lsun/jvm/hotspot/debugger/proc/ProcCFrame;
1006 * Description: fills CFrame list for a given thread
1007 */
1008 JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_fillCFrameList0
1009 (JNIEnv *env, jobject this_obj, jlongArray regsArray) {
1010 jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
1011
1012 DebuggerWith2Objects dbgo2;
1013 dbgo2.env = env;
1014 dbgo2.this_obj = this_obj;
1015 dbgo2.obj = NULL;
1016 dbgo2.obj2 = NULL;
1017
1018 jboolean isCopy;
1019 jlong* ptr = env->GetLongArrayElements(regsArray, &isCopy);
1020 CHECK_EXCEPTION_(0);
1021
1022 prgregset_t gregs;
1023 for (int i = 0; i < NPRGREG; i++) {
1024 gregs[i] = (uintptr_t) ptr[i];
1025 }
1026
1027 env->ReleaseLongArrayElements(regsArray, ptr, JNI_ABORT);
1028 CHECK_EXCEPTION_(0);
1029
1030 #ifdef SOLARIS_11_B159_OR_LATER
1031 // building on Nevada-B159 or later so use the new callback
1032 Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs,
1033 wrapper_fill_cframe_list, &dbgo2);
1034 #else
1035 // building on Nevada-B158 or earlier so figure out which callback to use
1036
1037 if (has_newer_Pstack_iter) {
1038 // Since we're building on Nevada-B158 or earlier, we have to
1039 // cast wrapper_fill_cframe_list to make the compiler happy.
1040 Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs,
1041 (proc_stack_f *)wrapper_fill_cframe_list, &dbgo2);
1042 } else {
1043 Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs,
1044 fill_cframe_list, &dbgo2);
1045 }
1046 #endif // SOLARIS_11_B159_OR_LATER
1047 return dbgo2.obj;
1048 }
1049
1050 /*
1051 * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
1052 * Method: fillLoadObjectList0
1053 * Signature: (Ljava/util/List;)V
1054 * Description: fills shared objects of the debuggee process/core
1055 */
1056 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_fillLoadObjectList0
1057 (JNIEnv *env, jobject this_obj, jobject list) {
1058 DebuggerWithObject dbgo;
1059 dbgo.env = env;
1060 dbgo.this_obj = this_obj;
1061 dbgo.obj = list;
1062
1063 jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
1064 Pobject_iter((struct ps_prochandle*) p_ps_prochandle, fill_load_object_list, &dbgo);
1065 }
1066
1216 env->ReleaseStringUTFChars(objectName, objectName_cstr);
1217 }
1218 env->ReleaseStringUTFChars(symbolName, symbolName_cstr);
1219 return (jlong) (uintptr_t) symbol_addr;
1220 }
1221
1222 /*
1223 * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
1224 * Method: lookupByAddress0
1225 * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;
1226 * Description: lookup symbol name for a given address
1227 */
1228 JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_lookupByAddress0
1229 (JNIEnv *env, jobject this_obj, jlong address) {
1230 jlong p_ps_prochandle;
1231 p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
1232
1233 char nameBuf[SYMBOL_BUF_SIZE + 1];
1234 GElf_Sym sym;
1235 int res = Plookup_by_addr((struct ps_prochandle*) p_ps_prochandle, (uintptr_t) address,
1236 nameBuf, sizeof(nameBuf), &sym);
1237 if (res != 0) { // failed
1238 return 0;
1239 }
1240
1241 jstring resSym = env->NewStringUTF(nameBuf);
1242 CHECK_EXCEPTION_(0);
1243
1244 return env->CallObjectMethod(this_obj, createClosestSymbol_ID, resSym, (address - sym.st_value));
1245 }
1246
1247 /*
1248 * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
1249 * Method: demangle0
1250 * Signature: (Ljava/lang/String;)Ljava/lang/String;
1251 */
1252 JNIEXPORT jstring JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_demangle0
1253 (JNIEnv *env, jobject this_object, jstring name) {
1254 jboolean isCopy;
1255 const char* ptr = env->GetStringUTFChars(name, &isCopy);
1256 char buf[2*SYMBOL_BUF_SIZE + 1];
1257 jstring res = 0;
1258 if (cplus_demangle((char*) ptr, buf, sizeof(buf)) != DEMANGLE_ESPACE) {
1259 res = env->NewStringUTF(buf);
1260 } else {
1261 res = name;
1262 }
1263 env->ReleaseStringUTFChars(name, ptr);
1264 return res;
1265 }
1266
1267 #ifndef SOLARIS_11_B159_OR_LATER
1268 // Determine if the OS we're running on has the newer version
1269 // of libproc's Pstack_iter.
1270 //
1271 // Set env var PSTACK_ITER_DEBUG=true to debug this logic.
1272 // Set env var PSTACK_ITER_DEBUG_RELEASE to simulate a 'release' value.
1273 // Set env var PSTACK_ITER_DEBUG_VERSION to simulate a 'version' value.
1274 //
1275 // frankenputer 'uname -r -v': 5.10 Generic_141445-09
1276 // jurassic 'uname -r -v': 5.11 snv_164
1277 // lonepeak 'uname -r -v': 5.11 snv_127
1278 //
1279 static void set_has_newer_Pstack_iter(JNIEnv *env) {
1280 static bool done_set = false;
1281
1282 if (done_set) {
1283 // already set has_newer_Pstack_iter
1284 return;
1285 }
1286
1287 struct utsname name;
1288 if (uname(&name) == -1) {
1289 THROW_NEW_DEBUGGER_EXCEPTION("uname() failed!");
1290 }
1291 dprintf_2("release='%s' version='%s'\n", name.release, name.version);
1292
1293 if (_Pstack_iter_debug) {
1294 char *override = getenv("PSTACK_ITER_DEBUG_RELEASE");
1295 if (override != NULL) {
1296 strncpy(name.release, override, SYS_NMLN - 1);
1297 name.release[SYS_NMLN - 2] = '\0';
1298 dprintf_2("overriding with release='%s'\n", name.release);
1299 }
1300 override = getenv("PSTACK_ITER_DEBUG_VERSION");
1301 if (override != NULL) {
1302 strncpy(name.version, override, SYS_NMLN - 1);
1303 name.version[SYS_NMLN - 2] = '\0';
1304 dprintf_2("overriding with version='%s'\n", name.version);
1305 }
1306 }
1307
1308 // the major number corresponds to the old SunOS major number
1309 int major = atoi(name.release);
1310 if (major >= 6) {
1311 dprintf_2("release is SunOS 6 or later\n");
1312 has_newer_Pstack_iter = true;
1313 done_set = true;
1314 return;
1315 }
1316 if (major < 5) {
1317 dprintf_2("release is SunOS 4 or earlier\n");
1318 done_set = true;
1319 return;
1320 }
1321
1322 // some SunOS 5.* build so now check for Solaris versions
1323 char *dot = strchr(name.release, '.');
1324 int minor = 0;
1325 if (dot != NULL) {
1326 // release is major.minor format
1327 *dot = NULL;
1328 minor = atoi(dot + 1);
1329 }
1330
1331 if (minor <= 10) {
1332 dprintf_2("release is Solaris 10 or earlier\n");
1333 done_set = true;
1334 return;
1335 } else if (minor >= 12) {
1336 dprintf_2("release is Solaris 12 or later\n");
1337 has_newer_Pstack_iter = true;
1338 done_set = true;
1339 return;
1340 }
1341
1342 // some Solaris 11 build so now check for internal build numbers
1343 if (strncmp(name.version, "snv_", 4) != 0) {
1344 dprintf_2("release is Solaris 11 post-GA or later\n");
1345 has_newer_Pstack_iter = true;
1346 done_set = true;
1347 return;
1348 }
1349
1350 // version begins with "snv_" so a pre-GA build of Solaris 11
1351 int build = atoi(&name.version[4]);
1352 if (build >= 159) {
1353 dprintf_2("release is Nevada-B159 or later\n");
1354 has_newer_Pstack_iter = true;
1355 } else {
1356 dprintf_2("release is Nevada-B158 or earlier\n");
1357 }
1358
1359 done_set = true;
1360 }
1361 #endif // !SOLARIS_11_B159_OR_LATER
1362
1363 /*
1364 * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
1365 * Method: initIDs
1366 * Signature: ()V
1367 * Description: get JNI ids for fields and methods of ProcDebuggerLocal class
1368 */
1369 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_initIDs
1370 (JNIEnv *env, jclass clazz) {
1371 _libsaproc_debug = getenv("LIBSAPROC_DEBUG") != NULL;
1372 if (_libsaproc_debug) {
1373 // propagate debug mode to libproc.so
1374 static const char* var = "LIBPROC_DEBUG=1";
1375 putenv((char*)var);
1376 }
1377
1378 void* libproc_handle = dlopen("libproc.so", RTLD_LAZY | RTLD_GLOBAL);
1379 if (libproc_handle == 0)
1380 THROW_NEW_DEBUGGER_EXCEPTION("can't load libproc.so, if you are using Solaris 5.7 or below, copy libproc.so from 5.8!");
1381
1382 #ifndef SOLARIS_11_B159_OR_LATER
1383 _Pstack_iter_debug = getenv("PSTACK_ITER_DEBUG") != NULL;
1384
1385 set_has_newer_Pstack_iter(env);
1386 CHECK_EXCEPTION;
1387 dprintf_2("has_newer_Pstack_iter=%d\n", has_newer_Pstack_iter);
1388 #endif
1389
1390 p_ps_prochandle_ID = env->GetFieldID(clazz, "p_ps_prochandle", "J");
1391 CHECK_EXCEPTION;
1392
1393 libthread_db_handle_ID = env->GetFieldID(clazz, "libthread_db_handle", "J");
1394 CHECK_EXCEPTION;
1395
1396 p_td_thragent_t_ID = env->GetFieldID(clazz, "p_td_thragent_t", "J");
1397 CHECK_EXCEPTION;
1398
1399 p_td_init_ID = env->GetFieldID(clazz, "p_td_init", "J");
1400 CHECK_EXCEPTION;
1401
1402 p_td_ta_new_ID = env->GetFieldID(clazz, "p_td_ta_new", "J");
1403 CHECK_EXCEPTION;
1404
1405 p_td_ta_delete_ID = env->GetFieldID(clazz, "p_td_ta_delete", "J");
1406 CHECK_EXCEPTION;
1407
1408 p_td_ta_thr_iter_ID = env->GetFieldID(clazz, "p_td_ta_thr_iter", "J");
|
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 *
23 */
24
25 #include "salibproc.h"
26 #include "sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal.h"
27 #include <thread_db.h>
28 #include <strings.h>
29 #include <limits.h>
30 #include <demangle.h>
31 #include <stdarg.h>
32 #include <stdlib.h>
33 #include <errno.h>
34
35 #define CHECK_EXCEPTION_(value) if(env->ExceptionOccurred()) { return value; }
36 #define CHECK_EXCEPTION if(env->ExceptionOccurred()) { return;}
37 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throwNewDebuggerException(env, str); return value; }
38 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throwNewDebuggerException(env, str); return;}
39
40 #define SYMBOL_BUF_SIZE 256
41 #define ERR_MSG_SIZE (PATH_MAX + 256)
42
43 // debug modes
44 static int _libsaproc_debug = 0;
45
46 static void print_debug(const char* format,...) {
47 if (_libsaproc_debug) {
48 va_list alist;
49
50 va_start(alist, format);
51 fputs("libsaproc DEBUG: ", stderr);
52 vfprintf(stderr, format, alist);
53 va_end(alist);
54 }
55 }
56
57 struct Debugger {
58 JNIEnv* env;
59 jobject this_obj;
60 };
61
62 struct DebuggerWithObject : Debugger {
63 jobject obj;
64 };
721 #ifndef _LP64
722 atoi(cmdLine_cstr);
723 if (errno) {
724 // core file
725 int core_fd;
726 if ((core_fd = open64(cmdLine_cstr, O_RDONLY)) >= 0) {
727 Elf32_Ehdr e32;
728 if (pread64(core_fd, &e32, sizeof (e32), 0) == sizeof (e32) &&
729 memcmp(&e32.e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0 &&
730 e32.e_type == ET_CORE && e32.e_ident[EI_CLASS] == ELFCLASS64) {
731 close(core_fd);
732 THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 64 bit, use java -d64 for debugger");
733 }
734 close(core_fd);
735 }
736 // all other conditions are handled by libproc.so.
737 }
738 #endif
739
740 // connect to process/core
741 ps_prochandle_t* ph = proc_arg_grab(cmdLine_cstr, (isProcess? PR_ARG_PIDS : PR_ARG_CORES), PGRAB_FORCE, &gcode, NULL);
742
743 env->ReleaseStringUTFChars(cmdLine, cmdLine_cstr);
744 if (! ph) {
745 if (gcode > 0 && gcode < sizeof(proc_arg_grab_errmsgs)/sizeof(const char*)) {
746 char errMsg[ERR_MSG_SIZE];
747 sprintf(errMsg, "Attach failed : %s", proc_arg_grab_errmsgs[gcode]);
748 THROW_NEW_DEBUGGER_EXCEPTION(errMsg);
749 } else {
750 if (_libsaproc_debug && gcode == G_STRANGE) {
751 perror("libsaproc DEBUG: ");
752 }
753 if (isProcess) {
754 THROW_NEW_DEBUGGER_EXCEPTION("Not able to attach to process!");
755 } else {
756 THROW_NEW_DEBUGGER_EXCEPTION("Not able to attach to core file!");
757 }
758 }
759 }
760
761 // even though libproc.so supports 64 bit debugger and 32 bit debuggee, we don't
762 // support such cross-bit-debugging. check for that combination and throw error.
961 */
962 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_fillThreadList0
963 (JNIEnv *env, jobject this_obj, jobject list) {
964
965 td_thragent_t* p_td_thragent_t = (td_thragent_t*) env->GetLongField(this_obj, p_td_thragent_t_ID);
966 if (p_td_thragent_t == 0) {
967 return;
968 }
969
970 p_td_ta_thr_iter_t p_td_ta_thr_iter = (p_td_ta_thr_iter_t) env->GetLongField(this_obj, p_td_ta_thr_iter_ID);
971
972 DebuggerWithObject dbgo;
973 dbgo.env = env;
974 dbgo.this_obj = this_obj;
975 dbgo.obj = list;
976
977 p_td_ta_thr_iter(p_td_thragent_t, fill_thread_list, &dbgo,
978 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
979 }
980
981 /*
982 * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
983 * Method: fillCFrameList0
984 * Signature: ([J)Lsun/jvm/hotspot/debugger/proc/ProcCFrame;
985 * Description: fills CFrame list for a given thread
986 */
987 JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_fillCFrameList0
988 (JNIEnv *env, jobject this_obj, jlongArray regsArray) {
989 jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
990
991 DebuggerWith2Objects dbgo2;
992 dbgo2.env = env;
993 dbgo2.this_obj = this_obj;
994 dbgo2.obj = NULL;
995 dbgo2.obj2 = NULL;
996
997 jboolean isCopy;
998 jlong* ptr = env->GetLongArrayElements(regsArray, &isCopy);
999 CHECK_EXCEPTION_(0);
1000
1001 prgregset_t gregs;
1002 for (int i = 0; i < NPRGREG; i++) {
1003 gregs[i] = (uintptr_t) ptr[i];
1004 }
1005
1006 env->ReleaseLongArrayElements(regsArray, ptr, JNI_ABORT);
1007 CHECK_EXCEPTION_(0);
1008
1009 Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs,
1010 wrapper_fill_cframe_list, &dbgo2);
1011 return dbgo2.obj;
1012 }
1013
1014 /*
1015 * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
1016 * Method: fillLoadObjectList0
1017 * Signature: (Ljava/util/List;)V
1018 * Description: fills shared objects of the debuggee process/core
1019 */
1020 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_fillLoadObjectList0
1021 (JNIEnv *env, jobject this_obj, jobject list) {
1022 DebuggerWithObject dbgo;
1023 dbgo.env = env;
1024 dbgo.this_obj = this_obj;
1025 dbgo.obj = list;
1026
1027 jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
1028 Pobject_iter((struct ps_prochandle*) p_ps_prochandle, fill_load_object_list, &dbgo);
1029 }
1030
1180 env->ReleaseStringUTFChars(objectName, objectName_cstr);
1181 }
1182 env->ReleaseStringUTFChars(symbolName, symbolName_cstr);
1183 return (jlong) (uintptr_t) symbol_addr;
1184 }
1185
1186 /*
1187 * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
1188 * Method: lookupByAddress0
1189 * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;
1190 * Description: lookup symbol name for a given address
1191 */
1192 JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_lookupByAddress0
1193 (JNIEnv *env, jobject this_obj, jlong address) {
1194 jlong p_ps_prochandle;
1195 p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
1196
1197 char nameBuf[SYMBOL_BUF_SIZE + 1];
1198 GElf_Sym sym;
1199 int res = Plookup_by_addr((struct ps_prochandle*) p_ps_prochandle, (uintptr_t) address,
1200 nameBuf, sizeof(nameBuf), &sym, NULL);
1201 if (res != 0) { // failed
1202 return 0;
1203 }
1204
1205 jstring resSym = env->NewStringUTF(nameBuf);
1206 CHECK_EXCEPTION_(0);
1207
1208 return env->CallObjectMethod(this_obj, createClosestSymbol_ID, resSym, (address - sym.st_value));
1209 }
1210
1211 /*
1212 * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
1213 * Method: demangle0
1214 * Signature: (Ljava/lang/String;)Ljava/lang/String;
1215 */
1216 JNIEXPORT jstring JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_demangle0
1217 (JNIEnv *env, jobject this_object, jstring name) {
1218 jboolean isCopy;
1219 const char* ptr = env->GetStringUTFChars(name, &isCopy);
1220 char buf[2*SYMBOL_BUF_SIZE + 1];
1221 jstring res = 0;
1222 if (cplus_demangle((char*) ptr, buf, sizeof(buf)) != DEMANGLE_ESPACE) {
1223 res = env->NewStringUTF(buf);
1224 } else {
1225 res = name;
1226 }
1227 env->ReleaseStringUTFChars(name, ptr);
1228 return res;
1229 }
1230
1231 /*
1232 * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
1233 * Method: initIDs
1234 * Signature: ()V
1235 * Description: get JNI ids for fields and methods of ProcDebuggerLocal class
1236 */
1237 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_initIDs
1238 (JNIEnv *env, jclass clazz) {
1239 _libsaproc_debug = getenv("LIBSAPROC_DEBUG") != NULL;
1240 if (_libsaproc_debug) {
1241 // propagate debug mode to libproc.so
1242 static const char* var = "LIBPROC_DEBUG=1";
1243 putenv((char*)var);
1244 }
1245
1246 void* libproc_handle = dlopen("libproc.so", RTLD_LAZY | RTLD_GLOBAL);
1247 if (libproc_handle == 0)
1248 THROW_NEW_DEBUGGER_EXCEPTION("can't load libproc.so, if you are using Solaris 5.7 or below, copy libproc.so from 5.8!");
1249
1250 p_ps_prochandle_ID = env->GetFieldID(clazz, "p_ps_prochandle", "J");
1251 CHECK_EXCEPTION;
1252
1253 libthread_db_handle_ID = env->GetFieldID(clazz, "libthread_db_handle", "J");
1254 CHECK_EXCEPTION;
1255
1256 p_td_thragent_t_ID = env->GetFieldID(clazz, "p_td_thragent_t", "J");
1257 CHECK_EXCEPTION;
1258
1259 p_td_init_ID = env->GetFieldID(clazz, "p_td_init", "J");
1260 CHECK_EXCEPTION;
1261
1262 p_td_ta_new_ID = env->GetFieldID(clazz, "p_td_ta_new", "J");
1263 CHECK_EXCEPTION;
1264
1265 p_td_ta_delete_ID = env->GetFieldID(clazz, "p_td_ta_delete", "J");
1266 CHECK_EXCEPTION;
1267
1268 p_td_ta_thr_iter_ID = env->GetFieldID(clazz, "p_td_ta_thr_iter", "J");
|