--- a/hotspot/agent/src/os/solaris/proc/libproc.h Tue May 03 13:01:41 2011 -0400
+++ b/hotspot/agent/src/os/solaris/proc/libproc.h Tue May 03 10:17:29 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -420,7 +420,22 @@
/*
* Stack frame iteration interface.
*/
+#ifdef SOLARIS_11_B159_OR_LATER
+/* building on Nevada-B159 or later so define the new callback */
+typedef int proc_stack_f(
+ void *, /* the cookie given to Pstack_iter() */
+ const prgregset_t, /* the frame's registers */
+ uint_t, /* argc for the frame's function */
+ const long *, /* argv for the frame's function */
+ int, /* bitwise flags describing the frame (see below) */
+ int); /* a signal number */
+
+#define PR_SIGNAL_FRAME 1 /* called by a signal handler */
+#define PR_FOUND_SIGNAL 2 /* we found the corresponding signal number */
+#else
+/* building on Nevada-B158 or earlier so define the old callback */
typedef int proc_stack_f(void *, const prgregset_t, uint_t, const long *);
+#endif
extern int Pstack_iter(struct ps_prochandle *,
const prgregset_t, proc_stack_f *, void *);
--- a/hotspot/agent/src/os/solaris/proc/salibproc.h Tue May 03 13:01:41 2011 -0400
+++ b/hotspot/agent/src/os/solaris/proc/salibproc.h Tue May 03 10:17:29 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -101,7 +101,23 @@
/*
* Stack frame iteration interface.
*/
+#ifdef SOLARIS_11_B159_OR_LATER
+/* building on Nevada-B159 or later so define the new callback */
+typedef int proc_stack_f(
+ void *, /* the cookie given to Pstack_iter() */
+ const prgregset_t, /* the frame's registers */
+ uint_t, /* argc for the frame's function */
+ const long *, /* argv for the frame's function */
+ int, /* bitwise flags describing the frame (see below) */
+ int); /* a signal number */
+
+#define PR_SIGNAL_FRAME 1 /* called by a signal handler */
+#define PR_FOUND_SIGNAL 2 /* we found the corresponding signal number */
+#else
+/* building on Nevada-B158 or earlier so define the old callback */
typedef int proc_stack_f(void *, const prgregset_t, uint_t, const long *);
+#endif
+
extern int Pstack_iter(struct ps_prochandle *,
const prgregset_t, proc_stack_f *, void *);
--- a/hotspot/agent/src/os/solaris/proc/saproc.cpp Tue May 03 13:01:41 2011 -0400
+++ b/hotspot/agent/src/os/solaris/proc/saproc.cpp Tue May 03 10:17:29 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,9 @@
#include "salibproc.h"
#include "sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal.h"
+#ifndef SOLARIS_11_B159_OR_LATER
+#include <sys/utsname.h>
+#endif
#include <thread_db.h>
#include <strings.h>
#include <limits.h>
@@ -40,8 +43,22 @@
#define SYMBOL_BUF_SIZE 256
#define ERR_MSG_SIZE (PATH_MAX + 256)
-// debug mode
+// debug modes
static int _libsaproc_debug = 0;
+#ifndef SOLARIS_11_B159_OR_LATER
+static bool _Pstack_iter_debug = false;
+
+static void dprintf_2(const char* format,...) {
+ if (_Pstack_iter_debug) {
+ va_list alist;
+
+ va_start(alist, format);
+ fputs("Pstack_iter DEBUG: ", stderr);
+ vfprintf(stderr, format, alist);
+ va_end(alist);
+ }
+}
+#endif // !SOLARIS_11_B159_OR_LATER
static void print_debug(const char* format,...) {
if (_libsaproc_debug) {
@@ -450,6 +467,7 @@
return 0;
}
+// Pstack_iter() proc_stack_f callback prior to Nevada-B159
static int
fill_cframe_list(void *cd, const prgregset_t regs, uint_t argc, const long *argv) {
DebuggerWith2Objects* dbgo2 = (DebuggerWith2Objects*) cd;
@@ -472,6 +490,14 @@
return 0;
}
+// Pstack_iter() proc_stack_f callback in Nevada-B159 or later
+/*ARGSUSED*/
+static int
+wrapper_fill_cframe_list(void *cd, const prgregset_t regs, uint_t argc,
+ const long *argv, int frame_flags, int sig) {
+ return(fill_cframe_list(cd, regs, argc, argv));
+}
+
// part of the class sharing workaround
// FIXME: !!HACK ALERT!!
@@ -970,6 +996,11 @@
TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
}
+#ifndef SOLARIS_11_B159_OR_LATER
+// building on Nevada-B158 or earlier so more hoops to jump through
+static bool has_newer_Pstack_iter = false; // older version by default
+#endif
+
/*
* Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
* Method: fillCFrameList0
@@ -997,7 +1028,24 @@
env->ReleaseLongArrayElements(regsArray, ptr, JNI_ABORT);
CHECK_EXCEPTION_(0);
- Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs, fill_cframe_list, &dbgo2);
+
+#ifdef SOLARIS_11_B159_OR_LATER
+ // building on Nevada-B159 or later so use the new callback
+ Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs,
+ wrapper_fill_cframe_list, &dbgo2);
+#else
+ // building on Nevada-B158 or earlier so figure out which callback to use
+
+ if (has_newer_Pstack_iter) {
+ // Since we're building on Nevada-B158 or earlier, we have to
+ // cast wrapper_fill_cframe_list to make the compiler happy.
+ Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs,
+ (proc_stack_f *)wrapper_fill_cframe_list, &dbgo2);
+ } else {
+ Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs,
+ fill_cframe_list, &dbgo2);
+ }
+#endif // SOLARIS_11_B159_OR_LATER
return dbgo2.obj;
}
@@ -1218,6 +1266,102 @@
return res;
}
+#ifndef SOLARIS_11_B159_OR_LATER
+// Determine if the OS we're running on has the newer version
+// of libproc's Pstack_iter.
+//
+// Set env var PSTACK_ITER_DEBUG=true to debug this logic.
+// Set env var PSTACK_ITER_DEBUG_RELEASE to simulate a 'release' value.
+// Set env var PSTACK_ITER_DEBUG_VERSION to simulate a 'version' value.
+//
+// frankenputer 'uname -r -v': 5.10 Generic_141445-09
+// jurassic 'uname -r -v': 5.11 snv_164
+// lonepeak 'uname -r -v': 5.11 snv_127
+//
+static void set_has_newer_Pstack_iter(JNIEnv *env) {
+ static bool done_set = false;
+
+ if (done_set) {
+ // already set has_newer_Pstack_iter
+ return;
+ }
+
+ struct utsname name;
+ if (uname(&name) == -1) {
+ THROW_NEW_DEBUGGER_EXCEPTION("uname() failed!");
+ }
+ dprintf_2("release='%s' version='%s'\n", name.release, name.version);
+
+ if (_Pstack_iter_debug) {
+ char *override = getenv("PSTACK_ITER_DEBUG_RELEASE");
+ if (override != NULL) {
+ strncpy(name.release, override, SYS_NMLN - 1);
+ name.release[SYS_NMLN - 2] = '\0';
+ dprintf_2("overriding with release='%s'\n", name.release);
+ }
+ override = getenv("PSTACK_ITER_DEBUG_VERSION");
+ if (override != NULL) {
+ strncpy(name.version, override, SYS_NMLN - 1);
+ name.version[SYS_NMLN - 2] = '\0';
+ dprintf_2("overriding with version='%s'\n", name.version);
+ }
+ }
+
+ // the major number corresponds to the old SunOS major number
+ int major = atoi(name.release);
+ if (major >= 6) {
+ dprintf_2("release is SunOS 6 or later\n");
+ has_newer_Pstack_iter = true;
+ done_set = true;
+ return;
+ }
+ if (major < 5) {
+ dprintf_2("release is SunOS 4 or earlier\n");
+ done_set = true;
+ return;
+ }
+
+ // some SunOS 5.* build so now check for Solaris versions
+ char *dot = strchr(name.release, '.');
+ int minor = 0;
+ if (dot != NULL) {
+ // release is major.minor format
+ *dot = NULL;
+ minor = atoi(dot + 1);
+ }
+
+ if (minor <= 10) {
+ dprintf_2("release is Solaris 10 or earlier\n");
+ done_set = true;
+ return;
+ } else if (minor >= 12) {
+ dprintf_2("release is Solaris 12 or later\n");
+ has_newer_Pstack_iter = true;
+ done_set = true;
+ return;
+ }
+
+ // some Solaris 11 build so now check for internal build numbers
+ if (strncmp(name.version, "snv_", 4) != 0) {
+ dprintf_2("release is Solaris 11 post-GA or later\n");
+ has_newer_Pstack_iter = true;
+ done_set = true;
+ return;
+ }
+
+ // version begins with "snv_" so a pre-GA build of Solaris 11
+ int build = atoi(&name.version[4]);
+ if (build >= 159) {
+ dprintf_2("release is Nevada-B159 or later\n");
+ has_newer_Pstack_iter = true;
+ } else {
+ dprintf_2("release is Nevada-B158 or earlier\n");
+ }
+
+ done_set = true;
+}
+#endif // !SOLARIS_11_B159_OR_LATER
+
/*
* Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
* Method: initIDs
@@ -1237,6 +1381,14 @@
if (libproc_handle == 0)
THROW_NEW_DEBUGGER_EXCEPTION("can't load libproc.so, if you are using Solaris 5.7 or below, copy libproc.so from 5.8!");
+#ifndef SOLARIS_11_B159_OR_LATER
+ _Pstack_iter_debug = getenv("PSTACK_ITER_DEBUG") != NULL;
+
+ set_has_newer_Pstack_iter(env);
+ CHECK_EXCEPTION;
+ dprintf_2("has_newer_Pstack_iter=%d\n", has_newer_Pstack_iter);
+#endif
+
p_ps_prochandle_ID = env->GetFieldID(clazz, "p_ps_prochandle", "J");
CHECK_EXCEPTION;
--- a/hotspot/make/linux/makefiles/gcc.make Tue May 03 13:01:41 2011 -0400
+++ b/hotspot/make/linux/makefiles/gcc.make Tue May 03 10:17:29 2011 -0700
@@ -205,7 +205,7 @@
SHARED_FLAG = -shared
# Keep symbols even they are not used
-AOUT_FLAGS += -export-dynamic
+AOUT_FLAGS += -Xlinker -export-dynamic
#------------------------------------------------------------------------
# Debug flags
--- a/hotspot/make/linux/makefiles/vm.make Tue May 03 13:01:41 2011 -0400
+++ b/hotspot/make/linux/makefiles/vm.make Tue May 03 10:17:29 2011 -0700
@@ -102,6 +102,10 @@
CFLAGS += $(EXTRA_CFLAGS)
LFLAGS += $(EXTRA_CFLAGS)
+# Don't set excutable bit on stack segment
+# the same could be done by separate execstack command
+LFLAGS += -Xlinker -z -Xlinker noexecstack
+
LIBS += -lm -ldl -lpthread
# By default, link the *.o into the library, not the executable.
--- a/hotspot/make/solaris/makefiles/saproc.make Tue May 03 13:01:41 2011 -0400
+++ b/hotspot/make/solaris/makefiles/saproc.make Tue May 03 10:17:29 2011 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -56,6 +56,30 @@
SA_LFLAGS += -mt -xnolib -norunpath
endif
+# The libproc Pstack_iter() interface changed in Nevada-B159.
+# This logic needs to match
+# agent/src/os/solaris/proc/saproc.cpp: set_has_newer_Pstack_iter():
+# - skip SunOS 4 or older
+# - skip Solaris 10 or older
+# - skip two digit Nevada builds
+# - skip three digit Nevada builds thru 149
+# - skip Nevada builds 150-158
+SOLARIS_11_B159_OR_LATER := \
+$(shell uname -r -v \
+ | sed -n ' \
+ /^[0-3]\. /b \
+ /^5\.[0-9] /b \
+ /^5\.10 /b \
+ / snv_[0-9][0-9]$/b \
+ / snv_[01][0-4][0-9]$/b \
+ / snv_15[0-8]$/b \
+ s/.*/-DSOLARIS_11_B159_OR_LATER/p \
+ ')
+
+# Uncomment the following to simulate building on Nevada-B159 or later
+# when actually building on Nevada-B158 or earlier:
+#SOLARIS_11_B159_OR_LATER=-DSOLARIS_11_B159_OR_LATER
+
$(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
$(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \
@@ -68,6 +92,7 @@
-I$(GENERATED) \
-I$(BOOT_JAVA_HOME)/include \
-I$(BOOT_JAVA_HOME)/include/$(Platform_os_family) \
+ $(SOLARIS_11_B159_OR_LATER) \
$(SASRCFILES) \
$(SA_LFLAGS) \
-o $@ \
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp Tue May 03 13:01:41 2011 -0400
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp Tue May 03 10:17:29 2011 -0700
@@ -1804,6 +1804,8 @@
}
void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) {
+ assert(name != NULL && name[0] != '\0', "sanity check");
+
JavaThread* thread = JavaThread::current();
// In theory everyone coming thru here is in_vm but we need to be certain
// because a callee will do a vm->native transition
--- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp Tue May 03 13:01:41 2011 -0400
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp Tue May 03 10:17:29 2011 -0700
@@ -38,6 +38,7 @@
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/javaCalls.hpp"
+#include "runtime/os.hpp"
#include "runtime/serviceThread.hpp"
#include "runtime/signature.hpp"
#include "runtime/vframe.hpp"
@@ -939,10 +940,15 @@
nmethodLocker::lock_nmethod(nm, true /* zombie_ok */);
return event;
}
+
JvmtiDeferredEvent JvmtiDeferredEvent::dynamic_code_generated_event(
const char* name, const void* code_begin, const void* code_end) {
JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_DYNAMIC_CODE_GENERATED);
- event._event_data.dynamic_code_generated.name = name;
+ // Need to make a copy of the name since we don't know how long
+ // the event poster will keep it around after we enqueue the
+ // deferred event and return. strdup() failure is handled in
+ // the post() routine below.
+ event._event_data.dynamic_code_generated.name = os::strdup(name);
event._event_data.dynamic_code_generated.code_begin = code_begin;
event._event_data.dynamic_code_generated.code_end = code_end;
return event;
@@ -968,12 +974,19 @@
nmethodLocker::unlock_nmethod(nm);
break;
}
- case TYPE_DYNAMIC_CODE_GENERATED:
+ case TYPE_DYNAMIC_CODE_GENERATED: {
JvmtiExport::post_dynamic_code_generated_internal(
- _event_data.dynamic_code_generated.name,
+ // if strdup failed give the event a default name
+ (_event_data.dynamic_code_generated.name == NULL)
+ ? "unknown_code" : _event_data.dynamic_code_generated.name,
_event_data.dynamic_code_generated.code_begin,
_event_data.dynamic_code_generated.code_end);
+ if (_event_data.dynamic_code_generated.name != NULL) {
+ // release our copy
+ os::free((void *)_event_data.dynamic_code_generated.name);
+ }
break;
+ }
default:
ShouldNotReachHere();
}