diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2008-02-15 14:29:08 -0500 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2008-02-15 14:29:08 -0500 |
commit | 0f05501579dc0a4e66ccbbd8e0b29d052d9b5920 (patch) | |
tree | 79bf8b7b328e87e8c30cc64e64a1bea9a6f2dca5 | |
parent | 044427bcdfa2a1d58a912bf96546892bef82b717 (diff) | |
parent | 275f40a6d612f94e5272eeed772e9c9294cb8e1f (diff) | |
download | systemtap-steved-0f05501579dc0a4e66ccbbd8e0b29d052d9b5920.tar.gz systemtap-steved-0f05501579dc0a4e66ccbbd8e0b29d052d9b5920.tar.xz systemtap-steved-0f05501579dc0a4e66ccbbd8e0b29d052d9b5920.zip |
Merge branch 'master' of git://sources.redhat.com/git/systemtap
69 files changed, 1402 insertions, 454 deletions
@@ -1,3 +1,128 @@ +2008-02-15 Frank Ch. Eigler <fche@elastic.org> + + * tapsets.cxx (function_name_last_match): New function. + (query_dwarf_func): Call it to stop unnecessary further iteration. + +2008-02-13 Frank Ch. Eigler <fche@elastic.org> + + PR 5759 + * tapsets.cxx (build_blacklist): Add some CONFIG_PREEMPT-related + functions. + +2008-02-13 Dave Brolley <brolley@redhat.com> + + PR5609 + * staptree.h (probe::collect_derivation_chain): Now takes vector<probe*>. + (probe::get_alias): New virtual method. + * elaborate.h (derived_probe::collect_derivation_chain): Now takes vector<probe*>. + * staptree.cxx (probe::collect_derivation_chain): Now takes vector<probe*>. Don't + cast 'this' to (derived_probe*). + * elaborate.cxx (derived_probe::collect_derivation_chain): Now takes vector<probe*>. + (alias_derived_probe::get_alias): New virtual method. + (alias_derived_probe::alias): New member. + (alias_expansion_builder::build): Call checkForRecursiveExpansion and emit a + diagnostic if recursion is detected. Pass alias to constructor of + alias_derived_probe. + (alias_expansion_builder::checkForRecursiveExpansion): New method. + * coveragedb.cxx: Pass vector<probe*> on all calls to collect_derivation_chain. + +2008-02-12 Frank Ch. Eigler <fche@elastic.org> + + PR 4393 + * tapsets.cxx (emit_address): Support relocatable kernels. + (dwarf_derived_probe ctor): Hack around for missing USHRT_MAX. + * elaborate.cxx (semantic_pass): Increment rc if exception caught. + +2008-02-12 Martin Hunt <hunt@redhat.com> + PR 5757 + * tapsets.cxx, translate.cxx: Cleanup indentation a bit. + +2008-02-11 Jim Keniston <jkenisto@us.ibm.com> + + PR 5693 + * runtime/uprobes/uprobes.c: Intercept handler-destined + signals received while we're single-stepping, and re-queue + them afterward. + * runtime/uprobes/uprobes.h: Ditto + +2008-02-09 Frank Ch. Eigler <fche@elastic.org> + + PR5750. + From Eugeniy Meshcheryakov eugen@debian.org: + * configure.ac (HAVE_LIBSQLITE3): Complete AC_DEFINE. + + * configure, INSTALL, missing, compile, depcomp, install-sh: + autoreconf -fi'd. + +2008-02-09 Frank Ch. Eigler <fche@elastic.org> + + PR 5751. + * configure.ac: Add -Werror to trial compilation with + -fstack-protector-all, for hosts that don't quite support it. + * configure: Regenerated. + +2008-02-08 David Smith <dsmith@redhat.com> + + PR 5650 + * systemtap.spec.in: Further simplification. + +2008-02-07 Frank Ch. Eigler <fche@elastic.org> + + * buildrun.cxx (run_make_cmd, compile_pass): Tweak kbuild + parametrization to produce useful compile logs at -vv. + +2008-02-04 David Smith <dsmith@redhat.com> + + PR 4446 (partial) + * tapsets.cxx + (mark_var_expanding_copy_visitor::visit_target_symbol_arg): New + function. + (mark_var_expanding_copy_visitor::visit_target_symbol_format): New + function. + (mark_var_expanding_copy_visitor::visit_target_symbol): Handles + "$arg" or "$format". + (mark_derived_probe_group::emit_module_decls): Sets up "$format" + data. + + PR 5650 (parital) + * systemtap.spec.in: Moved %pre section to the systemtap-runtime + rpm. + +2008-01-30 David Smith <dsmith@redhat.com> + + PR 5650 + * systemtap.spec.in: Simplified and explicitly specifies configure + options. + +2008-01-30 Dave Brolley <brolley@redhat.com> + + * coveragedb.cxx (print_coverage_info): Fix typo: s.probes -> s.unused_probes + where appropriate. + (sql_update_unused_probes): Likewise. + +2008-01-29 Frank Ch. Eigler <fche@elastic.org> + + PR 5647 + * configure.ac (--enable-ssp): Make default on compilers that + support it. + * configure: Regenerated. + +2008-01-28 David Smith <dsmith@redhat.com> + + * configure.ac: Fixed a bug when "--disable-permon" was used. + Added "--enable-crash" option. + * configure: Regenerated. + * Makefile.am: Improved staplog.so compile command. + * Makefile.in: Regenerated. + + * tapsets.cxx (dwarf_derived_probe_group::emit_module_decls): + Added 'const' to several members of stap_dwarf_probes. + + PR 5685. From Eugeniy Meshcheryakov <eugen@debian.org> + * configure.ac: If "--enable-sqlite" is specified, define + HAVE_LIBSQLITE3. + * configure: Regenerated. + 2008-01-26 Frank Ch. Eigler <fche@elastic.org> PR 5673. @@ -131,6 +256,12 @@ error when trying to use the perfmon target variable '$counter as an array or structure. +2008-01-17 Srinivasa DS <srinivasa@in.ibm.com> + + PR 5483. + * tapsets.cxx (emit_address): Tolerate dummy relocation entry + added for kernel by recent elfutils. + 2008-01-16 David Smith <dsmith@redhat.com> PR 5608. @@ -1,8 +1,8 @@ Installation Instructions ************************* -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free -Software Foundation, Inc. +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. @@ -10,7 +10,10 @@ unlimited permission to copy, distribute and modify it. Basic Installation ================== -These are generic installation instructions. +Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses @@ -23,9 +26,9 @@ debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is +the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale -cache files.) +cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail @@ -35,20 +38,17 @@ some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. + `./configure' to configure the package for your system. - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. 2. Type `make' to compile the package. @@ -78,7 +78,7 @@ details on some of the pertinent environment variables. by setting variables in the command line or in the environment. Here is an example: - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. @@ -87,31 +87,29 @@ Compiling For Multiple Architectures You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the +own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. Installation Names ================== -By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PREFIX'. +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PREFIX', the package will -use PREFIX as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular @@ -159,7 +157,7 @@ where SYSTEM can have one of these forms: need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should -use the `--target=TYPE' option to select the type of system they will +use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a @@ -189,9 +187,14 @@ them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc -will cause the specified gcc to be used as the C compiler (unless it is +causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + `configure' Invocation ====================== diff --git a/Makefile.am b/Makefile.am index 291adfd9..cfdc051d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -88,12 +88,12 @@ if BUILD_CRASHMOD STAPLOG=staplog.so $(STAPLOG): staplog.c - $(CC) -Wall -shared -rdynamic $(LDFLAGS) $(CFLAGS) -fPIC -o $@ $< + $(CC) $(staplog_CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -shared -rdynamic \ + $(AM_LDFLAGS) $(LDFLAGS) -fPIC -o $@ $< all-local: $(STAPLOG) install-exec-local: $(STAPLOG) $(MKDIR_P) $(DESTDIR)$(pkglibdir) $(INSTALL) $(STAPLOG) $(DESTDIR)$(pkglibdir) -else endif # Get extra libs as needed diff --git a/Makefile.in b/Makefile.in index d92d7a94..b3ad3c74 100644 --- a/Makefile.in +++ b/Makefile.in @@ -181,7 +181,6 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ELFUTILS_REQUIRED_VERSION = @ELFUTILS_REQUIRED_VERSION@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ @@ -254,6 +253,7 @@ sharedstatedir = @sharedstatedir@ sqlite3_LIBS = @sqlite3_LIBS@ srcdir = @srcdir@ stap_LIBS = @stap_LIBS@ +staplog_CPPFLAGS = @staplog_CPPFLAGS@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ @@ -1474,7 +1474,8 @@ install-exec-hook: if [ `id -u` -eq 0 ]; then chmod 04111 "$(DESTDIR)$(bindir)/staprun"; fi @BUILD_CRASHMOD_TRUE@$(STAPLOG): staplog.c -@BUILD_CRASHMOD_TRUE@ $(CC) -Wall -shared -rdynamic $(LDFLAGS) $(CFLAGS) -fPIC -o $@ $< +@BUILD_CRASHMOD_TRUE@ $(CC) $(staplog_CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -shared -rdynamic \ +@BUILD_CRASHMOD_TRUE@ $(AM_LDFLAGS) $(LDFLAGS) -fPIC -o $@ $< @BUILD_CRASHMOD_TRUE@all-local: $(STAPLOG) @BUILD_CRASHMOD_TRUE@install-exec-local: $(STAPLOG) @BUILD_CRASHMOD_TRUE@ $(MKDIR_P) $(DESTDIR)$(pkglibdir) diff --git a/buildrun.cxx b/buildrun.cxx index b41b9545..66cc4986 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -47,8 +47,10 @@ run_make_cmd(systemtap_session& s, string& make_cmd) cerr << "unsetenv failed: " << e << endl; } - if (s.verbose > 1) + if (s.verbose > 2) make_cmd += " V=1"; + else if (s.verbose > 1) + make_cmd += " >/dev/null"; else make_cmd += " -s >/dev/null 2>&1"; @@ -73,7 +75,7 @@ compile_pass (systemtap_session& s) // Clever hacks copied from vmware modules o << "stap_check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo \"$(1)\"; else echo \"$(2)\"; fi)" << endl; - o << "stap_check_build = $(shell " << "set -x; " << " if $(CC) $(KBUILD_CPPFLAGS) $(CPPFLAGS) $(KBUILD_CFLAGS) $(CFLAGS_KERNEL) $(EXTRA_CFLAGS) $(CFLAGS) -DKBUILD_BASENAME=\\\"" << s.module_name << "\\\" -Werror -S -o /dev/null -xc $(1) > /dev/null ; then echo \"$(2)\"; else echo \"$(3)\"; fi)" << endl; + o << "stap_check_build = $(shell if $(CC) $(KBUILD_CPPFLAGS) $(CPPFLAGS) $(KBUILD_CFLAGS) $(CFLAGS_KERNEL) $(EXTRA_CFLAGS) $(CFLAGS) -DKBUILD_BASENAME=\\\"" << s.module_name << "\\\" -Werror -S -o /dev/null -xc $(1) > /dev/null 2>&1 ; then echo \"$(2)\"; else echo \"$(3)\"; fi)" << endl; o << "SYSTEMTAP_RUNTIME = \"" << s.runtime_path << "\"" << endl; @@ -1,7 +1,7 @@ #! /bin/sh # Wrapper for compilers which do not understand `-c -o'. -scriptversion=2005-02-03.08 +scriptversion=2005-05-14.22 # Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. # Written by Tom Tromey <tromey@cygnus.com>. @@ -18,7 +18,7 @@ scriptversion=2005-02-03.08 # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -706,6 +706,7 @@ U ANSI2KNR RANLIB sqlite3_LIBS +staplog_CPPFLAGS BUILD_CRASHMOD_TRUE BUILD_CRASHMOD_FALSE BUILD_ELFUTILS_TRUE @@ -1316,8 +1317,13 @@ Optional Features: installation (needed if installed in a non-standard location). --enable-prologues make -P prologue-searching default - --enable-ssp enable gcc stack-protector + --disable-ssp disable gcc stack-protector --enable-sqlite build with sqlite support + --enable-crash[=DIRECTORY] + enable crash extension (default is disabled). + Optional DIRECTORY is the path to the crash header + file (needed if installed in a non-standard + location). Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -5828,14 +5834,13 @@ fi # Check whether --enable-perfmon was given. if test "${enable_perfmon+set}" = set; then enableval=$enable_perfmon; - CFLAGS="$CFLAGS -DPERFMON" - CXXFLAGS="$CXXFLAGS -DPERFMON" - LIBS="$LIBS -lpfm" - if test "$enable_perfmon" != "yes"; then - CFLAGS="$CFLAGS -I$enable_perfmon/include" - CXXFLAGS="$CXXFLAGS -I$enable_perfmon/include" - LDFLAGS="$LDFLAGS -L$enable_perfmon/lib" - fi + if test "$enable_perfmon" != "no"; then + CPPFLAGS="$CPPFLAGS -DPERFMON" + LIBS="$LIBS -lpfm" + if test "$enable_perfmon" != "yes"; then + CPPFLAGS="$CPPFLAGS -I$enable_perfmon/include" + LDFLAGS="$LDFLAGS -L$enable_perfmon/lib" + fi { echo "$as_me:$LINENO: checking for pfm_start in -lpfm" >&5 echo $ECHO_N "checking for pfm_start in -lpfm... $ECHO_C" >&6; } @@ -5907,12 +5912,12 @@ _ACEOF else - { { echo "$as_me:$LINENO: error: systemtap cannot find required perfmon libs" >&5 -echo "$as_me: error: systemtap cannot find required perfmon libs" >&2;} + { { echo "$as_me:$LINENO: error: systemtap cannot find required perfmon libs (libpfm-devel may need to be installed" >&5 +echo "$as_me: error: systemtap cannot find required perfmon libs (libpfm-devel may need to be installed" >&2;} { (exit 1); exit 1; }; } fi - + fi fi @@ -5943,17 +5948,54 @@ fi fi - # Check whether --enable-ssp was given. if test "${enable_ssp+set}" = set; then enableval=$enable_ssp; fi -if test "x$enable_ssp" == xyes; then - CFLAGS="$CFLAGS -fstack-protector-all -D_FORTIFY_SOURCE=2" - CXXFLAGS="$CXXFLAGS -fstack-protector-all -D_FORTIFY_SOURCE=2" - { echo "$as_me:$LINENO: Compiling with gcc -fstack-protector-all et al." >&5 +if test "x$enable_ssp" != xno; then + + save_CFLAGS="$CFLAGS" + save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -Werror -fstack-protector-all -D_FORTIFY_SOURCE=2" + CFLAGS="$CFLAGS -Werror -fstack-protector-all -D_FORTIFY_SOURCE=2" + cat >conftest.$ac_ext <<_ACEOF +int something (); +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + + { echo "$as_me:$LINENO: Compiling with gcc -fstack-protector-all et al." >&5 echo "$as_me: Compiling with gcc -fstack-protector-all et al." >&6;} + CFLAGS="$save_CFLAGS -fstack-protector-all -D_FORTIFY_SOURCE=2" + CXFXLAGS="$save_CXXFLAGS -fstack-protector-all -D_FORTIFY_SOURCE=2" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + { echo "$as_me:$LINENO: Compiler does not support -fstack-protector-all et al." >&5 +echo "$as_me: Compiler does not support -fstack-protector-all et al." >&6;} + CFLAGS="$save_CFLAGS" + CXXFLAGS="$save_CXXFLAGS" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi @@ -6029,6 +6071,11 @@ echo "${ECHO_T}$ac_cv_lib_sqlite3_sqlite3_open" >&6; } if test $ac_cv_lib_sqlite3_sqlite3_open = yes; then sqlite3_LIBS=-lsqlite3 + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBSQLITE3 1 +_ACEOF + else if test "x$enable_sqlite" != xcheck; then { { echo "$as_me:$LINENO: error: --enable-sqlite was given, but test for sqlite failed @@ -6042,6 +6089,15 @@ fi fi +# Check whether --enable-crash was given. +if test "${enable_crash+set}" = set; then + enableval=$enable_crash; if test "$enable_crash" != "no"; then + save_CPPFLAGS="$CPPFLAGS" + if test "$enable_crash" != "yes"; then + staplog_CPPFLAGS=-I$enable_crash + CPPFLAGS="${staplog_CPPFLAGS} $CPPFLAGS" + + fi for ac_header in crash/defs.h do @@ -6097,14 +6153,22 @@ if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF - build_crashmod=yes + else - build_crashmod=no + { { echo "$as_me:$LINENO: error: cannot find required crash header (crash-devel may need to be installed)" >&5 +echo "$as_me: error: cannot find required crash header (crash-devel may need to be installed)" >&2;} + { (exit 1); exit 1; }; } fi done - if test $build_crashmod = yes; then + CPPFLAGS="$save_CPPFLAGS" + fi +else + enable_crash="no" +fi + + if test "$enable_crash" != "no"; then BUILD_CRASHMOD_TRUE= BUILD_CRASHMOD_FALSE='#' else @@ -7366,11 +7430,11 @@ U!$U$ac_delim ANSI2KNR!$ANSI2KNR$ac_delim RANLIB!$RANLIB$ac_delim sqlite3_LIBS!$sqlite3_LIBS$ac_delim +staplog_CPPFLAGS!$staplog_CPPFLAGS$ac_delim BUILD_CRASHMOD_TRUE!$BUILD_CRASHMOD_TRUE$ac_delim BUILD_CRASHMOD_FALSE!$BUILD_CRASHMOD_FALSE$ac_delim BUILD_ELFUTILS_TRUE!$BUILD_ELFUTILS_TRUE$ac_delim BUILD_ELFUTILS_FALSE!$BUILD_ELFUTILS_FALSE$ac_delim -elfutils_abs_srcdir!$elfutils_abs_srcdir$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -7412,6 +7476,7 @@ _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +elfutils_abs_srcdir!$elfutils_abs_srcdir$ac_delim stap_LIBS!$stap_LIBS$ac_delim DATE!$DATE$ac_delim PROCFLAGS!$PROCFLAGS$ac_delim @@ -7421,7 +7486,7 @@ LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 7; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 8; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff --git a/configure.ac b/configure.ac index f5fcc968..990245a9 100644 --- a/configure.ac +++ b/configure.ac @@ -30,19 +30,18 @@ AC_ARG_ENABLE([perfmon], [enable perfmon support (default is disabled). Optional DIRECTORY is the path to the perfmon installation (needed if installed in a non-standard location).]), [ - dnl Add perfmon define and library - CFLAGS="$CFLAGS -DPERFMON" - CXXFLAGS="$CXXFLAGS -DPERFMON" - LIBS="$LIBS -lpfm" - dnl Handle custom install dir (if needed) - if test "$enable_perfmon" != "yes"; then - CFLAGS="$CFLAGS -I$enable_perfmon/include" - CXXFLAGS="$CXXFLAGS -I$enable_perfmon/include" - LDFLAGS="$LDFLAGS -L$enable_perfmon/lib" - fi - AC_CHECK_LIB([pfm], [pfm_start], [], [ - AC_MSG_ERROR([systemtap cannot find required perfmon libs])]) -]) + if test "$enable_perfmon" != "no"; then + dnl Add perfmon define and library + CPPFLAGS="$CPPFLAGS -DPERFMON" + LIBS="$LIBS -lpfm" + dnl Handle custom install dir (if needed) + if test "$enable_perfmon" != "yes"; then + CPPFLAGS="$CPPFLAGS -I$enable_perfmon/include" + LDFLAGS="$LDFLAGS -L$enable_perfmon/lib" + fi + AC_CHECK_LIB([pfm], [pfm_start], [], [ + AC_MSG_ERROR([systemtap cannot find required perfmon libs (libpfm-devel may need to be installed])]) + fi]) dnl Handle the prologues option. dnl @@ -67,13 +66,20 @@ if test "$enable_prologues" = yes; then AC_DEFINE([ENABLE_PROLOGUES],[],[make -P prologue-searching default]) fi]) - AC_ARG_ENABLE([ssp], - [AS_HELP_STRING([--enable-ssp], [enable gcc stack-protector])]) -AS_IF([test "x$enable_ssp" == xyes], - [CFLAGS="$CFLAGS -fstack-protector-all -D_FORTIFY_SOURCE=2" - CXXFLAGS="$CXXFLAGS -fstack-protector-all -D_FORTIFY_SOURCE=2" - AC_MSG_NOTICE([Compiling with gcc -fstack-protector-all et al.])]) + [AS_HELP_STRING([--disable-ssp], [disable gcc stack-protector])]) +AS_IF([test "x$enable_ssp" != xno],[ + save_CFLAGS="$CFLAGS" + save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -Werror -fstack-protector-all -D_FORTIFY_SOURCE=2" + CFLAGS="$CFLAGS -Werror -fstack-protector-all -D_FORTIFY_SOURCE=2" + AC_COMPILE_IFELSE([int something ();], [ + AC_MSG_NOTICE([Compiling with gcc -fstack-protector-all et al.]) + CFLAGS="$save_CFLAGS -fstack-protector-all -D_FORTIFY_SOURCE=2" + CXFXLAGS="$save_CXXFLAGS -fstack-protector-all -D_FORTIFY_SOURCE=2"],[ + AC_MSG_NOTICE([Compiler does not support -fstack-protector-all et al.]) + CFLAGS="$save_CFLAGS" + CXXFLAGS="$save_CXXFLAGS"])]) dnl Handle optional sqlite support. If enabled/disabled by the user, dnl do the right thing. If not specified by the user, use it if @@ -85,17 +91,35 @@ AC_ARG_ENABLE([sqlite], sqlite3_LIBS= AS_IF([test "x$enable_sqlite" != xno], [AC_CHECK_LIB([sqlite3], [sqlite3_open], - [AC_SUBST([sqlite3_LIBS], [-lsqlite3])], + [AC_SUBST([sqlite3_LIBS], [-lsqlite3]) + AC_DEFINE([HAVE_LIBSQLITE3], [1], [Define to 1 if you have the `sqlite3' library (-lsqlite3).])], [if test "x$enable_sqlite" != xcheck; then AC_MSG_FAILURE([--enable-sqlite was given, but test for sqlite failed]) fi])]) -AC_CHECK_HEADERS(crash/defs.h, - build_crashmod=yes,build_crashmod=no, - [ +dnl Handle the option to build the crash extension +AC_ARG_ENABLE([crash], + AS_HELP_STRING([--enable-crash@<:@=DIRECTORY@:>@], + [enable crash extension (default is disabled). Optional DIRECTORY + is the path to the crash header file (needed if installed in a + non-standard location).]), + [if test "$enable_crash" != "no"; then + dnl Handle custom install dir (if needed) + save_CPPFLAGS="$CPPFLAGS" + if test "$enable_crash" != "yes"; then + staplog_CPPFLAGS=-I$enable_crash + CPPFLAGS="${staplog_CPPFLAGS} $CPPFLAGS" + AC_SUBST([staplog_CPPFLAGS]) + fi + AC_CHECK_HEADERS([crash/defs.h], [], + [AC_MSG_ERROR([cannot find required crash header (crash-devel may need to be installed)])], + [ #define NR_CPUS 256 -]) -AM_CONDITIONAL(BUILD_CRASHMOD, test $build_crashmod = yes) + ]) + CPPFLAGS="$save_CPPFLAGS" + fi], + [enable_crash="no"]) +AM_CONDITIONAL([BUILD_CRASHMOD], [test "$enable_crash" != "no"]) AC_CHECK_HEADERS([sys/capability.h], , [AC_MSG_ERROR([cannot find required libcap header (libcap-devel may need to be installed)])]) diff --git a/coveragedb.cxx b/coveragedb.cxx index bee84db9..8258b359 100644 --- a/coveragedb.cxx +++ b/coveragedb.cxx @@ -28,7 +28,7 @@ void print_coverage_info(systemtap_session &s) clog << "---- used probes-----" << endl; for (unsigned i=0; i<s.probes.size(); i++) { // walk through the chain of probes - vector<derived_probe*> used_probe_list; + vector<probe*> used_probe_list; s.probes[i]->collect_derivation_chain(used_probe_list); for (unsigned j=0; j<used_probe_list.size(); ++j) { for (unsigned k=0; k< used_probe_list[j]->locations.size(); ++k) @@ -51,8 +51,8 @@ void print_coverage_info(systemtap_session &s) clog << "---- unused probes----- " << endl; for (unsigned i=0; i<s.unused_probes.size(); i++) { // walk through the chain of probes - vector<derived_probe*> unused_probe_list; - s.probes[i]->collect_derivation_chain(unused_probe_list); + vector<probe*> unused_probe_list; + s.unused_probes[i]->collect_derivation_chain(unused_probe_list); for (unsigned j=0; j<unused_probe_list.size(); ++j) { for (unsigned k=0; k< unused_probe_list[j]->locations.size(); ++k) clog << "probe: " @@ -197,7 +197,7 @@ sql_update_used_probes(sqlite3 *db, systemtap_session &s) // update database used probes for (unsigned i=0; i<s.probes.size(); i++) { // walk through the chain of probes - vector<derived_probe*> used_probe_list; + vector<probe*> used_probe_list; s.probes[i]->collect_derivation_chain(used_probe_list); for (unsigned j=0; j<used_probe_list.size(); ++j) { for (unsigned k=0; k< used_probe_list[j]->locations.size(); ++k){ @@ -240,8 +240,8 @@ sql_update_unused_probes(sqlite3 *db, systemtap_session &s) // update database unused probes for (unsigned i=0; i<s.unused_probes.size(); i++) { // walk through the chain of probes - vector<derived_probe*> unused_probe_list; - s.probes[i]->collect_derivation_chain(unused_probe_list); + vector<probe*> unused_probe_list; + s.unused_probes[i]->collect_derivation_chain(unused_probe_list); for (unsigned j=0; j<unused_probe_list.size(); ++j) { for (unsigned k=0; k< unused_probe_list[j]->locations.size(); ++k) { @@ -1,9 +1,10 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2004-05-31.23 +scriptversion=2006-10-15.18 -# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc. +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software +# Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,8 +18,8 @@ scriptversion=2004-05-31.23 # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -50,11 +51,11 @@ Environment variables: Report bugs to <bug-automake@gnu.org>. EOF - exit 0 + exit $? ;; -v | --v*) echo "depcomp $scriptversion" - exit 0 + exit $? ;; esac @@ -91,7 +92,20 @@ gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. - "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" stat=$? if test $stat -eq 0; then : else @@ -276,6 +290,46 @@ icc) rm -f "$tmpdepfile" ;; +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. @@ -287,36 +341,43 @@ tru64) base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then - # Dependencies are output in .lo.d with libtool 1.4. - # With libtool 1.5 they are output both in $dir.libs/$base.o.d - # and in $dir.libs/$base.o.d and $dir$base.o.d. We process the - # latter, because the former will be cleaned when $dir.libs is - # erased. - tmpdepfile1="$dir.libs/$base.lo.d" - tmpdepfile2="$dir$base.o.d" - tmpdepfile3="$dir.libs/$base.d" + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else - tmpdepfile1="$dir$base.o.d" - tmpdepfile2="$dir$base.d" - tmpdepfile3="$dir$base.d" + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi - if test -f "$tmpdepfile1"; then - tmpdepfile="$tmpdepfile1" - elif test -f "$tmpdepfile2"; then - tmpdepfile="$tmpdepfile2" - else - tmpdepfile="$tmpdepfile3" - fi + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. @@ -460,7 +521,8 @@ cpp) done "$@" -E | - sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" diff --git a/elaborate.cxx b/elaborate.cxx index 39dae294..bc0d1489 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -1,5 +1,5 @@ // elaboration functions -// Copyright (C) 2005-2007 Red Hat Inc. +// Copyright (C) 2005-2008 Red Hat Inc. // // This file is part of systemtap, and is free software. You can // redistribute it and/or modify it under the terms of the GNU General @@ -112,7 +112,7 @@ derived_probe::printsig_nested (ostream& o) const void -derived_probe::collect_derivation_chain (std::vector<derived_probe*> &probes_list) +derived_probe::collect_derivation_chain (std::vector<probe*> &probes_list) { probes_list.push_back(this); base->collect_derivation_chain(probes_list); @@ -432,7 +432,8 @@ match_node::build_no_more (systemtap_session& s) struct alias_derived_probe: public derived_probe { - alias_derived_probe (probe* base, probe_point *l): derived_probe (base, l) {} + alias_derived_probe (probe* base, probe_point *l, const probe_alias *a): + derived_probe (base, l), alias(a) {} void upchuck () { throw semantic_error ("inappropriate", this->tok); } @@ -441,6 +442,11 @@ struct alias_derived_probe: public derived_probe // systemtap_session.probes void join_group (systemtap_session&) { upchuck (); } + + virtual const probe_alias *get_alias () const { return alias; } + +private: + const probe_alias *alias; // Used to check for recursion }; @@ -460,11 +466,20 @@ alias_expansion_builder std::map<std::string, literal *> const &, vector<derived_probe *> & finished_results) { + // Don't build the alias expansion if infinite recursion is detected. + if (checkForRecursiveExpansion (use)) { + stringstream msg; + msg << "Recursive loop in alias expansion of " << *location << " at " << location->tok->location; + // semantic_errors thrown here are ignored. + sess.print_error (semantic_error (msg.str())); + return; + } + // We're going to build a new probe and wrap it up in an // alias_expansion_probe so that the expansion loop recognizes it as // such and re-expands its expansion. - alias_derived_probe * n = new alias_derived_probe (use, location /* soon overwritten */); + alias_derived_probe * n = new alias_derived_probe (use, location /* soon overwritten */, this->alias); n->body = new block(); // The new probe gets the location list of the alias (with incoming condition joined) @@ -508,6 +523,26 @@ alias_expansion_builder derive_probes (sess, n, finished_results, location->optional); } + + bool checkForRecursiveExpansion (probe *use) + { + // Collect the derivation chain of this probe. + vector<probe*>derivations; + use->collect_derivation_chain (derivations); + + // Check all probe points in the alias expansion against the currently-being-expanded probe point + // of each of the probes in the derivation chain, looking for a match. This + // indicates infinite recursion. + // The first element of the derivation chain will be the derived_probe representing 'use', so + // start the search with the second element. + assert (derivations.size() > 0); + assert (derivations[0] == use); + for (unsigned d = 1; d < derivations.size(); ++d) { + if (use->get_alias() == derivations[d]->get_alias()) + return true; // recursion detected + } + return false; + } }; @@ -1135,6 +1170,7 @@ semantic_pass (systemtap_session& s) catch (const semantic_error& e) { s.print_error (e); + rc ++; } return rc; diff --git a/elaborate.h b/elaborate.h index 5f396526..607f8689 100644 --- a/elaborate.h +++ b/elaborate.h @@ -1,5 +1,5 @@ // -*- C++ -*- -// Copyright (C) 2005-2007 Red Hat Inc. +// Copyright (C) 2005-2008 Red Hat Inc. // // This file is part of systemtap, and is free software. You can // redistribute it and/or modify it under the terms of the GNU General @@ -118,7 +118,7 @@ struct derived_probe: public probe virtual probe_point* sole_location () const; virtual void printsig (std::ostream &o) const; void printsig_nested (std::ostream &o) const; - virtual void collect_derivation_chain (std::vector<derived_probe*> &probes_list); + virtual void collect_derivation_chain (std::vector<probe*> &probes_list); virtual void emit_probe_context_vars (translator_output*) {} // From within unparser::emit_common_header, add any extra variables diff --git a/examples/ChangeLog b/examples/ChangeLog index c1bf2238..99fc6928 100644 --- a/examples/ChangeLog +++ b/examples/ChangeLog @@ -1,3 +1,7 @@ +2008-01-29 Frank Ch. Eigler <fche@elastic.org> + + * nettop.stp: Reorganize array usage to minimize contention. + 2007-11-19 Frank Ch. Eigler <fche@elastic.org> * iostat-scsi.stp: Adopt "!" probe point flag. diff --git a/examples/nettop.stp b/examples/nettop.stp index 1310f5b4..96db413a 100755 --- a/examples/nettop.stp +++ b/examples/nettop.stp @@ -1,25 +1,15 @@ #! /usr/bin/env stap -global ifxmit, ifrecv, ifdevs, ifpid, execname, user +global ifxmit, ifrecv probe netdev.transmit { - p = pid() - execname[p] = execname() - user[p] = uid() - ifdevs[p, dev_name] = dev_name - ifxmit[p, dev_name] <<< length - ifpid[p, dev_name] ++ + ifxmit[pid(), dev_name, execname(), uid()] <<< length } probe netdev.receive { - p = pid() - execname[p] = execname() - user[p] = uid() - ifdevs[p, dev_name] = dev_name - ifrecv[p, dev_name] <<< length - ifpid[p, dev_name] ++ + ifrecv[pid(), dev_name, execname(), uid()] <<< length } @@ -29,27 +19,24 @@ function print_activity() "PID", "UID", "DEV", "XMIT_PK", "RECV_PK", "XMIT_KB", "RECV_KB", "COMMAND") - foreach ([pid, dev] in ifpid-) { - n_xmit = @count(ifxmit[pid, dev]) - n_recv = @count(ifrecv[pid, dev]) + foreach ([pid, dev, exec, uid] in ifrecv-) { + n_xmit = @count(ifxmit[pid, dev, exec, uid]) + n_recv = @count(ifrecv[pid, dev, exec, uid]) printf("%5d %5d %-7s %7d %7d %7d %7d %-15s\n", - pid, user[pid], dev, n_xmit, n_recv, - n_xmit ? @sum(ifxmit[pid, dev])/1024 : 0, - n_recv ? @sum(ifrecv[pid, dev])/1024 : 0, - execname[pid]) + pid, uid, dev, n_xmit, n_recv, + n_xmit ? @sum(ifxmit[pid, dev, exec, uid])/1024 : 0, + n_recv ? @sum(ifrecv[pid, dev, exec, uid])/1024 : 0, + exec) } print("\n") - delete execname - delete user - delete ifdevs delete ifxmit delete ifrecv - delete ifpid } -probe timer.ms(5000) +probe timer.ms(5000), end, error { print_activity() } + @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2004-09-10.20 +scriptversion=2006-10-14.15 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -39,15 +39,24 @@ scriptversion=2004-09-10.20 # when there is no Makefile. # # This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. +# from scratch. + +nl=' +' +IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi -# put in absolute paths if you don't have them in your path; or use env. vars. +# Put in absolute file names if you don't have them in your path; +# or use environment vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" @@ -58,7 +67,13 @@ stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" -chmodcmd="$chmodprog 0755" +posix_glob= +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chmodcmd=$chmodprog chowncmd= chgrpcmd= stripcmd= @@ -95,7 +110,7 @@ Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " -while test -n "$1"; do +while test $# -ne 0; do case $1 in -c) shift continue;; @@ -109,11 +124,17 @@ while test -n "$1"; do shift continue;; - --help) echo "$usage"; exit 0;; + --help) echo "$usage"; exit $?;; - -m) chmodcmd="$chmodprog $2" + -m) mode=$2 shift shift + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac continue;; -o) chowncmd="$chownprog $2" @@ -134,27 +155,35 @@ while test -n "$1"; do shift continue;; - --version) echo "$0 $scriptversion"; exit 0;; - - *) # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - test -n "$dir_arg$dstarg" && break - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dstarg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dstarg" - shift # fnord - fi - shift # arg - dstarg=$arg - done + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; esac done -if test -z "$1"; then +if test $# -ne 0 && test -z "$dir_arg$dstarg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done +fi + +if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 @@ -164,6 +193,33 @@ if test -z "$1"; then exit 0 fi +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + for src do # Protect names starting with `-'. @@ -173,15 +229,11 @@ do if test -n "$dir_arg"; then dst=$src - src= - - if test -d "$dst"; then - mkdircmd=: - chmodcmd= - else - mkdircmd=$mkdirprog - fi + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. @@ -208,52 +260,188 @@ do echo "$0: $dstarg: Is a directory" >&2 exit 1 fi - dst=$dst/`basename "$src"` + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? fi fi - # This sed command emulates the dirname command. - dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - - # Make sure that the destination directory exists. - - # Skip lots of stat calls in the usual case. - if test ! -d "$dstdir"; then - defaultIFS=' - ' - IFS="${IFS-$defaultIFS}" - - oIFS=$IFS - # Some sh's can't handle IFS=/ for some reason. - IFS='%' - set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` - IFS=$oIFS + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac - pathcomp= + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else - while test $# -ne 0 ; do - pathcomp=$pathcomp$1 + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix=/ ;; + -*) prefix=./ ;; + *) prefix= ;; + esac + + case $posix_glob in + '') + if (set -f) 2>/dev/null; then + posix_glob=true + else + posix_glob=false + fi ;; + esac + + oIFS=$IFS + IFS=/ + $posix_glob && set -f + set fnord $dstdir shift - if test ! -d "$pathcomp"; then - $mkdirprog "$pathcomp" - # mkdir can fail with a `File exist' error in case several - # install-sh are creating the directory concurrently. This - # is OK. - test -d "$pathcomp" || exit + $posix_glob && set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true fi - pathcomp=$pathcomp/ - done + fi fi if test -n "$dir_arg"; then - $doit $mkdircmd "$dst" \ - && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ - && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ - && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ - && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } - + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else - dstfile=`basename "$dst"` # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ @@ -261,10 +449,9 @@ do # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - trap '(exit $?); exit' 1 2 13 15 # Copy the file name to the temp name. - $doit $cpprog "$src" "$dsttmp" && + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # @@ -275,10 +462,10 @@ do { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ - && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # Now rename the file to the real destination. - { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ || { # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not @@ -290,12 +477,13 @@ do # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { - if test -f "$dstdir/$dstfile"; then - $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ - || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + if test -f "$dst"; then + $doit $rmcmd -f "$dst" 2>/dev/null \ + || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ + && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ || { - echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 - (exit 1); exit + echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 } else : @@ -303,16 +491,13 @@ do } && # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + $doit $mvcmd "$dsttmp" "$dst" } - } - fi || { (exit 1); exit; } -done + } || exit 1 -# The final little trick to "correctly" pass the exit status to the exit trap. -{ - (exit 0); exit -} + trap '' 0 + fi +done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) @@ -1,5 +1,5 @@ // systemtap translator/driver -// Copyright (C) 2005-2007 Red Hat Inc. +// Copyright (C) 2005-2008 Red Hat Inc. // Copyright (C) 2005 IBM Corp. // Copyright (C) 2006 Intel Corporation. // @@ -47,7 +47,7 @@ version () << "SystemTap translator/driver " << "(version " << VERSION << "/" << dwfl_version (NULL) << " built " << DATE << ")" << endl - << "Copyright (C) 2005-2007 Red Hat, Inc. and others" << endl + << "Copyright (C) 2005-2008 Red Hat, Inc. and others" << endl << "This is free software; see the source for copying conditions." << endl; } @@ -1,9 +1,9 @@ #! /bin/sh # Common stub for a few missing GNU programs while installing. -scriptversion=2004-09-07.08 +scriptversion=2006-05-10.23 -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004 +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. @@ -19,8 +19,8 @@ scriptversion=2004-09-07.08 # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -33,6 +33,8 @@ if test $# -eq 0; then fi run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. @@ -44,7 +46,7 @@ fi msg="missing on your system" -case "$1" in +case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= @@ -77,6 +79,7 @@ Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c @@ -87,12 +90,12 @@ Supported PROGRAM values: yacc create \`y.tab.[ch]', if possible, from existing .[ch] Send bug reports to <bug-automake@gnu.org>." - exit 0 + exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" - exit 0 + exit $? ;; -*) @@ -106,7 +109,7 @@ esac # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). -case "$1" in +case $1 in lex|yacc) # Not GNU programs, they don't have --version. ;; @@ -135,7 +138,7 @@ esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. -case "$1" in +case $1 in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if @@ -164,7 +167,7 @@ WARNING: \`$1' is $msg. You should only need it if test -z "$files" && files="config.h" touch_files= for f in $files; do - case "$f" in + case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; @@ -192,8 +195,8 @@ WARNING: \`$1' is needed, but is $msg. You can get \`$1' as part of \`Autoconf' from any GNU archive site." - file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` - test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else @@ -214,25 +217,25 @@ WARNING: \`$1' $msg. You should only need it if in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h - if [ $# -ne 1 ]; then + if test $# -ne 1; then eval LASTARG="\${$#}" - case "$LASTARG" in + case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if [ -f "$SRCFILE" ]; then + if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if [ -f "$SRCFILE" ]; then + if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi - if [ ! -f y.tab.h ]; then + if test ! -f y.tab.h; then echo >y.tab.h fi - if [ ! -f y.tab.c ]; then + if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; @@ -244,18 +247,18 @@ WARNING: \`$1' is $msg. You should only need it if in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c - if [ $# -ne 1 ]; then + if test $# -ne 1; then eval LASTARG="\${$#}" - case "$LASTARG" in + case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if [ -f "$SRCFILE" ]; then + if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi - if [ ! -f lex.yy.c ]; then + if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; @@ -267,11 +270,9 @@ WARNING: \`$1' is $msg. You should only need it if \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` - fi - if [ -f "$file" ]; then + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then touch $file else test -z "$file" || exec >$file @@ -288,11 +289,24 @@ WARNING: \`$1' is $msg. You should only need it if call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then - file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 touch $file ;; @@ -310,13 +324,13 @@ WARNING: \`$1' is $msg. You should only need it if fi firstarg="$1" if shift; then - case "$firstarg" in + case $firstarg in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac - case "$firstarg" in + case $firstarg in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 7536cc88..b501c1ef 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,31 @@ +2008-02-06 Masami Hiramatsu <mhiramat@redhat.com> + + * stack-ia64.c (__stp_show_stack_sym): Skip printing symbol if (ip == + REG_IP(regs)). + +2008-01-29 Martin Hunt <hunt@redhat.com> + + * io.c (_stp_vlog): Use get_cpu() instead + of smp_processor_id() because this function can get + called with interrupts enabled. + +2008-01-29 Martin Hunt <hunt@redhat.com> + + * alloc.c (struct _stp_malloc_type): Remove + redundant field. + +2008-01-28 Martin Hunt <hunt@redhat.com> + + * alloc.c: Use DEFINE_SPINLOCK. + * counter.c: Ditto. + * pmap-gen.c: Ditto. + * print_new.c: Ditto. + * stat.c: Ditto. + +2008-01-27 Frank Ch. Eigler <fche@elastic.org> + + * stack-i386.c (__stp_stack_print): Correct #elif->#else typo. + 2008-01-14 Martin Hunt <hunt@redhat.com> * print.c (_stp_print_kernel_info): New function. diff --git a/runtime/alloc.c b/runtime/alloc.c index f022755a..cfdb97bd 100644 --- a/runtime/alloc.c +++ b/runtime/alloc.c @@ -32,7 +32,7 @@ static int _stp_allocated_net_memory = 0; #ifdef DEBUG_MEM -static spinlock_t _stp_mem_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(_stp_mem_lock); static int _stp_allocated_memory = 0; #define MEM_MAGIC 0xc11cf77f @@ -41,15 +41,14 @@ static int _stp_allocated_memory = 0; enum _stp_memtype { MEM_KMALLOC, MEM_VMALLOC, MEM_PERCPU }; typedef struct { - enum _stp_memtype type; char *alloc; char *free; } _stp_malloc_type; static const _stp_malloc_type const _stp_malloc_types[] = { - {MEM_KMALLOC, "kmalloc", "kfree"}, - {MEM_VMALLOC, "vmalloc", "vfree"}, - {MEM_PERCPU, "alloc_percpu", "free_percpu"} + {"kmalloc", "kfree"}, + {"vmalloc", "vfree"}, + {"alloc_percpu", "free_percpu"} }; struct _stp_mem_entry { diff --git a/runtime/counter.c b/runtime/counter.c index 42555dfa..d0376547 100644 --- a/runtime/counter.c +++ b/runtime/counter.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * Counter aggregation Functions - * Copyright (C) 2005 Red Hat Inc. + * Copyright (C) 2005-2008 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -60,7 +60,7 @@ Counter _stp_counter_init (void) int i; for_each_cpu(i) { Counter c = per_cpu_ptr (cnt, i); - c->lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(c->lock); } } #endif diff --git a/runtime/io.c b/runtime/io.c index e36381bd..c49d86e6 100644 --- a/runtime/io.c +++ b/runtime/io.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * I/O for printing warnings, errors and debug messages - * Copyright (C) 2005, 2006, 2007 Red Hat Inc. + * Copyright (C) 2005-2008 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -25,7 +25,7 @@ enum code { INFO=0, WARN, ERROR, DBUG }; static void _stp_vlog (enum code type, const char *func, int line, const char *fmt, va_list args) { int num; - char *buf = per_cpu_ptr(Stp_lbuf, smp_processor_id()); + char *buf = per_cpu_ptr(Stp_lbuf, get_cpu()); int start = 0; if (type == DBUG) { @@ -53,6 +53,7 @@ static void _stp_vlog (enum code type, const char *func, int line, const char *f _stp_print_flush(); } } + put_cpu(); } /** Logs Data. diff --git a/runtime/pmap-gen.c b/runtime/pmap-gen.c index ca8d45c5..0efffdb6 100644 --- a/runtime/pmap-gen.c +++ b/runtime/pmap-gen.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * pmap API generator - * Copyright (C) 2005-2007 Red Hat Inc. + * Copyright (C) 2005-2008 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -412,7 +412,7 @@ PMAP KEYSYM(_stp_pmap_new) (unsigned max_entries) m->copy = KEYSYM(pmap_copy_keys); m->cmp = KEYSYM(pmap_key_cmp); #if NEED_MAP_LOCKS - m->lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(m->lock); #endif } m = &pmap->agg; @@ -466,7 +466,7 @@ PMAP KEYSYM(_stp_pmap_new) (unsigned max_entries, int htype, ...) m->copy = KEYSYM(pmap_copy_keys); m->cmp = KEYSYM(pmap_key_cmp); #if NEED_MAP_LOCKS - m->lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(m->lock); #endif } m = &pmap->agg; diff --git a/runtime/print_new.c b/runtime/print_new.c index 95a83a8d..75bbd82b 100644 --- a/runtime/print_new.c +++ b/runtime/print_new.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * Print Flush Function - * Copyright (C) 2007 Red Hat Inc. + * Copyright (C) 2007-2008 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -15,7 +15,8 @@ * * @note Preemption must be disabled to use this. */ -spinlock_t _stp_print_lock = SPIN_LOCK_UNLOCKED; + +DEFINE_SPINLOCK(_stp_print_lock); void EXPORT_FN(stp_print_flush) (_stp_pbuf *pb) { diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c index d73f4c84..b46ff06b 100644 --- a/runtime/stack-i386.c +++ b/runtime/stack-i386.c @@ -23,7 +23,7 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) { #ifdef STAPCONF_X86_UNIREGS unsigned long ebp = regs->bp; - #elif + #else unsigned long ebp = regs->ebp; #endif diff --git a/runtime/stack-ia64.c b/runtime/stack-ia64.c index cab25a0b..ca9d25a6 100644 --- a/runtime/stack-ia64.c +++ b/runtime/stack-ia64.c @@ -23,8 +23,8 @@ static void __stp_show_stack_sym(struct unw_frame_info *info, void *arg) if (skip){ if (ip == REG_IP(regs)) skip = 0; - else continue; - } + continue; + } _stp_print_char(' '); _stp_symbol_print(ip); _stp_print_char('\n'); diff --git a/runtime/staprun/staprun_funcs.c b/runtime/staprun/staprun_funcs.c index d1bba3f8..3a678405 100644 --- a/runtime/staprun/staprun_funcs.c +++ b/runtime/staprun/staprun_funcs.c @@ -336,7 +336,11 @@ int check_permissions(void) /* If neither group was found, just return an error. */ if (stapdev_gid == (gid_t)-1 && stapusr_gid == (gid_t)-1) { - err("ERROR: unable to find either group \"stapdev\" or group \"stapusr\"\n"); + err("ERROR: You are trying to run stap as a normal user.\n" + "You should either be root, or be part of either " + "group \"stapdev\" or group \"stapusr\".\n" + "Your system doesn't seem to have either group.\n" + "For more information, please consult the \"SAFETY AND SECURITY\" section of the \"stap(1)\" manpage\n"); return -1; } @@ -374,7 +378,10 @@ int check_permissions(void) /* If path_check is 0, then the user isn't a member of either * group. Error out. */ if (path_check == 0) { - err("ERROR: you must be a member of either group \"stapdev\" or group \"stapusr\"\n"); + err("ERROR: You are trying to run stap as a normal user.\n" + "You must be a member of either group \"stapdev\" or group \"stapusr\".\n" + "Please contact your system administrator to get yourself membership to either of those groups.\n" + "For more information, please consult the \"SAFETY AND SECURITY\" section of the \"stap(1)\" manpage.\n"); return 0; } diff --git a/runtime/stat.c b/runtime/stat.c index 298a6653..f8b5f018 100644 --- a/runtime/stat.c +++ b/runtime/stat.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * Statistics Aggregation - * Copyright (C) 2005, 2007 Red Hat Inc. + * Copyright (C) 2005-2008 Red Hat Inc. * Copyright (C) 2006 Intel Corporation * * This file is part of systemtap, and is free software. You can @@ -111,7 +111,7 @@ Stat _stp_stat_init (int type, ...) int i; for_each_cpu(i) { stat *sdp = per_cpu_ptr (sd, i); - sdp->lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(sdp->lock); } } #endif diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog index e7bbabd8..764e3579 100644 --- a/runtime/transport/ChangeLog +++ b/runtime/transport/ChangeLog @@ -1,3 +1,7 @@ +2008-01-28 Martin Hunt <hunt@redhat.com> + + * control.c, procfs.c, symbols.c: Use DEFINE_SPINLOCK + 2008-01-15 Martin Hunt <hunt@redhat.com> PR4037 and fixes to better synchronize staprun and stapio. diff --git a/runtime/transport/control.c b/runtime/transport/control.c index 3179f507..0bf99fc8 100644 --- a/runtime/transport/control.c +++ b/runtime/transport/control.c @@ -1,7 +1,7 @@ /* -*- linux-c -*- * * debugfs control channel - * Copyright (C) 2007 Red Hat Inc. + * Copyright (C) 2007-2008 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -15,9 +15,9 @@ static int _stp_current_buffers = STP_DEFAULT_BUFFERS; static struct list_head _stp_ctl_ready_q; static struct list_head _stp_sym_ready_q; static struct list_head _stp_pool_q; -spinlock_t _stp_pool_lock = SPIN_LOCK_UNLOCKED; -spinlock_t _stp_ctl_ready_lock = SPIN_LOCK_UNLOCKED; -spinlock_t _stp_sym_ready_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(_stp_pool_lock); +DEFINE_SPINLOCK(_stp_ctl_ready_lock); +DEFINE_SPINLOCK(_stp_sym_ready_lock); static ssize_t _stp_sym_write_cmd (struct file *file, const char __user *buf, size_t count, loff_t *ppos) diff --git a/runtime/transport/procfs.c b/runtime/transport/procfs.c index 85e97d15..33f6db33 100644 --- a/runtime/transport/procfs.c +++ b/runtime/transport/procfs.c @@ -15,9 +15,9 @@ static int _stp_current_buffers = STP_DEFAULT_BUFFERS; static struct list_head _stp_ctl_ready_q; static struct list_head _stp_sym_ready_q; static struct list_head _stp_pool_q; -spinlock_t _stp_pool_lock = SPIN_LOCK_UNLOCKED; -spinlock_t _stp_ctl_ready_lock = SPIN_LOCK_UNLOCKED; -spinlock_t _stp_sym_ready_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(_stp_pool_lock); +DEFINE_SPINLOCK(_stp_ctl_ready_lock); +DEFINE_SPINLOCK(_stp_sym_ready_lock); #ifdef STP_BULKMODE extern int _stp_relay_flushing; diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c index dde0f967..e740dde8 100644 --- a/runtime/transport/symbols.c +++ b/runtime/transport/symbols.c @@ -16,7 +16,7 @@ #define _SYMBOLS_C_ #include "../sym.h" -spinlock_t _stp_module_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(_stp_module_lock); #define STP_TRYLOCK_MODULES ({ \ int numtrylock = 0; \ while (!spin_trylock_irqsave (&_stp_module_lock, flags) && (++numtrylock < MAXTRYLOCK)) \ diff --git a/runtime/uprobes/uprobes.c b/runtime/uprobes/uprobes.c index f0b72c46..f7d90add 100644 --- a/runtime/uprobes/uprobes.c +++ b/runtime/uprobes/uprobes.c @@ -94,6 +94,15 @@ struct deferred_registration { enum uprobe_type type; }; +/* + * Calling a signal handler cancels single-stepping, so uprobes delays + * calling the handler, as necessary, until after single-stepping is completed. + */ +struct delayed_signal { + struct list_head list; + siginfo_t info; +}; + static struct uprobe_task *uprobe_find_utask(struct task_struct *tsk) { struct hlist_head *head; @@ -436,6 +445,7 @@ static int quiesce_all_threads(struct uprobe_process *uproc, static void uprobe_free_task(struct uprobe_task *utask) { struct deferred_registration *dr, *d; + struct delayed_signal *ds, *ds2; struct uretprobe_instance *ri; struct hlist_node *r1, *r2; @@ -445,6 +455,12 @@ static void uprobe_free_task(struct uprobe_task *utask) list_del(&dr->list); kfree(dr); } + + list_for_each_entry_safe(ds, ds2, &utask->delayed_signals, list) { + list_del(&ds->list); + kfree(ds); + } + hlist_for_each_entry_safe(ri, r1, r2, &utask->uretprobe_instances, hlist) { hlist_del(&ri->hlist); @@ -557,6 +573,7 @@ static struct uprobe_task *uprobe_add_task(struct task_struct *t, utask->doomed = 0; INIT_HLIST_HEAD(&utask->uretprobe_instances); INIT_LIST_HEAD(&utask->deferred_registrations); + INIT_LIST_HEAD(&utask->delayed_signals); INIT_LIST_HEAD(&utask->list); list_add_tail(&utask->list, &uproc->thread_list); uprobe_hash_utask(utask); @@ -1577,6 +1594,33 @@ static inline void uprobe_post_ssin(struct uprobe_task *utask, /* uprobe_pre_ssout() and uprobe_post_ssout() are architecture-specific. */ /* + * Delay delivery of the indicated signal until after single-step. + * Otherwise single-stepping will be cancelled as part of calling + * the signal handler. + */ +static u32 uprobe_delay_signal(struct uprobe_task *utask, siginfo_t *info) +{ + struct delayed_signal *ds = kmalloc(sizeof(*ds), GFP_USER); + if (ds) { + ds->info = *info; + INIT_LIST_HEAD(&ds->list); + list_add_tail(&ds->list, &utask->delayed_signals); + } + return UTRACE_ACTION_HIDE | UTRACE_SIGNAL_IGN | + UTRACE_ACTION_SINGLESTEP | UTRACE_ACTION_NEWSTATE; +} + +static void uprobe_inject_delayed_signals(struct list_head *delayed_signals) +{ + struct delayed_signal *ds, *tmp; + list_for_each_entry_safe(ds, tmp, delayed_signals, list) { + send_sig_info(ds->info.si_signo, &ds->info, current); + list_del(&ds->list); + kfree(ds); + } +} + +/* * Signal callback: * * We get called here with: @@ -1616,10 +1660,24 @@ static u32 uprobe_report_signal(struct utrace_attached_engine *engine, unsigned long probept; int hit_uretprobe_trampoline = 0; int registrations_deferred = 0; + int uproc_freed = 0; + struct list_head delayed_signals; utask = (struct uprobe_task *)rcu_dereference(engine->data); BUG_ON(!utask); + /* + * info will be null if we're called with action=UTRACE_SIGNAL_HANDLER, + * which means that single-stepping has been disabled so a signal + * handler can be called in the probed process. That should never + * happen because we intercept and delay handled signals (action = + * UTRACE_ACTION_RESUME) until after we're done single-stepping. + */ + BUG_ON(!info); + if (action == UTRACE_ACTION_RESUME && utask->active_probe && + info->si_signo != SSTEP_SIGNAL) + return uprobe_delay_signal(utask, info); + if (info->si_signo != BREAKPOINT_SIGNAL && info->si_signo != SSTEP_SIGNAL) goto no_interest; @@ -1722,13 +1780,21 @@ bkpt_done: uprobe_get_process(uproc); } + /* + * Delayed signals are a little different. We want + * them delivered even if all the probes get unregistered + * and uproc and utask go away. So disconnect the list + * from utask and make it a local list. + */ + INIT_LIST_HEAD(&delayed_signals); + list_splice_init(&utask->delayed_signals, &delayed_signals); + ret = UTRACE_ACTION_HIDE | UTRACE_SIGNAL_IGN | UTRACE_ACTION_NEWSTATE; utask->state = UPTASK_RUNNING; if (utask->quiescing) { up_read(&uproc->rwsem); - if (utask_fake_quiesce(utask) == 1) - ret |= UTRACE_ACTION_DETACH; + uproc_freed |= utask_fake_quiesce(utask); } else up_read(&uproc->rwsem); @@ -1738,12 +1804,17 @@ bkpt_done: * we just recycled was the last reason for * keeping uproc around. */ - uprobe_put_process(uproc); + uproc_freed |= uprobe_put_process(uproc); if (registrations_deferred) { uprobe_run_def_regs(&utask->deferred_registrations); - uprobe_put_process(uproc); + uproc_freed |= uprobe_put_process(uproc); } + + uprobe_inject_delayed_signals(&delayed_signals); + + if (uproc_freed) + ret |= UTRACE_ACTION_DETACH; break; default: goto no_interest; diff --git a/runtime/uprobes/uprobes.h b/runtime/uprobes/uprobes.h index 418518f8..0c471474 100644 --- a/runtime/uprobes/uprobes.h +++ b/runtime/uprobes/uprobes.h @@ -385,6 +385,9 @@ struct uprobe_task { /* [un]registrations initiated by handlers must be asynchronous. */ struct list_head deferred_registrations; + + /* Delay handler-destined signals 'til after single-step done. */ + struct list_head delayed_signals; }; #ifdef CONFIG_UPROBES_SSOL diff --git a/staptree.cxx b/staptree.cxx index 6d001375..36ef04f5 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -1,5 +1,5 @@ // parse tree functions -// Copyright (C) 2005, 2006 Red Hat Inc. +// Copyright (C) 2005-2008 Red Hat Inc. // // This file is part of systemtap, and is free software. You can // redistribute it and/or modify it under the terms of the GNU General @@ -903,9 +903,9 @@ void probe::printsig (ostream& o) const void -probe::collect_derivation_chain (std::vector<derived_probe*> &probes_list) +probe::collect_derivation_chain (std::vector<probe*> &probes_list) { - probes_list.push_back((derived_probe*)this); + probes_list.push_back(this); } @@ -1,5 +1,5 @@ // -*- C++ -*- -// Copyright (C) 2005-2007 Red Hat Inc. +// Copyright (C) 2005-2008 Red Hat Inc. // Copyright (C) 2006 Intel Corporation. // // This file is part of systemtap, and is free software. You can @@ -595,7 +595,8 @@ struct probe probe (); void print (std::ostream& o) const; virtual void printsig (std::ostream &o) const; - virtual void collect_derivation_chain (std::vector<derived_probe*> &probes_list); + virtual void collect_derivation_chain (std::vector<probe*> &probes_list); + virtual const probe_alias *get_alias () const { return 0; } virtual probe* basest () { return this; } virtual ~probe() {} bool privileged; diff --git a/systemtap.spec.in b/systemtap.spec.in index e2f93056..789f219f 100644 --- a/systemtap.spec.in +++ b/systemtap.spec.in @@ -1,37 +1,17 @@ # Release number for rpm build. Stays at 1 for new PACKAGE_VERSION increases. -%define release 1 +%define release 3 # Version number of oldest elfutils release that works with systemtap. %define elfutils_version 0.127 -# Set bundled_elfutils to 0 on systems that have %{elfutils_version} or newer. -%if 0%{?fedora} -%define bundled_elfutils 1 -%define sqlite 0 -%if "%fedora" >= "6" -%define bundled_elfutils 0 -%define sqlite 1 -%endif -%endif - -%if 0%{?rhel} -%define bundled_elfutils 1 -%define sqlite 0 -%if "%rhel" >= "5" -%define bundled_elfutils 0 -%define sqlite 1 -%endif -%endif +# Default options (suitable for fedora) +%define with_sqlite 1 +%define with_crash 0 +%define with_bundled_elfutils 0 -%if 0%{!?bundled_elfutils:1} -# Yo! DO NOT TOUCH THE FOLLOWING LINE. -# You can use rpmbuild --define "bundled_elfutils 0" for a build of your own. -%define bundled_elfutils 1 -%endif - -%if 0%{!?sqlite:1} -# Yo! DO NOT TOUCH THE FOLLOWING LINE. -# You can use rpmbuild --define "sqlite 1" for a build of your own. -%define sqlite 0 +# Enable these options by default for RHEL +%if 0%{?rhel} >= 5 +%define with_crash 1 +%define with_bundled_elfutils 1 %endif Name: systemtap @@ -47,27 +27,29 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Requires: kernel >= 2.6.9-11 BuildRequires: libcap-devel -%if %{sqlite} +%if %{with_sqlite} BuildRequires: sqlite-devel Requires: sqlite %endif -%if "%rhel" >= "5" -BuildRequires: crash-devel +%if %{with_crash} +BuildRequires: crash-devel zlib-devel %endif # Requires: kernel-devel # or is that kernel-smp-devel? kernel-hugemem-devel? Requires: gcc make # Suggest: kernel-debuginfo Requires: systemtap-runtime = %{version}-%{release} -Requires(pre): shadow-utils -%if %{bundled_elfutils} +%if %{with_bundled_elfutils} Source1: elfutils-%{elfutils_version}.tar.gz Patch1: elfutils-portability.patch %define setup_elfutils -a1 %else BuildRequires: elfutils-devel >= %{elfutils_version} %endif +%if %{with_crash} +Requires: crash +%endif %description SystemTap is an instrumentation system for systems running Linux 2.6. @@ -80,6 +62,7 @@ Group: Development/System License: GPLv2+ URL: http://sourceware.org/systemtap/ Requires: kernel >= 2.6.9-11 +Requires(pre): shadow-utils %description runtime SystemTap runtime is the runtime component of an instrumentation @@ -100,7 +83,7 @@ without having to rebuild from sources. %prep %setup -q %{?setup_elfutils} -%if %{bundled_elfutils} +%if %{with_bundled_elfutils} cd elfutils-%{elfutils_version} %patch1 -p1 sleep 1 @@ -112,7 +95,7 @@ cd .. %build -%if %{bundled_elfutils} +%if %{with_bundled_elfutils} # Build our own copy of elfutils. %define elfutils_config --with-elfutils=elfutils-%{elfutils_version} @@ -128,17 +111,24 @@ cd .. %endif # Enable/disable the sqlite coverage testing support -%if %{sqlite} +%if %{with_sqlite} %define sqlite_config --enable-sqlite %else %define sqlite_config --disable-sqlite %endif -%configure %{?elfutils_config} %{?sqlite_config} +# Enable/disable the crash extension +%if %{with_crash} +%define crash_config --enable-crash +%else +%define crash_config --disable-crash +%endif + +%configure %{?elfutils_config} %{sqlite_config} %{crash_config} make %{?_smp_mflags} -# Fix paths in the example scripts -find examples -type f -name '*.stp' -print0 | xargs -0 sed -i -r -e '1s@^#!.+stap@#!%{_bindir}/stap@' +# Fix paths in the example & testsuite scripts +find examples testsuite -type f -name '*.stp' -print0 | xargs -0 sed -i -r -e '1s@^#!.+stap@#!%{_bindir}/stap@' # To avoid perl dependency, make perl sample script non-executable chmod -x examples/samples/kmalloc-top @@ -156,16 +146,10 @@ chmod 755 $RPM_BUILD_ROOT%{_bindir}/staprun # Copy over the testsuite cp -rp testsuite $RPM_BUILD_ROOT%{_datadir}/systemtap -if [ -f $RPM_BUILD_ROOT%{_libdir}/%{name}/staplog.so ]; then - echo %{_libdir}/%{name}/staplog.so > runtime-addl-files.txt -else - touch runtime-addl-files.txt -fi - %clean rm -rf ${RPM_BUILD_ROOT} -%pre +%pre runtime getent group stapdev >/dev/null || groupadd -r stapdev getent group stapusr >/dev/null || groupadd -r stapusr exit 0 @@ -183,12 +167,17 @@ exit 0 %{_datadir}/systemtap/runtime %{_datadir}/systemtap/tapset -%if %{bundled_elfutils} +%if %{with_bundled_elfutils} || %{with_crash} %dir %{_libdir}/%{name} +%endif +%if %{with_bundled_elfutils} %{_libdir}/%{name}/lib*.so* %endif +%if %{with_crash} +%{_libdir}/%{name}/staplog.so* +%endif -%files runtime -f runtime-addl-files.txt +%files runtime %defattr(-,root,root) %attr(4111,root,root) %{_bindir}/staprun %{_libexecdir}/systemtap @@ -202,6 +191,10 @@ exit 0 %changelog +* Fri Feb 1 2008 Frank Ch. Eigler <fche@redhat.com> - 0.6.1-3 +- Add zlib-devel to buildreq; missing from crash-devel +- Process testsuite .stp files for #!stap->#!/usr/bin/stap + * Fri Jan 18 2008 Frank Ch. Eigler <fche@redhat.com> - 0.6.1-1 - Add crash-devel buildreq to build staplog.so crash(8) module. - Many robustness & functionality improvements: diff --git a/tapsets.cxx b/tapsets.cxx index d753dc2e..4ff53e6f 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1,5 +1,5 @@ // tapset resolution -// Copyright (C) 2005-2007 Red Hat Inc. +// Copyright (C) 2005-2008 Red Hat Inc. // Copyright (C) 2005-2007 Intel Corporation. // // This file is part of systemtap, and is free software. You can @@ -660,6 +660,10 @@ struct dwflpp << "function '" << function_name << "'" << "\n"; return t; } + bool function_name_final_match(string pattern) + { + return module_name_final_match (pattern); + } bool cu_name_matches(string pattern) @@ -1365,6 +1369,17 @@ struct dwflpp modname, secname, address); obstack_printf (pool, "addr; })"); } + else if (n == 1 && module_name == TOK_KERNEL && secname[0] == '\0') + { + // elfutils' way of telling us that this is a relocatable kernel address, which we + // need to treat the same way here as dwarf_query::add_probe_point does: _stext. + address -= sess.sym_stext; + secname = "_stext"; + obstack_printf (pool, "({ static unsigned long addr = 0; "); + obstack_printf (pool, "if (addr==0) addr = _stp_module_relocate (\"%s\",\"%s\",%#" PRIx64 "); ", + modname, secname, address); + obstack_printf (pool, "addr; })"); + } else { throw semantic_error ("cannot relocate user-space dso (?) address"); @@ -2407,6 +2422,11 @@ dwarf_query::build_blacklist() blacklisted_probes.insert("_spin_unlock"); blacklisted_probes.insert("_spin_unlock_irqrestore"); + // PR 5759, CONFIG_PREEMPT kernels + blacklisted_probes.insert("add_preempt_count"); + blacklisted_probes.insert("preempt_schedule"); + blacklisted_probes.insert("sub_preempt_count"); + // __switch_to changes "current" on x86_64 and i686, so return probes // would cause kernel panic, and it is marked as "__kprobes" on x86_64 if (sess.architecture == "x86_64") @@ -2871,6 +2891,9 @@ query_dwarf_func (Dwarf_Die * func, void * arg) clog << "checking instances of inline " << q->dw.function_name << "\n"; q->dw.iterate_over_inline_instances (query_dwarf_inline_instance, arg); + + if (q->dw.function_name_final_match (q->function)) + return DWARF_CB_ABORT; } else if (!q->dw.func_is_inline () && (! q->has_inline)) { @@ -2907,6 +2930,9 @@ query_dwarf_func (Dwarf_Die * func, void * arg) q->dw.function_file (&func.decl_file); q->dw.function_line (&func.decl_line); q->filtered_functions[entrypc] = func; + + if (q->dw.function_name_final_match (q->function)) + return DWARF_CB_ABORT; } else throw semantic_error("no entrypc found for function '" @@ -3649,6 +3675,11 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname, this->tok = q.base_probe->tok; + // XXX: hack for strange g++/gcc's +#ifndef USHRT_MAX +#define USHRT_MAX 32767 +#endif + // Range limit maxactive() value if (q.has_maxactive && (q.maxactive_val < 0 || q.maxactive_val > USHRT_MAX)) throw semantic_error ("maxactive value out of range [0," @@ -3826,10 +3857,10 @@ dwarf_derived_probe_group::emit_module_decls (systemtap_session& s) // NB: bss! s.op->newline() << "struct stap_dwarf_probe {"; - s.op->newline(1) << "unsigned return_p:1;"; - s.op->newline() << "unsigned maxactive_p:1;"; + s.op->newline(1) << "const unsigned return_p:1;"; + s.op->newline() << "const unsigned maxactive_p:1;"; s.op->newline() << "unsigned registered_p:1;"; - s.op->newline() << "unsigned short maxactive_val;"; + s.op->newline() << "const unsigned short maxactive_val;"; // Let's find some stats for the three embedded strings. Maybe they // are small and uniform enough to justify putting char[MAX]'s into @@ -3862,7 +3893,7 @@ dwarf_derived_probe_group::emit_module_decls (systemtap_session& s) } \ else \ { \ - s.op->newline() << "const char *" << #var << ";"; \ + s.op->newline() << "const char * const " << #var << ";"; \ if (s.verbose > 2) clog << "stap_dwarf_probe *" << #var << endl; \ } @@ -3870,8 +3901,8 @@ dwarf_derived_probe_group::emit_module_decls (systemtap_session& s) CALCIT(section); CALCIT(pp); - s.op->newline() << "unsigned long address;"; - s.op->newline() << "void (*ph) (struct context*);"; + s.op->newline() << "const unsigned long address;"; + s.op->newline() << "void (* const ph) (struct context*);"; s.op->newline(-1) << "} stap_dwarf_probes[] = {"; s.op->indent(1); @@ -3924,7 +3955,7 @@ dwarf_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(1) << "struct kretprobe *krp = inst->rp;"; // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS - s.op->newline(1) << "int kprobe_idx = ((uintptr_t)krp-(uintptr_t)stap_dwarf_kprobes)/sizeof(struct stap_dwarf_kprobe);"; + s.op->newline() << "int kprobe_idx = ((uintptr_t)krp-(uintptr_t)stap_dwarf_kprobes)/sizeof(struct stap_dwarf_kprobe);"; // Check that the index is plausible s.op->newline() << "struct stap_dwarf_probe *sdp = &stap_dwarf_probes["; s.op->line() << "((kprobe_idx >= 0 && kprobe_idx < " << probes_by_module.size() << ")?"; @@ -3948,7 +3979,7 @@ dwarf_derived_probe_group::emit_module_init (systemtap_session& s) { s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {"; s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];"; - s.op->newline(1) << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];"; + s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];"; s.op->newline() << "unsigned long relocated_addr = _stp_module_relocate (sdp->module, sdp->section, sdp->address);"; s.op->newline() << "if (relocated_addr == 0) continue;"; // quietly; assume module is absent s.op->newline() << "probe_point = sdp->pp;"; @@ -3987,7 +4018,7 @@ dwarf_derived_probe_group::emit_module_exit (systemtap_session& s) { s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {"; s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];"; - s.op->newline(1) << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];"; + s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];"; s.op->newline() << "if (! sdp->registered_p) continue;"; s.op->newline() << "if (sdp->return_p) {"; s.op->newline(1) << "unregister_kretprobe (&kp->u.krp);"; @@ -5079,6 +5110,8 @@ struct mark_var_expanding_copy_visitor: public var_expanding_copy_visitor bool target_symbol_seen; void visit_target_symbol (target_symbol* e); + void visit_target_symbol_arg (target_symbol* e); + void visit_target_symbol_format (target_symbol* e); }; @@ -5119,13 +5152,8 @@ hex_dump(unsigned char *data, size_t len) void -mark_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e) +mark_var_expanding_copy_visitor::visit_target_symbol_arg (target_symbol* e) { - assert(e->base_name.size() > 0 && e->base_name[0] == '$'); - - if (e->base_name.substr(0,4) != "$arg") - throw semantic_error ("invalid target symbol for marker, $argN expected", - e->tok); string argnum_s = e->base_name.substr(4,e->base_name.length()-4); int argnum = atoi (argnum_s.c_str()); @@ -5152,7 +5180,7 @@ mark_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e) break; } } - + // Remember that we've seen a target variable. target_symbol_seen = true; @@ -5189,6 +5217,73 @@ mark_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e) } +void +mark_var_expanding_copy_visitor::visit_target_symbol_format (target_symbol* e) +{ + static bool function_synthesized = false; + + if (is_active_lvalue (e)) + throw semantic_error("write to marker format not permitted", e->tok); + + if (e->components.size() > 0) + { + switch (e->components[0].first) + { + case target_symbol::comp_literal_array_index: + throw semantic_error("marker format may not be used as array", + e->tok); + break; + case target_symbol::comp_struct_member: + throw semantic_error("marker format may not be used as a structure", + e->tok); + break; + default: + throw semantic_error ("invalid marker format use", e->tok); + break; + } + } + + string fname = string("_mark_format_get"); + + // Synthesize a function (if not already synthesized). + if (! function_synthesized) + { + function_synthesized = true; + functiondecl *fdecl = new functiondecl; + fdecl->tok = e->tok; + embeddedcode *ec = new embeddedcode; + ec->tok = e->tok; + + ec->code = string("strlcpy (THIS->__retvalue, CONTEXT->data, MAXSTRINGLEN); /* pure */"); + fdecl->name = fname; + fdecl->body = ec; + fdecl->type = pe_string; + sess.functions.push_back(fdecl); + } + + // Synthesize a functioncall. + functioncall* n = new functioncall; + n->tok = e->tok; + n->function = fname; + n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session + provide <functioncall*> (this, n); +} + +void +mark_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e) +{ + assert(e->base_name.size() > 0 && e->base_name[0] == '$'); + + if (e->base_name.substr(0,4) == "$arg") + visit_target_symbol_arg (e); + else if (e->base_name == "$format") + visit_target_symbol_format (e); + else + throw semantic_error ("invalid target symbol for marker, $argN or $format expected", + e->tok); +} + + mark_derived_probe::mark_derived_probe (systemtap_session &s, const string& p_n, @@ -5445,10 +5540,10 @@ mark_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(); s.op->newline() << "struct stap_marker_probe {"; - s.op->newline(1) << "const char *name;"; - s.op->newline() << "const char *format;"; - s.op->newline() << "const char *pp;"; - s.op->newline() << "void (*ph) (struct context *);"; + s.op->newline(1) << "const char * const name;"; + s.op->newline() << "const char * const format;"; + s.op->newline() << "const char * const pp;"; + s.op->newline() << "void (* const ph) (struct context *);"; s.op->newline(-1) << "} stap_marker_probes [" << probes.size() << "] = {"; s.op->indent(1); @@ -5474,10 +5569,13 @@ mark_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(1) << "struct stap_marker_probe *smp = (struct stap_marker_probe *)probe_data;"; common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING"); s.op->newline() << "c->probe_point = smp->pp;"; + s.op->newline() << "c->data = (char *)smp->format;"; s.op->newline() << "c->mark_va_list = args;"; s.op->newline() << "(*smp->ph) (c);"; s.op->newline() << "c->mark_va_list = NULL;"; + s.op->newline() << "c->data = NULL;"; + common_probe_entryfn_epilogue (s.op); s.op->newline(-1) << "}"; diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index 4b5a3ce8..11af94f3 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,64 @@ +2008-02-12 Frank Ch. Eigler <fche@elastic.org> + + * systemtap.context/context.exp: Build temporary modules under + build tree, to tolerate read-only source trees. + * {args,backtrace,pid}.tcl: Corresponding changes. + * systemtap_test_module2.c: Add a bunch of asm("")'s to prevent + inlining even better than noinline does. + +2008-02-12 Frank Ch. Eigler <fche@elastic.org> + + * systemtap.pass1-4/buildok.exp: No longer kfail buildok/seventeen. + +2008-02-07 Martin Hunt <hunt@redhat.com> + + * systemtap.base/debugpath.exp: Remove explicit closes. + Stap will terminate without help, and cleanup after itself. + +2008-02-06 Masami Hiramatsu <mhiramat@redhat.com> + + * systemtap.context/backtrace.tcl: Fixed regular expressions and Added + new expression for checking return probe's stacktrace on ia64. + * systemtap.context/backtrace.stp (print_all_trace_info): Added + trace point output before calling print_stack(). + +2008-02-06 Masami Hiramatsu <mhiramat@redhat.com> + + * systemtap.base/cmd_parse.exp: Added 'wait' between tests for + preventing unexpected EOF. + +2008-02-06 Masami Hiramatsu <mhiramat@redhat.com> + + * systemtap.base/procfs.exp: Added PROCFS.ko cleanup. + * systemtap.context/context.exp: Added cleanup call. + * systemtap.printf/end1b.exp: Passed evaluated command string to + as_root. + * systemtap.printf/mixed_outb.exp: Ditto. + * systemtap.printf/out1b.exp: Ditto. + * systemtap.printf/out2b.exp: Ditto. + * systemtap.printf/out3b.exp: Ditto. + +2008-02-04 David Smith <dsmith@redhat.com> + + PR 4446. + * systemtap.base/marker.exp: Added tests for marker "$format" + variable. + +2008-02-01 Martin Hunt <hunt@redhat.com> + PR4736 + * systemtap.printf/stap_merge.tcl: Copied here so + it will always be available. + +2008-01-31 Will Cohen <wcohen@redhat.com> + + * systemtap.pass1-4/buildok.exp: Add some kfails. + +2008-01-29 Frank Ch. Eigler <fche@elastic.org> + + * Makefile.am (clean-local): Allow "rm -rf" to fail due to + root-owned .ko files in the local cache. + * Makefile.in: Regenerated. + 2008-01-26 Frank Ch. Eigler <fche@elastic.org> PR 5673. diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 6b14bd60..edaaff3c 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -8,8 +8,8 @@ all-local: @echo Run \"make check\" or \"make installcheck\". clean-local: - @rm -f ./stap site.exp systemtap.sum systemtap.log - @rm -rf .systemtap .cache_test + -rm -f ./stap site.exp systemtap.sum systemtap.log + -rm -rf .systemtap .cache_test 2>/dev/null installcheck-local: clean site.exp $(MAKE) AM_RUNTESTFLAGS="--tool_opts install" check-DEJAGNU diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in index 8907c519..99acf141 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -458,8 +458,8 @@ all-local: @echo Run \"make check\" or \"make installcheck\". clean-local: - @rm -f ./stap site.exp systemtap.sum systemtap.log - @rm -rf .systemtap .cache_test + -rm -f ./stap site.exp systemtap.sum systemtap.log + -rm -rf .systemtap .cache_test 2>/dev/null installcheck-local: clean site.exp $(MAKE) AM_RUNTESTFLAGS="--tool_opts install" check-DEJAGNU diff --git a/testsuite/parseko/probepoint04.stp b/testsuite/parseko/probepoint04.stp index 754c9e63..754c9e63 100644..100755 --- a/testsuite/parseko/probepoint04.stp +++ b/testsuite/parseko/probepoint04.stp diff --git a/testsuite/parseko/probepoint05.stp b/testsuite/parseko/probepoint05.stp index 11464ae2..11464ae2 100644..100755 --- a/testsuite/parseko/probepoint05.stp +++ b/testsuite/parseko/probepoint05.stp diff --git a/testsuite/parseko/probepoint06.stp b/testsuite/parseko/probepoint06.stp index ebe23514..ebe23514 100644..100755 --- a/testsuite/parseko/probepoint06.stp +++ b/testsuite/parseko/probepoint06.stp diff --git a/testsuite/parseko/probepoint07.stp b/testsuite/parseko/probepoint07.stp index 1f240a02..1f240a02 100644..100755 --- a/testsuite/parseko/probepoint07.stp +++ b/testsuite/parseko/probepoint07.stp diff --git a/testsuite/parseko/probepoint08.stp b/testsuite/parseko/probepoint08.stp index a0ec712f..a0ec712f 100644..100755 --- a/testsuite/parseko/probepoint08.stp +++ b/testsuite/parseko/probepoint08.stp diff --git a/testsuite/parseko/probepoint09.stp b/testsuite/parseko/probepoint09.stp index a7bf15d8..a7bf15d8 100644..100755 --- a/testsuite/parseko/probepoint09.stp +++ b/testsuite/parseko/probepoint09.stp diff --git a/testsuite/semko/fortyfour.stp b/testsuite/semko/fortyfour.stp new file mode 100755 index 00000000..8f3caeeb --- /dev/null +++ b/testsuite/semko/fortyfour.stp @@ -0,0 +1,5 @@ +#! stap -p2 + +probe foo = bar {} +probe bar = foo {} +probe foo {} diff --git a/testsuite/semko/fortythree.stp b/testsuite/semko/fortythree.stp new file mode 100755 index 00000000..cbf52a91 --- /dev/null +++ b/testsuite/semko/fortythree.stp @@ -0,0 +1,4 @@ +#! stap -p2 + +probe foo.bar = foo.* { } +probe foo.* { } diff --git a/testsuite/semko/maxactive04.stp b/testsuite/semko/maxactive04.stp index 9471fd21..9471fd21 100644..100755 --- a/testsuite/semko/maxactive04.stp +++ b/testsuite/semko/maxactive04.stp diff --git a/testsuite/semko/maxactive05.stp b/testsuite/semko/maxactive05.stp index bdc8a101..bdc8a101 100644..100755 --- a/testsuite/semko/maxactive05.stp +++ b/testsuite/semko/maxactive05.stp diff --git a/testsuite/semok/thirty.stp b/testsuite/semok/thirty.stp new file mode 100755 index 00000000..27612ed0 --- /dev/null +++ b/testsuite/semok/thirty.stp @@ -0,0 +1,9 @@ +#! stap -p2 + +probe foo.a.one = foo.b, foo.c {} // not recursive +probe foo.a.two = foo.c, foo.b {} // not recursive +probe foo.b = foo.c {} +probe foo.c = begin {} +probe foo.a.one {} +probe foo.a.two {} + diff --git a/testsuite/semok/twentynine.stp b/testsuite/semok/twentynine.stp index 05e591ce..05e591ce 100644..100755 --- a/testsuite/semok/twentynine.stp +++ b/testsuite/semok/twentynine.stp diff --git a/testsuite/systemtap.base/cmd_parse.exp b/testsuite/systemtap.base/cmd_parse.exp index 31676a6f..cf15698f 100644 --- a/testsuite/systemtap.base/cmd_parse.exp +++ b/testsuite/systemtap.base/cmd_parse.exp @@ -13,6 +13,7 @@ expect { timeout {fail "cmd_parse1: unexpected timeout"} eof {fail "cmd_parse1: unexpected EOF"} } +wait # stap -c 'echo "hello "\"world\"' -e 'probe begin {}' spawn stap -c {echo "hello "\"world\"} -e {probe begin {}} @@ -22,6 +23,7 @@ expect { timeout {fail "cmd_parse2: unexpected timeout"} eof {fail "cmd_parse2: unexpected EOF"} } +wait #stap -c '(a="hello world"; echo $a)' -e 'probe begin {}' spawn stap -c {(a="hello world"; echo $a)} -e {probe begin {}} @@ -31,6 +33,7 @@ expect { timeout {fail "cmd_parse3: unexpected timeout"} eof {fail "cmd_parse3: unexpected EOF"} } +wait #stap -c '(a="hello "\"world\"; echo $a)' -e 'probe begin {}' spawn stap -c {(a="hello "\"world\"; echo $a)} -e {probe begin {}} @@ -40,6 +43,7 @@ expect { timeout {fail "cmd_parse4: unexpected timeout"} eof {fail "cmd_parse4: unexpected EOF"} } +wait #stap -c '(a="hello "world; echo $a)' -e 'probe begin {}' spawn stap -c {(a="hello "world; echo $a)} -e {probe begin {}} @@ -49,6 +53,7 @@ expect { timeout {fail "cmd_parse5: unexpected timeout"} eof {fail "cmd_parse5: unexpected EOF"} } +wait #stap -c '(((a=42+7)); echo "The answer is $a")' -e 'probe begin {}' spawn stap -c {(((a=42+7)); echo "The answer is $a")} -e {probe begin {}} @@ -58,6 +63,7 @@ expect { timeout {fail "cmd_parse6: unexpected timeout"} eof {fail "cmd_parse6: unexpected EOF"} } +wait #stap -c '(echo "Hello World" 1>&2) > /dev/null' -e 'probe begin {}' spawn stap -c {(echo "Hello World" 1>&2) > /dev/null} -e {probe begin {}} @@ -67,3 +73,4 @@ expect { timeout {fail "cmd_parse7: unexpected timeout"} eof {fail "cmd_parse7: unexpected EOF"} } +wait diff --git a/testsuite/systemtap.base/debugpath.exp b/testsuite/systemtap.base/debugpath.exp index 67b9eb70..b0b12207 100644 --- a/testsuite/systemtap.base/debugpath.exp +++ b/testsuite/systemtap.base/debugpath.exp @@ -6,7 +6,8 @@ expect { timeout { fail "$test (timeout1)" } eof { fail "$test (eof)" } } -catch { close; wait } + +wait set test "debugpath-good" spawn env SYSTEMTAP_DEBUGINFO_PATH=:/usr/lib/debug stap -e "probe kernel.function(\"sys_open\") {}" -p2 @@ -15,4 +16,5 @@ expect { timeout { fail "$test (timeout2)" } eof { fail "$test (eof)" } } -catch { close ; wait } + +wait diff --git a/testsuite/systemtap.base/marker.exp b/testsuite/systemtap.base/marker.exp index bfa3b02d..59d6fd33 100644 --- a/testsuite/systemtap.base/marker.exp +++ b/testsuite/systemtap.base/marker.exp @@ -11,7 +11,7 @@ proc stap_compile { TEST_NAME compile script args } { set cmd [concat {stap -v -p4 -e} $script $args] - puts "running $cmd" + verbose -log "running $cmd" eval spawn $cmd set compile_errors 0 expect { @@ -192,3 +192,47 @@ if {$kernel_markers_found == 0} { set script [format $kernel_script_arg3 $num_marker_name {\[0\]}] stap_compile $TEST_NAME 0 $script } + +set TEST_NAME "K_MARKER11" +if {$kernel_markers_found == 0} { + untested "$TEST_NAME : no kernel markers present" +} else { + # Try compiling a script that prints the format string of a + # marker. + set script [format $kernel_script_arg \ + [lindex $kernel_marker_names 0] {\$format}] + stap_compile $TEST_NAME 1 $script +} + +set TEST_NAME "K_MARKER12" +if {$kernel_markers_found == 0} { + untested "$TEST_NAME : no kernel markers present" +} else { + # Try compiling a script that writes to a marker format string + # (which isn't allowed). + set script [format $kernel_script_arg2 \ + [lindex $kernel_marker_names 0] {\$format}] + stap_compile $TEST_NAME 0 $script +} + +set TEST_NAME "K_MARKER13" +if {$kernel_markers_found == 0} { + untested "$TEST_NAME : no kernel markers present" +} else { + # Try compiling a script that treats the marker format string as a + # structure (which isn't allowed). + set script [format $kernel_script_arg \ + [lindex $kernel_marker_names 0] {\$format->foo}] + stap_compile $TEST_NAME 0 $script +} + +set TEST_NAME "K_MARKER14" +if {$kernel_markers_found == 0} { + untested "$TEST_NAME : no kernel markers present" +} else { + # Try compiling a script that treats the marker format string like + # an array (which isn't allowed). + set script [format $kernel_script_arg \ + [lindex $kernel_marker_names 0] {\$format\[0\]}] + stap_compile $TEST_NAME 0 $script +} diff --git a/testsuite/systemtap.base/procfs.exp b/testsuite/systemtap.base/procfs.exp index ac00acc6..182f1e2e 100644 --- a/testsuite/systemtap.base/procfs.exp +++ b/testsuite/systemtap.base/procfs.exp @@ -110,3 +110,5 @@ set systemtap_script { # test procfs probes set output_string "\\mfinal value = goodbye\\M\r\n" stap_run $test proc_read_write $output_string -e $systemtap_script -m $test + +exec /bin/rm -f ${test}.ko diff --git a/testsuite/systemtap.context/args.tcl b/testsuite/systemtap.context/args.tcl index 6c14c4b7..37a43823 100644 --- a/testsuite/systemtap.context/args.tcl +++ b/testsuite/systemtap.context/args.tcl @@ -1,4 +1,4 @@ -spawn stap args.stp +spawn stap $srcdir/$subdir/args.stp expect { -timeout 240 "READY" { diff --git a/testsuite/systemtap.context/backtrace.stp b/testsuite/systemtap.context/backtrace.stp index 73781371..c14d071c 100644 --- a/testsuite/systemtap.context/backtrace.stp +++ b/testsuite/systemtap.context/backtrace.stp @@ -4,7 +4,7 @@ function print_all_trace_info(point:string) { print("--------\n") bt = backtrace() printf("the %s stack is %s\n", point, bt) - print("--------\n") + printf("--<%s>--\n", point) print_stack(bt); print("--------\n") } diff --git a/testsuite/systemtap.context/backtrace.tcl b/testsuite/systemtap.context/backtrace.tcl index e35832ee..703f0ec2 100644 --- a/testsuite/systemtap.context/backtrace.tcl +++ b/testsuite/systemtap.context/backtrace.tcl @@ -5,7 +5,13 @@ set m4 0 set m5 0 set m6 0 -spawn stap backtrace.stp +if {[istarget ia64-*-*]} { + set retexp {.*return\>--\r\n 0x[a-f0-9]+ : yyy_func3[^\[]+\[systemtap_test_module2\]\r\n} +} else { + set retexp {.*return\>--\r\n 0x[a-f0-9]+ : kretprobe_trampoline_holder[^\r\n]+\r\n} +} + +spawn stap $srcdir/$subdir/backtrace.stp #exp_internal 1 expect { -timeout 240 @@ -36,7 +42,7 @@ expect { incr m2 expect { -timeout 5 - -re {.*---\r\n 0x[a-f0-9]+ : yyy_func3[^\[]+\[systemtap_test_module2\]\r\n} { + -re {.*call\>--\r\n 0x[a-f0-9]+ : yyy_func3[^\[]+\[systemtap_test_module2\]\r\n} { if {$m2 == 1} {incr m2} exp_continue } @@ -76,7 +82,7 @@ expect { incr m4 expect { -timeout 5 - -re {.*0x[a-f0-9]+ : kretprobe_trampoline_holder[^\[]+\[\]\r\n} { + -re $retexp { if {$m4 == 1} {incr m4} exp_continue } @@ -104,7 +110,7 @@ expect { incr m6 expect { -timeout 5 - -re {.*---\r\n 0x[a-f0-9]+[^\r\n]+\r\n} { + -re {.*profile>--\r\n 0x[a-f0-9]+[^\r\n]+\r\n} { if {$m6 == 1} {incr m6} } } diff --git a/testsuite/systemtap.context/context.exp b/testsuite/systemtap.context/context.exp index bc5f8ebe..11c0f2fc 100644 --- a/testsuite/systemtap.context/context.exp +++ b/testsuite/systemtap.context/context.exp @@ -21,20 +21,21 @@ proc cleanup {} { proc build_modules {} { global build_dir + global srcdir subdir if {[catch {exec mktemp -d staptestXXXXX} build_dir]} { puts stderr "Failed to create temporary directory: $build_dir" return 0 } - foreach f [glob systemtap_test_module*.c] { + foreach f [glob $srcdir/$subdir/systemtap_test_module*.c] { exec cp $f $build_dir } set old_dir [pwd] cd $build_dir foreach n {2 1} { - exec cp $old_dir/makefile$n Makefile + exec cp $srcdir/$subdir/makefile$n Makefile if {[catch {exec make clean} res]} { puts $res cd $old_dir @@ -61,7 +62,13 @@ proc build_modules {} { } # first build the modules -cd $srcdir/$subdir + +# NB: We cannot "cd" on behalf the whole dejagnu process, especially +# without going back to the build tree, and especially not to the +# source tree expecting to be able to write there. +# +# cd $srcdir/$subdir + set uname [exec /bin/uname -r] if {[build_modules] == 0} { @@ -73,9 +80,8 @@ if {[build_modules] == 0} { } foreach test $testlist { - source $test.tcl + source $srcdir/$subdir/$test.tcl } - - +cleanup diff --git a/testsuite/systemtap.context/pid.tcl b/testsuite/systemtap.context/pid.tcl index c96d922f..a2c091f1 100644 --- a/testsuite/systemtap.context/pid.tcl +++ b/testsuite/systemtap.context/pid.tcl @@ -1,5 +1,5 @@ set tests [list execname pexecname pid ppid tid uid euid gid egid] -spawn stap pid.stp +spawn stap $srcdir/$subdir/pid.stp #exp_internal 1 expect { -timeout 240 diff --git a/testsuite/systemtap.context/systemtap_test_module2.c b/testsuite/systemtap.context/systemtap_test_module2.c index 51cb58bb..b0d47428 100644 --- a/testsuite/systemtap.context/systemtap_test_module2.c +++ b/testsuite/systemtap.context/systemtap_test_module2.c @@ -22,19 +22,23 @@ /* some nested functions to test backtraces */ int noinline yyy_func4 (int foo) { + asm (""); return foo + 1; } int noinline yyy_func3 (int foo) { foo = yyy_func4(foo); + asm (""); return foo + 1; } int noinline yyy_func2 (int foo) { foo = yyy_func3(foo); + asm (""); return foo + 1; } int noinline yyy_func1 (int foo) { foo = yyy_func2(foo); + asm (""); return foo + 1; } EXPORT_SYMBOL(yyy_func1); @@ -42,31 +46,37 @@ EXPORT_SYMBOL(yyy_func1); /* 1. int argument testing */ int noinline yyy_int(int a, int b, int c) { + asm (""); return a+b+c; } /* 2. uint argument testing */ unsigned noinline yyy_uint(unsigned a, unsigned b, unsigned c) { + asm (""); return a+b+c; } /* 3. long argument testing */ long noinline yyy_long(long a, long b, long c) { + asm (""); return a+b+c; } /* 4. int64_t argument testing */ int noinline yyy_int64(int64_t a, int64_t b, int64_t c) { + asm (""); return a+b+c; } /* 5. char argument testing */ char noinline yyy_char(char a, char b, char c) { + asm (""); return 'Q'; } /* 5. string argument testing */ char * noinline yyy_str(char *a, char *b, char *c) { + asm (""); return "XYZZY"; } diff --git a/testsuite/systemtap.printf/end1b.exp b/testsuite/systemtap.printf/end1b.exp index 6168f66e..e28dce5b 100644 --- a/testsuite/systemtap.printf/end1b.exp +++ b/testsuite/systemtap.printf/end1b.exp @@ -3,13 +3,7 @@ set TEST_NAME "$subdir/end1b" if {![installtest_p]} { untested $TEST_NAME; return } -# Look for stap_merge in the toplevel build directory -# and if that fails, use "which" to try to find a copy -# in the path. -set stap_merge_path "$srcdir/../runtime/staprun/stap_merge.tcl" -if (![file executable $stap_merge_path]) { - catch {exec which stap_merge} stap_merge_path -} +set stap_merge_path "$srcdir/$subdir/stap_merge.tcl" if (![file executable $stap_merge_path]) { fail "$TEST_NAME : could not find stap_merge" return @@ -24,24 +18,24 @@ if {[catch {exec mktemp -t staptestXXXXX} tmpfile]} { if {[catch {exec stap -b -o $tmpfile $test} res]} { untested $TEST_NAME puts "stap failed: $res" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } if {[catch {eval [list exec $stap_merge_path -o $tmpfile] [glob "${tmpfile}_*"]} res]} { puts "merge failed: $res" fail "$TEST_NAME failed" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } if {[catch {exec cmp $tmpfile $srcdir/$subdir/large_output} res]} { puts "$res" fail "$TEST_NAME failed" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } pass "$TEST_NAME passed" -as_root {/bin/rm -f [glob ${tmpfile}*]} +as_root "/bin/rm -f [glob ${tmpfile}*]" diff --git a/testsuite/systemtap.printf/mixed_outb.exp b/testsuite/systemtap.printf/mixed_outb.exp index 6d352dd4..748dd0f2 100644 --- a/testsuite/systemtap.printf/mixed_outb.exp +++ b/testsuite/systemtap.printf/mixed_outb.exp @@ -3,13 +3,7 @@ set TEST_NAME "$subdir/mixed_outb" if {![installtest_p]} { untested $TEST_NAME; return } -# Look for stap_merge in the toplevel build directory -# and if that fails, use "which" to try to find a copy -# in the path. -set stap_merge_path "$srcdir/../runtime/staprun/stap_merge.tcl" -if (![file executable $stap_merge_path]) { - catch {exec which stap_merge} stap_merge_path -} +set stap_merge_path "$srcdir/$subdir/stap_merge.tcl" if (![file executable $stap_merge_path]) { fail "$TEST_NAME : could not find stap_merge" return @@ -24,24 +18,24 @@ if {[catch {exec mktemp -t staptestXXXXX} tmpfile]} { if {[catch {exec stap -DMAXACTION=100000 -b -o $tmpfile $test} res]} { untested $TEST_NAME puts "stap failed: $res" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } if {[catch {eval [list exec $stap_merge_path -o $tmpfile] [glob "${tmpfile}_*"]} res]} { puts "merge failed: $res" fail "$TEST_NAME failed" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } if {[catch {exec cmp $tmpfile $srcdir/$subdir/large_output} res]} { puts "$res" fail "$TEST_NAME failed" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } pass "$TEST_NAME passed" -as_root {/bin/rm -f [glob ${tmpfile}*]} +as_root "/bin/rm -f [glob ${tmpfile}*]" diff --git a/testsuite/systemtap.printf/out1b.exp b/testsuite/systemtap.printf/out1b.exp index 723238c5..6edb8772 100644 --- a/testsuite/systemtap.printf/out1b.exp +++ b/testsuite/systemtap.printf/out1b.exp @@ -3,13 +3,7 @@ set TEST_NAME "$subdir/out1b" if {![installtest_p]} { untested $TEST_NAME; return } -# Look for stap_merge in the toplevel build directory -# and if that fails, use "which" to try to find a copy -# in the path. -set stap_merge_path "$srcdir/../runtime/staprun/stap_merge.tcl" -if (![file executable $stap_merge_path]) { - catch {exec which stap_merge} stap_merge_path -} +set stap_merge_path "$srcdir/$subdir/stap_merge.tcl" if (![file executable $stap_merge_path]) { fail "$TEST_NAME : could not find stap_merge" return @@ -24,24 +18,24 @@ if {[catch {exec mktemp -t staptestXXXXX} tmpfile]} { if {[catch {exec stap -b -o $tmpfile $test} res]} { untested $TEST_NAME puts "stap failed: $res" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } if {[catch {eval [list exec $stap_merge_path -o $tmpfile] [glob "${tmpfile}_*"]} res]} { puts "merge failed: $res" fail "$TEST_NAME failed" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } if {[catch {exec cmp $tmpfile $srcdir/$subdir/large_output} res]} { puts "$res" fail "$TEST_NAME failed" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } pass "$TEST_NAME passed" -as_root {/bin/rm -f [glob ${tmpfile}*]} +as_root "/bin/rm -f [glob ${tmpfile}*]" diff --git a/testsuite/systemtap.printf/out2b.exp b/testsuite/systemtap.printf/out2b.exp index 085cfa14..fc3301ab 100644 --- a/testsuite/systemtap.printf/out2b.exp +++ b/testsuite/systemtap.printf/out2b.exp @@ -3,13 +3,7 @@ set TEST_NAME "$subdir/out2b" if {![installtest_p]} { untested $TEST_NAME; return } -# Look for stap_merge in the toplevel build directory -# and if that fails, use "which" to try to find a copy -# in the path. -set stap_merge_path "$srcdir/../runtime/staprun/stap_merge.tcl" -if (![file executable $stap_merge_path]) { - catch {exec which stap_merge} stap_merge_path -} +set stap_merge_path "$srcdir/$subdir/stap_merge.tcl" if (![file executable $stap_merge_path]) { fail "$TEST_NAME : could not find stap_merge" return @@ -24,24 +18,24 @@ if {[catch {exec mktemp -t staptestXXXXX} tmpfile]} { if {[catch {exec stap -b -o $tmpfile $test} res]} { untested $TEST_NAME puts "stap failed: $res" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } if {[catch {eval [list exec $stap_merge_path -o $tmpfile] [glob "${tmpfile}_*"]} res]} { puts "merge failed: $res" fail "$TEST_NAME failed" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } if {[catch {exec cmp $tmpfile $srcdir/$subdir/large_output} res]} { puts "$res" fail "$TEST_NAME failed" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } pass "$TEST_NAME passed" -as_root {/bin/rm -f [glob ${tmpfile}*]} +as_root "/bin/rm -f [glob ${tmpfile}*]" diff --git a/testsuite/systemtap.printf/out3b.exp b/testsuite/systemtap.printf/out3b.exp index 395363fc..af0d6be7 100644 --- a/testsuite/systemtap.printf/out3b.exp +++ b/testsuite/systemtap.printf/out3b.exp @@ -3,13 +3,7 @@ set TEST_NAME "$subdir/out3b" if {![installtest_p]} { untested $TEST_NAME; return } -# Look for stap_merge in the toplevel build directory -# and if that fails, use "which" to try to find a copy -# in the path. -set stap_merge_path "$srcdir/../runtime/staprun/stap_merge.tcl" -if (![file executable $stap_merge_path]) { - catch {exec which stap_merge} stap_merge_path -} +set stap_merge_path "$srcdir/$subdir/stap_merge.tcl" if (![file executable $stap_merge_path]) { fail "$TEST_NAME : could not find stap_merge" return @@ -24,24 +18,24 @@ if {[catch {exec mktemp -t staptestXXXXX} tmpfile]} { if {[catch {exec stap -DMAXACTION=100000 -b -o $tmpfile $test} res]} { untested $TEST_NAME puts "stap failed: $res" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } if {[catch {eval [list exec $stap_merge_path -o $tmpfile] [glob "${tmpfile}_*"]} res]} { puts "merge failed: $res" fail "$TEST_NAME failed" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } if {[catch {exec cmp $tmpfile $srcdir/$subdir/large_output} res]} { puts "$res" fail "$TEST_NAME failed" - as_root {/bin/rm -f [glob ${tmpfile}*]} + as_root "/bin/rm -f [glob ${tmpfile}*]" return } pass "$TEST_NAME passed" -as_root {/bin/rm -f [glob ${tmpfile}*]} +as_root "/bin/rm -f [glob ${tmpfile}*]" diff --git a/testsuite/systemtap.printf/stap_merge.tcl b/testsuite/systemtap.printf/stap_merge.tcl new file mode 100755 index 00000000..47d419ce --- /dev/null +++ b/testsuite/systemtap.printf/stap_merge.tcl @@ -0,0 +1,102 @@ +#!/usr/bin/env tclsh +# +# stap_merge.tcl - systemtap merge program +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Copyright (C) Red Hat Inc, 2007 +# +# + +proc usage {} { + puts stderr "$::argv0 \[-v\] \[-o output_filename\] input_files ...\n" + exit 1 +} + +set outfile "stdout" +set verbose 0 +set index 0 +while {[string match -* [lindex $argv $index]]} { + switch -glob -- [lindex $argv $index] { + -v {set verbose 1} + -o {incr index; set outfile [lindex $argv $index]} + default {usage} + } + incr index +} + +if {$tcl_platform(byteOrder) == "littleEndian"} { + set int_format i +} else { + set int_format I +} + +set files [lrange $argv $index end] + +set n 0 +foreach file $files { + if {[catch {open $file} fd($n)]} { + puts stderr $fd($n) + exit 1 + } + fconfigure $fd($n) -translation binary + if {![binary scan [read $fd($n) 4] $int_format timestamp($n)]} { + continue + } + set timestamp($n) [expr $timestamp($n) & 0xFFFFFFFF] + incr n +} +set ncpus $n + +if {$outfile != "stdout"} { + if {[catch {open $outfile w} outfile]} { + puts stderr $outfile + exit 1 + } +} +fconfigure $outfile -translation binary + +while {1} { + set mincpu -1 + for {set n 0} {$n < $ncpus} {incr n} { + if {[info exists fd($n)] && (![info exists min] || $timestamp($n) <= $min)} { + set min $timestamp($n) + set mincpu $n + } + } + + if {![info exists min]} {break} + + if {![binary scan [read $fd($mincpu) 4] $int_format len]} { + puts stderr "Error reading length from channel $mincpu" + exit 1 + } + + if {$verbose == 1} { + puts stderr "\[CPU:$mincpu, seq=$min, length=$len\]" + } + + set data [read $fd($mincpu) $len] + puts -nonewline $outfile $data + + set data [read $fd($mincpu) 4] + if {$data == ""} { + unset fd($mincpu) + } else { + binary scan $data $int_format timestamp($mincpu) + set timestamp($mincpu) [expr $timestamp($mincpu) & 0xFFFFFFFF] + } + unset min +} diff --git a/translate.cxx b/translate.cxx index 0beaf1f8..fefb0c8f 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1260,8 +1260,8 @@ c_unparser::emit_module_exit () << "atomic_read (& ((struct context *)per_cpu_ptr(contexts, i))->busy)) " << "holdon = 1;"; o->newline () << "schedule ();"; - o->newline(-1) << "} while (holdon);"; - o->newline(-1); + o->newline(-2) << "} while (holdon);"; + // XXX: might like to have an escape hatch, in case some probe is // genuinely stuck somehow |