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

changeset 2838
405c634f4aaa
parent 1907
c18cbe5936b8
child 4037
da91efe96a93
     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  

mercurial