1.1 --- a/agent/src/os/solaris/proc/saproc.cpp Fri Apr 29 21:13:00 2011 +0400 1.2 +++ b/agent/src/os/solaris/proc/saproc.cpp Mon May 02 14:53:49 2011 -0700 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -24,6 +24,9 @@ 1.11 1.12 #include "salibproc.h" 1.13 #include "sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal.h" 1.14 +#ifndef SOLARIS_11_B159_OR_LATER 1.15 +#include <sys/utsname.h> 1.16 +#endif 1.17 #include <thread_db.h> 1.18 #include <strings.h> 1.19 #include <limits.h> 1.20 @@ -40,8 +43,22 @@ 1.21 #define SYMBOL_BUF_SIZE 256 1.22 #define ERR_MSG_SIZE (PATH_MAX + 256) 1.23 1.24 -// debug mode 1.25 +// debug modes 1.26 static int _libsaproc_debug = 0; 1.27 +#ifndef SOLARIS_11_B159_OR_LATER 1.28 +static bool _Pstack_iter_debug = false; 1.29 + 1.30 +static void dprintf_2(const char* format,...) { 1.31 + if (_Pstack_iter_debug) { 1.32 + va_list alist; 1.33 + 1.34 + va_start(alist, format); 1.35 + fputs("Pstack_iter DEBUG: ", stderr); 1.36 + vfprintf(stderr, format, alist); 1.37 + va_end(alist); 1.38 + } 1.39 +} 1.40 +#endif // !SOLARIS_11_B159_OR_LATER 1.41 1.42 static void print_debug(const char* format,...) { 1.43 if (_libsaproc_debug) { 1.44 @@ -450,6 +467,7 @@ 1.45 return 0; 1.46 } 1.47 1.48 +// Pstack_iter() proc_stack_f callback prior to Nevada-B159 1.49 static int 1.50 fill_cframe_list(void *cd, const prgregset_t regs, uint_t argc, const long *argv) { 1.51 DebuggerWith2Objects* dbgo2 = (DebuggerWith2Objects*) cd; 1.52 @@ -472,6 +490,14 @@ 1.53 return 0; 1.54 } 1.55 1.56 +// Pstack_iter() proc_stack_f callback in Nevada-B159 or later 1.57 +/*ARGSUSED*/ 1.58 +static int 1.59 +wrapper_fill_cframe_list(void *cd, const prgregset_t regs, uint_t argc, 1.60 + const long *argv, int frame_flags, int sig) { 1.61 + return(fill_cframe_list(cd, regs, argc, argv)); 1.62 +} 1.63 + 1.64 // part of the class sharing workaround 1.65 1.66 // FIXME: !!HACK ALERT!! 1.67 @@ -970,6 +996,11 @@ 1.68 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS); 1.69 } 1.70 1.71 +#ifndef SOLARIS_11_B159_OR_LATER 1.72 +// building on Nevada-B158 or earlier so more hoops to jump through 1.73 +static bool has_newer_Pstack_iter = false; // older version by default 1.74 +#endif 1.75 + 1.76 /* 1.77 * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal 1.78 * Method: fillCFrameList0 1.79 @@ -997,7 +1028,24 @@ 1.80 1.81 env->ReleaseLongArrayElements(regsArray, ptr, JNI_ABORT); 1.82 CHECK_EXCEPTION_(0); 1.83 - Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs, fill_cframe_list, &dbgo2); 1.84 + 1.85 +#ifdef SOLARIS_11_B159_OR_LATER 1.86 + // building on Nevada-B159 or later so use the new callback 1.87 + Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs, 1.88 + wrapper_fill_cframe_list, &dbgo2); 1.89 +#else 1.90 + // building on Nevada-B158 or earlier so figure out which callback to use 1.91 + 1.92 + if (has_newer_Pstack_iter) { 1.93 + // Since we're building on Nevada-B158 or earlier, we have to 1.94 + // cast wrapper_fill_cframe_list to make the compiler happy. 1.95 + Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs, 1.96 + (proc_stack_f *)wrapper_fill_cframe_list, &dbgo2); 1.97 + } else { 1.98 + Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs, 1.99 + fill_cframe_list, &dbgo2); 1.100 + } 1.101 +#endif // SOLARIS_11_B159_OR_LATER 1.102 return dbgo2.obj; 1.103 } 1.104 1.105 @@ -1218,6 +1266,102 @@ 1.106 return res; 1.107 } 1.108 1.109 +#ifndef SOLARIS_11_B159_OR_LATER 1.110 +// Determine if the OS we're running on has the newer version 1.111 +// of libproc's Pstack_iter. 1.112 +// 1.113 +// Set env var PSTACK_ITER_DEBUG=true to debug this logic. 1.114 +// Set env var PSTACK_ITER_DEBUG_RELEASE to simulate a 'release' value. 1.115 +// Set env var PSTACK_ITER_DEBUG_VERSION to simulate a 'version' value. 1.116 +// 1.117 +// frankenputer 'uname -r -v': 5.10 Generic_141445-09 1.118 +// jurassic 'uname -r -v': 5.11 snv_164 1.119 +// lonepeak 'uname -r -v': 5.11 snv_127 1.120 +// 1.121 +static void set_has_newer_Pstack_iter(JNIEnv *env) { 1.122 + static bool done_set = false; 1.123 + 1.124 + if (done_set) { 1.125 + // already set has_newer_Pstack_iter 1.126 + return; 1.127 + } 1.128 + 1.129 + struct utsname name; 1.130 + if (uname(&name) == -1) { 1.131 + THROW_NEW_DEBUGGER_EXCEPTION("uname() failed!"); 1.132 + } 1.133 + dprintf_2("release='%s' version='%s'\n", name.release, name.version); 1.134 + 1.135 + if (_Pstack_iter_debug) { 1.136 + char *override = getenv("PSTACK_ITER_DEBUG_RELEASE"); 1.137 + if (override != NULL) { 1.138 + strncpy(name.release, override, SYS_NMLN - 1); 1.139 + name.release[SYS_NMLN - 2] = '\0'; 1.140 + dprintf_2("overriding with release='%s'\n", name.release); 1.141 + } 1.142 + override = getenv("PSTACK_ITER_DEBUG_VERSION"); 1.143 + if (override != NULL) { 1.144 + strncpy(name.version, override, SYS_NMLN - 1); 1.145 + name.version[SYS_NMLN - 2] = '\0'; 1.146 + dprintf_2("overriding with version='%s'\n", name.version); 1.147 + } 1.148 + } 1.149 + 1.150 + // the major number corresponds to the old SunOS major number 1.151 + int major = atoi(name.release); 1.152 + if (major >= 6) { 1.153 + dprintf_2("release is SunOS 6 or later\n"); 1.154 + has_newer_Pstack_iter = true; 1.155 + done_set = true; 1.156 + return; 1.157 + } 1.158 + if (major < 5) { 1.159 + dprintf_2("release is SunOS 4 or earlier\n"); 1.160 + done_set = true; 1.161 + return; 1.162 + } 1.163 + 1.164 + // some SunOS 5.* build so now check for Solaris versions 1.165 + char *dot = strchr(name.release, '.'); 1.166 + int minor = 0; 1.167 + if (dot != NULL) { 1.168 + // release is major.minor format 1.169 + *dot = NULL; 1.170 + minor = atoi(dot + 1); 1.171 + } 1.172 + 1.173 + if (minor <= 10) { 1.174 + dprintf_2("release is Solaris 10 or earlier\n"); 1.175 + done_set = true; 1.176 + return; 1.177 + } else if (minor >= 12) { 1.178 + dprintf_2("release is Solaris 12 or later\n"); 1.179 + has_newer_Pstack_iter = true; 1.180 + done_set = true; 1.181 + return; 1.182 + } 1.183 + 1.184 + // some Solaris 11 build so now check for internal build numbers 1.185 + if (strncmp(name.version, "snv_", 4) != 0) { 1.186 + dprintf_2("release is Solaris 11 post-GA or later\n"); 1.187 + has_newer_Pstack_iter = true; 1.188 + done_set = true; 1.189 + return; 1.190 + } 1.191 + 1.192 + // version begins with "snv_" so a pre-GA build of Solaris 11 1.193 + int build = atoi(&name.version[4]); 1.194 + if (build >= 159) { 1.195 + dprintf_2("release is Nevada-B159 or later\n"); 1.196 + has_newer_Pstack_iter = true; 1.197 + } else { 1.198 + dprintf_2("release is Nevada-B158 or earlier\n"); 1.199 + } 1.200 + 1.201 + done_set = true; 1.202 +} 1.203 +#endif // !SOLARIS_11_B159_OR_LATER 1.204 + 1.205 /* 1.206 * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal 1.207 * Method: initIDs 1.208 @@ -1237,6 +1381,14 @@ 1.209 if (libproc_handle == 0) 1.210 THROW_NEW_DEBUGGER_EXCEPTION("can't load libproc.so, if you are using Solaris 5.7 or below, copy libproc.so from 5.8!"); 1.211 1.212 +#ifndef SOLARIS_11_B159_OR_LATER 1.213 + _Pstack_iter_debug = getenv("PSTACK_ITER_DEBUG") != NULL; 1.214 + 1.215 + set_has_newer_Pstack_iter(env); 1.216 + CHECK_EXCEPTION; 1.217 + dprintf_2("has_newer_Pstack_iter=%d\n", has_newer_Pstack_iter); 1.218 +#endif 1.219 + 1.220 p_ps_prochandle_ID = env->GetFieldID(clazz, "p_ps_prochandle", "J"); 1.221 CHECK_EXCEPTION; 1.222