< prev index next >

agent/src/os/solaris/proc/saproc.cpp

Print this page


   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");


< prev index next >