# HG changeset patch # User zgu # Date 1304443049 25200 # Node ID f7b5dc171e923fb5e138376b6f52b4e2635bab91 # Parent 250642c729b42043ea99e5e4e27d153b0c766da0# Parent 69e41359aef0c927847c5c3ed2db3ebc1e1f855e Merge diff -r 69e41359aef0 -r f7b5dc171e92 agent/src/os/solaris/proc/libproc.h --- a/agent/src/os/solaris/proc/libproc.h Tue May 03 13:01:41 2011 -0400 +++ b/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 *); diff -r 69e41359aef0 -r f7b5dc171e92 agent/src/os/solaris/proc/salibproc.h --- a/agent/src/os/solaris/proc/salibproc.h Tue May 03 13:01:41 2011 -0400 +++ b/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 *); diff -r 69e41359aef0 -r f7b5dc171e92 agent/src/os/solaris/proc/saproc.cpp --- a/agent/src/os/solaris/proc/saproc.cpp Tue May 03 13:01:41 2011 -0400 +++ b/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 +#endif #include #include #include @@ -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; diff -r 69e41359aef0 -r f7b5dc171e92 make/linux/makefiles/gcc.make --- a/make/linux/makefiles/gcc.make Tue May 03 13:01:41 2011 -0400 +++ b/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 diff -r 69e41359aef0 -r f7b5dc171e92 make/linux/makefiles/vm.make --- a/make/linux/makefiles/vm.make Tue May 03 13:01:41 2011 -0400 +++ b/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. diff -r 69e41359aef0 -r f7b5dc171e92 make/solaris/makefiles/saproc.make --- a/make/solaris/makefiles/saproc.make Tue May 03 13:01:41 2011 -0400 +++ b/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 $@ \ diff -r 69e41359aef0 -r f7b5dc171e92 src/share/vm/prims/jvmtiExport.cpp --- a/src/share/vm/prims/jvmtiExport.cpp Tue May 03 13:01:41 2011 -0400 +++ b/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 diff -r 69e41359aef0 -r f7b5dc171e92 src/share/vm/prims/jvmtiImpl.cpp --- a/src/share/vm/prims/jvmtiImpl.cpp Tue May 03 13:01:41 2011 -0400 +++ b/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(); }