diff options
-rw-r--r-- | ChangeLog | 32 | ||||
-rw-r--r-- | Makefile.am | 52 | ||||
-rw-r--r-- | Makefile.in | 45 | ||||
-rw-r--r-- | NEWS | 12 | ||||
-rwxr-xr-x | configure | 7 | ||||
-rw-r--r-- | configure.ac | 7 | ||||
-rw-r--r-- | elaborate.cxx | 3 | ||||
-rw-r--r-- | elaborate.h | 2 | ||||
-rwxr-xr-x | git_version.sh | 348 | ||||
-rw-r--r-- | main.cxx | 191 | ||||
-rw-r--r-- | session.h | 1 | ||||
-rw-r--r-- | stap.1.in | 14 | ||||
-rw-r--r-- | stapex.5.in | 6 | ||||
-rw-r--r-- | tapsets.cxx | 6 | ||||
-rw-r--r-- | testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | testsuite/systemtap.base/cmd_parse.exp | 9 |
16 files changed, 645 insertions, 95 deletions
@@ -1,4 +1,4 @@ -2008-04-10 David Smith <dsmith@redhat.com> +2008-04-11 David Smith <dsmith@redhat.com> * elaborate.h (struct derived_probe_group): Added emit_module_header virtual function. @@ -8,12 +8,13 @@ mark_derived_probe_group::emit_module_header(). * tapsets.cxx (struct be_derived_probe_group): Added empty emit_module_header function. - (struct dwarf_derived_probe_group): Ditto. (struct timer_derived_probe_group): Ditto. (struct profile_derived_probe_group): Ditto. (struct procfs_derived_probe_group): Ditto. (struct hrtimer_derived_probe_group): Ditto. (struct perfmon_derived_probe_group): Ditto. + (dwarf_derived_probe_group::emit_module_header): Moved kprobes + kernel check from emit_module_decls() to here. (uprobe_derived_probe_group::emit_module_header): Moved uprobe kernel check from emit_module_decls() to here. (uprobe_derived_probe_group::emit_module_decls): Moved uprobe @@ -23,6 +24,33 @@ (uprobe_derived_probe_group::emit_module_decls): Moved marker kernel check to emit_module_header(). +2008-04-10 Frank Ch. Eigler <fche@elastic.org> + + PR 2949. + * session.h (listing_mode): New field. + * main.cxx (main): Test it. Enjoy it. + (printscript): Do it. + (usage): Document it. + * stap.1.in, stapex.5.in: Ditto. + * elaborate.cxx (print_error): Disable error messages in listing mode. + +2008-04-10 Frank Ch. Eigler <fche@elastic.org> + + PR 6393 cont'd. + * Makefile.am: Also copy RadeonHD.am fragment to force + git_version.h regeneration at every make, and also special + tagging for "make dist". Thanks <ndim>. + +2008-04-10 Frank Ch. Eigler <fche@elastic.org> + + PR 6393. + * git_version.sh: New file, copied from radeonhd. + * configure.ac: No longer generate $builddir/SNAPSHOT. + * Makefile.am: Generate $builddir/git_version.h. + (EXTRA_DIST): Add git_version.h and git_version.sh. + * main.cxx (version): Print generated GIT_MESSAGE therefrom. + * Makefile.in, configure: Regenerated. + 2008-04-09 David Smith <dsmith@redhat.com> * .gitignore: Added more files to ignore. diff --git a/Makefile.am b/Makefile.am index 1fc4dbec..19451834 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,12 +18,53 @@ stap_SOURCES = main.cxx \ cache.cxx util.cxx coveragedb.cxx stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@ +BUILT_SOURCES = +CLEANFILES = + +# Arrange for git_version.h to be regenerated at every "make". +# Code fragment is based upon RadeonHD.am. + +# The stamp file which is never created ensures that git_version.h is updated +# before every build. Having git_version.h in foo_SOURCES ensures a recompile +# of foo-bar.c if it is newer than the foo-bar.o file. Using noinst_foo_SOURCES +# instead of foo_SOURCES prevents shipping git_version.h in dist tarballs, +# which may cause false GIT_FOO readings. +BUILT_SOURCES += git_version.stamp +CLEANFILES += git_version.h +GIT_VERSION_CMD = $(SHELL) $(top_srcdir)/git_version.sh +git_version.stamp: + @if test -f "$(srcdir)/git_version.h"; then \ + if test -f "git_version.h"; then :; \ + else \ + cp "$(srcdir)/git_version.h" "git_version.h"; \ + fi; \ + fi + $(GIT_VERSION_CMD) -k -s $(top_srcdir) -o git_version.h + @if test -s "$(srcdir)/git_version.h"; then \ + if cmp "$(srcdir)/git_version.h" "git_version.h"; then :; \ + else \ + echo "Error: $(srcdir)/git_version.h and git_version.h differ."; \ + echo " You probably want to remove the former."; \ + exit 1; \ + fi; \ + fi + +dist-gitversion: git_version.stamp + if test -f "git_version.h"; then \ + sed -e 's|^#undef GIT_IS_DIST.*|#define GIT_IS_DIST 1|' \ + "git_version.h" > "$(distdir)/git_version.h"; \ + fi + + +git_version.h: + $(srcdir)/git_version.sh -k --srcdir $(srcdir) -o git_version.h + + + stap_CXXFLAGS = $(AM_CXXFLAGS) stap_CPPFLAGS = $(AM_CPPFLAGS) stap_LDFLAGS = $(AM_LDFLAGS) -CLEANFILES = - if BUILD_ELFUTILS # This tells automake's "make distcheck" what we need to compile. DISTCHECK_CONFIGURE_FLAGS = --with-elfutils=$(elfutils_abs_srcdir) @@ -31,7 +72,7 @@ DISTCHECK_CONFIGURE_FLAGS = --with-elfutils=$(elfutils_abs_srcdir) stap_CPPFLAGS += -Iinclude-elfutils stap_LDFLAGS += -Llib-elfutils -Wl,-rpath-link,lib-elfutils \ -Wl,--enable-new-dtags,-rpath,$(pkglibdir) -BUILT_SOURCES = stamp-elfutils +BUILT_SOURCES += stamp-elfutils CLEANFILES += stamp-elfutils stamp-elfutils: config.status $(MAKE) $(AM_MAKEFLAGS) -C build-elfutils all @@ -102,7 +143,8 @@ LDADD = EXTRA_DIST = buildrun.h elaborate.h loc2c.h session.h \ parse.h staptree.h tapsets.h translate.h \ cache.h hash.h mdfour.h util.h staplog.c coveragedb.h \ - examples testsuite systemtap.spec runtime tapset + examples testsuite systemtap.spec runtime tapset \ + git_version.h git_version.sh SAMPLE_DEST_DIR = $(distdir)/examples/samples @@ -121,7 +163,7 @@ dist-add-samples: $(SAMPLE_SRC) mkdir -p $(SAMPLE_DEST_DIR) cp $(SAMPLE_SRC) $(SAMPLE_DEST_DIR) -dist-hook: dist-add-samples +dist-hook: dist-add-samples dist-gitversion find $(distdir) -name CVS -o -name '*~' -o -name '.#*' | xargs rm -rf find $(distdir) -name '*.o' -o -name '*.ko' -o -name '*.cmd' -o -name '*.mod.c' -o -name '.??*' | xargs rm -rf find $(distdir) -name 'stap' -o -name '*.log' -o -name '*.sum' -o -name 'site.exp' | xargs rm -rf diff --git a/Makefile.in b/Makefile.in index e82d66a3..74ed1bea 100644 --- a/Makefile.in +++ b/Makefile.in @@ -38,6 +38,7 @@ bin_PROGRAMS = stap$(EXEEXT) staprun$(EXEEXT) @BUILD_ELFUTILS_TRUE@ -Wl,--enable-new-dtags,-rpath,$(pkglibdir) @BUILD_ELFUTILS_TRUE@am__append_3 = stamp-elfutils +@BUILD_ELFUTILS_TRUE@am__append_4 = stamp-elfutils @BUILD_ELFUTILS_FALSE@stap_DEPENDENCIES = pkglibexec_PROGRAMS = stapio$(EXEEXT) noinst_PROGRAMS = loc2c-test$(EXEEXT) @@ -275,14 +276,24 @@ stap_SOURCES = main.cxx \ cache.cxx util.cxx coveragedb.cxx stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@ + +# Arrange for git_version.h to be regenerated at every "make". +# Code fragment is based upon RadeonHD.am. + +# The stamp file which is never created ensures that git_version.h is updated +# before every build. Having git_version.h in foo_SOURCES ensures a recompile +# of foo-bar.c if it is newer than the foo-bar.o file. Using noinst_foo_SOURCES +# instead of foo_SOURCES prevents shipping git_version.h in dist tarballs, +# which may cause false GIT_FOO readings. +BUILT_SOURCES = git_version.stamp $(am__append_3) +CLEANFILES = git_version.h $(am__append_4) $(pkglibexec_PROGRAMS) +GIT_VERSION_CMD = $(SHELL) $(top_srcdir)/git_version.sh stap_CXXFLAGS = $(AM_CXXFLAGS) stap_CPPFLAGS = $(AM_CPPFLAGS) $(am__append_1) stap_LDFLAGS = $(AM_LDFLAGS) $(am__append_2) -CLEANFILES = $(am__append_3) $(pkglibexec_PROGRAMS) # This tells automake's "make distcheck" what we need to compile. @BUILD_ELFUTILS_TRUE@DISTCHECK_CONFIGURE_FLAGS = --with-elfutils=$(elfutils_abs_srcdir) -@BUILD_ELFUTILS_TRUE@BUILT_SOURCES = stamp-elfutils @BUILD_ELFUTILS_TRUE@stap_DEPENDENCIES = lib-elfutils/libdw.so staprun_SOURCES = runtime/staprun/staprun.c runtime/staprun/staprun_funcs.c\ runtime/staprun/ctl.c runtime/staprun/common.c \ @@ -311,7 +322,8 @@ LDADD = EXTRA_DIST = buildrun.h elaborate.h loc2c.h session.h \ parse.h staptree.h tapsets.h translate.h \ cache.h hash.h mdfour.h util.h staplog.c coveragedb.h \ - examples testsuite systemtap.spec runtime tapset + examples testsuite systemtap.spec runtime tapset \ + git_version.h git_version.sh SAMPLE_DEST_DIR = $(distdir)/examples/samples SAMPLE_SRC = $(srcdir)/testsuite/systemtap.samples/iotask.stp \ @@ -1458,6 +1470,31 @@ uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8 uninstall-man uninstall-man1 uninstall-man5 uninstall-man8 \ uninstall-pkglibexecPROGRAMS +git_version.stamp: + @if test -f "$(srcdir)/git_version.h"; then \ + if test -f "git_version.h"; then :; \ + else \ + cp "$(srcdir)/git_version.h" "git_version.h"; \ + fi; \ + fi + $(GIT_VERSION_CMD) -k -s $(top_srcdir) -o git_version.h + @if test -s "$(srcdir)/git_version.h"; then \ + if cmp "$(srcdir)/git_version.h" "git_version.h"; then :; \ + else \ + echo "Error: $(srcdir)/git_version.h and git_version.h differ."; \ + echo " You probably want to remove the former."; \ + exit 1; \ + fi; \ + fi + +dist-gitversion: git_version.stamp + if test -f "git_version.h"; then \ + sed -e 's|^#undef GIT_IS_DIST.*|#define GIT_IS_DIST 1|' \ + "git_version.h" > "$(distdir)/git_version.h"; \ + fi + +git_version.h: + $(srcdir)/git_version.sh -k --srcdir $(srcdir) -o git_version.h @BUILD_ELFUTILS_TRUE@stamp-elfutils: config.status @BUILD_ELFUTILS_TRUE@ $(MAKE) $(AM_MAKEFLAGS) -C build-elfutils all @BUILD_ELFUTILS_TRUE@ for dir in libelf libebl libdw libdwfl backends; do \ @@ -1492,7 +1529,7 @@ dist-add-samples: $(SAMPLE_SRC) mkdir -p $(SAMPLE_DEST_DIR) cp $(SAMPLE_SRC) $(SAMPLE_DEST_DIR) -dist-hook: dist-add-samples +dist-hook: dist-add-samples dist-gitversion find $(distdir) -name CVS -o -name '*~' -o -name '.#*' | xargs rm -rf find $(distdir) -name '*.o' -o -name '*.ko' -o -name '*.cmd' -o -name '*.mod.c' -o -name '.??*' | xargs rm -rf find $(distdir) -name 'stap' -o -name '*.log' -o -name '*.sum' -o -name 'site.exp' | xargs rm -rf @@ -1,3 +1,15 @@ +* What's new in version 0.7 + +- A probe listing mode is available. + % stap -l vm.* + vm.brk + vm.mmap + vm.munmap + vm.oom_kill + vm.pagefault + vm.write_shared + + * What's new in version 0.6 - A copy of the systemtap tutorial and language reference guide @@ -6812,13 +6812,6 @@ cap_LIBS="$LIBS" LIBS="$SAVE_LIBS" CFLAGS="$SAVE_CFLAGS" -if test -d $srcdir/.git -a ! -f $srcdir/SNAPSHOT; then - snapshot=`cd $srcdir; git-rev-list --abbrev-commit --max-count=1 HEAD` - echo $snapshot > SNAPSHOT - { echo "$as_me:$LINENO: Created git SNAPSHOT $snapshot" >&5 -echo "$as_me: Created git SNAPSHOT $snapshot" >&6;} -fi - ac_config_headers="$ac_config_headers config.h:config.in" ac_config_files="$ac_config_files Makefile doc/Makefile systemtap.spec stap.1 stapprobes.5 stapfuncs.5 stapex.5 staprun.8 man/stapprobes.iosched.5 man/stapprobes.netdev.5 man/stapprobes.nfs.5 man/stapprobes.nfsd.5 man/stapprobes.pagefault.5 man/stapprobes.process.5 man/stapprobes.rpc.5 man/stapprobes.scsi.5 man/stapprobes.signal.5 man/stapprobes.socket.5 man/stapprobes.tcp.5 man/stapprobes.udp.5" diff --git a/configure.ac b/configure.ac index fa14516c..51ed83a7 100644 --- a/configure.ac +++ b/configure.ac @@ -204,13 +204,6 @@ AC_SUBST(cap_LIBS) LIBS="$SAVE_LIBS" CFLAGS="$SAVE_CFLAGS" -dnl Create SNAPSHOT file from git commit id if possible -if test -d $srcdir/.git -a ! -f $srcdir/SNAPSHOT; then - snapshot=`cd $srcdir; git-rev-list --abbrev-commit --max-count=1 HEAD` - echo $snapshot > SNAPSHOT - AC_MSG_NOTICE([Created git SNAPSHOT $snapshot]) -fi - AC_CONFIG_HEADERS([config.h:config.in]) AC_CONFIG_FILES(Makefile doc/Makefile systemtap.spec stap.1 stapprobes.5 stapfuncs.5 stapex.5 staprun.8 man/stapprobes.iosched.5 man/stapprobes.netdev.5 man/stapprobes.nfs.5 man/stapprobes.nfsd.5 man/stapprobes.pagefault.5 man/stapprobes.process.5 man/stapprobes.rpc.5 man/stapprobes.scsi.5 man/stapprobes.signal.5 man/stapprobes.socket.5 man/stapprobes.tcp.5 man/stapprobes.udp.5) AC_CONFIG_SUBDIRS(testsuite) diff --git a/elaborate.cxx b/elaborate.cxx index 2d9fa7bc..1c41df64 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -1214,6 +1214,9 @@ systemtap_session::print_error (const semantic_error& e) string message_str; stringstream message; + // NB: we don't print error messages during listing mode. + if (listing_mode) return; + message << "semantic error: " << e.what (); if (e.tok1 || e.tok2) message << ": "; diff --git a/elaborate.h b/elaborate.h index 1a029e3c..f53f3870 100644 --- a/elaborate.h +++ b/elaborate.h @@ -114,6 +114,8 @@ struct derived_probe: public probe derived_probe (probe* b, probe_point* l); probe* base; // the original parsed probe virtual probe* basest () { return base->basest(); } + // XXX: might be helpful for listing and stepwise expansion, but aliases/wildcards don't show up right + // virtual probe* almost_basest () { probe* bb = base->basest(); return (bb == base) ? this : bb; } virtual ~derived_probe () {} virtual void join_group (systemtap_session& s) = 0; virtual probe_point* sole_location () const; diff --git a/git_version.sh b/git_version.sh new file mode 100755 index 00000000..69eb0f24 --- /dev/null +++ b/git_version.sh @@ -0,0 +1,348 @@ +#!/bin/sh +# +# Generate some basic versioning information which can be piped to a header. +# +# Copyright (c) 2006-2007 Luc Verhaegen <libv@skynet.be> +# Copyright (C) 2007 Hans Ulrich Niedermann <hun@n-dimensional.de> +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# This script is based on the one written for xf86-video-unichrome by +# Luc Verhaegen, but was rewritten almost completely by Hans Ulrich +# Niedermann. The script contains a few bug fixes from Egbert Eich, +# Matthias Hopf, Joerg Sonnenberger, and possibly others. +# +# The author thanks the nice people on #git for the assistance. +# +# Simple testing of this script: +# /sbin/busybox sh git_version.sh --example > moo.c \ +# && gcc -Wall -Wextra -Wno-unused -o moo moo.c \ +# && ./moo +# (bash should also do) +# +# For how to hook this up to your automake- and/or imake-based build +# system, best take a look at how the RadeonHD.am and/or RadeonHD.tmpl +# work in the xf86-video-radeonhd build system. For non-recursive make, +# you can probably make things a little bit simpler. +# +# KNOWN BUGS: +# * Uses hyphenated ("git-foo-bar") program names, which git upstream +# have declared deprecated. +# + +# Help messages +USAGE="[<option>...]" +LONG_USAGE="\ +Options: + -h, --help Print this help message. + + -k, --keep-if-no-repo Keep old output file if no git repo found. + -o, --output FILENAME Set output file name. + -q, --quiet Quiet output. + -s, --srcdir DIRNAME Set source tree dir name. + -x, --example Print complete example program." + +# The caller may have set these for us +SED="${SED-sed}" + +# Initialize +working_dir="$(pwd)" + +# Who am I? +self="$(basename "$0")" + +# Defaults +ifndef_symbol="GIT_VERSION_H" +outfile="-" +print_example=false +keep_if_no_repo=no +quiet=false +srcdir="$(pwd)" + +# Parse command line parameter, affecting defaults +while [ "x$1" != "x" ] +do + case "$1" in + -x|--example) + print_example=: + ;; + -o|--output) + if shift; then + outfile="$1" + if [ "x$outfile" = "x-" ]; then + : # keep default ifndef_symbol + else + ifndef_symbol=`basename "$outfile" | $SED 's|\.|_|g; s|[^A-Za-z0-9_]||g' | tr a-z A-Z` + fi + else + echo "$self: Fatal: \"$1\" option requires parameter." >&2 + exit 1 + fi + ;; + -q|--quiet) + quiet=: + ;; + -h|--help) + echo "Usage: ${self} $USAGE" + [ -n "$LONG_USAGE" ] && echo "$LONG_USAGE" + exit + ;; + -k|--keep-if-no-repo) + keep_if_no_repo=yes + ;; + -s|--srcdir) + if shift; then + if test -d "$1"; then + srcdir="$1" + else + echo "$self: Fatal: \"$1\" not a directory." >&2 + exit 1 + fi + else + echo "$self: Fatal: \"$1\" option requires directory parameter." >&2 + exit 1 + fi + ;; + *) + echo "$self: Fatal: Invalid command line paramenter: \"$1\"" >&2 + exit 1 + ;; + esac + shift +done + +# If not printing to stdout, redirect stdout to output file +rename_new_output=false +if [ "x$outfile" = "x-" ] +then + : # keep using stdout +else + exec 1> "${outfile}.new" +fi + +# Done with creating output files, so we can change to source dir +abs_srcdir="$(cd "$srcdir" && pwd)" +cd "$srcdir" + +# Write program header +cat<<EOF +/* + * Basic versioning gathered from the git repository. + * Automatically generated by $0. + */ + +#ifndef ${ifndef_symbol} +#define ${ifndef_symbol} 1 + +/* whether this is a dist tarball or not */ +#undef GIT_IS_DIST + +EOF + +# Detect git tools (should work with old and new git versions) +git_found=yes +for git_tool in git-symbolic-ref git-rev-parse git-diff-files git-diff-index git +do + if [ x`which $git_tool 2>/dev/null` = "x" ]; then + git_found="'$git_tool' not found" + break + fi +done + +# Determine git specific defines +unset git_errors ||: +if [ "x$git_found" = "xyes" ]; then + git_version=`git --version` + if [ "x$git_version" = "x" ]; then + git_errors="${git_errors+${git_errors}; }error running 'git --version'" + fi +fi + +git_repo=no +# "git-rev-parse --git-dir" since git-0.99.7 +git_repo_dir="$(git-rev-parse --git-dir 2> /dev/null || true)" +abs_repo_dir="$(cd "$git_repo_dir" && pwd)" +# Only accept the found git repo iff it is in our top srcdir, as determined +# by comparing absolute pathnames creaged by running pwd in the respective dir. +if [ "x$git_repo_dir" != "x" ] && [ "x${abs_repo_dir}" = "x${abs_srcdir}/.git" ]; then + git_repo=yes + if [ "x$git_found" = "xyes" ]; then + # git-1.4 and probably earlier understand "git-rev-parse HEAD" + git_shaid=`git-rev-parse HEAD | $SED -n 's/^\(.\{8\}\).*/\1/p'` + if [ "x$git_shaid" = "x" ]; then + git_errors="${git_errors+${git_errors}; }error running 'git-rev-parse HEAD'" + fi + # git-1.4 and probably earlier understand "git-symbolic-ref HEAD" + git_branch=`git-symbolic-ref HEAD | $SED -n 's|^refs/heads/||p'` + if [ "x$git_branch" = "x" ]; then + # This happens, is OK, and "(no branch)" is what "git branch" prints. + git_branch="(no branch)" + fi + git_dirty=yes + # git-1.4 does not understand "git-diff-files --quiet" + # git-1.4 does not understand "git-diff-index --cached --quiet HEAD" + if [ "x$(git-diff-files)" = "x" ] && [ "x$(git-diff-index --cached HEAD)" = "x" ]; then + git_dirty=no + fi + fi +fi + +# Write git specific defines +if [ "x$git_errors" = "x" ]; then + echo "/* No errors occured while running git */" + echo "#undef GIT_ERRORS" +else + echo "/* Some errors occured while running git */" + echo "#define GIT_ERRORS \"${git_errors}\"" +fi +echo "" + +if [ "x$git_found" = "xyes" ]; then + echo "/* git utilities found */" + echo "#undef GIT_NOT_FOUND" + echo "#define GIT_VERSION \"${git_version}\"" +else + echo "/* git utilities not found */" + echo "#define GIT_NOT_FOUND \"${git_found}\"" + echo "#undef GIT_VERSION" +fi +echo "" + +if [ "x$git_repo" = "xno" ]; then + echo "/* No git repo found, probably building from dist tarball */" + echo "#undef GIT_REPO" +else + echo "/* git repo found */" + echo "#define GIT_REPO 1" + echo "" + if [ "x$git_found" = "xyes" ]; then + echo "/* Git SHA ID of last commit */" + echo "#define GIT_SHAID \"${git_shaid}\"" + echo "" + + echo "/* Branch this tree is on */" + echo "#define GIT_BRANCH \"$git_branch\"" + echo "" + + # Any uncommitted changes we should know about? + # Or technically: Are the working tree or index dirty? + if [ "x$git_dirty" = "xno" ]; then + echo "/* SHA-ID uniquely defines the state of this code */" + echo "#undef GIT_DIRTY" + else + echo "/* Local changes might be breaking things */" + echo "#define GIT_DIRTY 1" + fi + fi +fi + +# Define a few immediately useful message strings +cat<<EOF + +/* Define GIT_MESSAGE such that + * printf("%s: built from %s", argv[0], GIT_MESSAGE); + * forms a proper sentence. + */ + +#ifdef GIT_DIRTY +# define GIT_DIRTY_MSG " + changes" +#else /* !GIT_DIRTY */ +# define GIT_DIRTY_MSG "" +#endif /* GIT_DIRTY */ + +#ifdef GIT_ERRORS +# define GIT_ERROR_MSG " with error: " GIT_ERRORS +#else /* !GIT_ERRORS */ +# define GIT_ERROR_MSG "" +#endif /* GIT_ERRORS */ + +#ifdef GIT_IS_DIST +# define GIT_DIST_MSG "dist of " +#else /* !GIT_IS_DIST */ +# define GIT_DIST_MSG "" +#endif /* GIT_IS_DIST */ + +#ifdef GIT_REPO +# ifdef GIT_NOT_FOUND +# define GIT_MESSAGE GIT_DIST_MSG "git sources without git: " GIT_NOT_FOUND +# else /* !GIT_NOT_FOUND */ +# define GIT_MESSAGE \\ + GIT_DIST_MSG \\ + "git branch " GIT_BRANCH ", " \\ + "commit " GIT_SHAID GIT_DIRTY_MSG \\ + GIT_ERROR_MSG +# endif /* GIT_NOT_FOUND */ +#else /* !GIT_REPO */ +# define GIT_MESSAGE GIT_DIST_MSG "non-git sources" GIT_ERROR_MSG +#endif /* GIT_REPO */ + +#endif /* ${ifndef_symbol} */ +EOF + +# Example program +if "$print_example" +then + cat<<EOF + +/* example program demonstrating the use of git_version.sh output */ +#include <stdio.h> +#include <string.h> + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +int main(int argc, char *argv[]) +{ + const char *const idx = strrchr(argv[0], '/'); + const char *const prog = (idx)?(idx+1):(argv[0]); +#ifdef PACKAGE_VERSION + printf("%s: version %s, built from %s\n", prog, PACKAGE_VERSION, GIT_MESSAGE); +#elif defined(GIT_USED) + printf("%s: built from %s\n", prog, GIT_MESSAGE); +#endif + return 0; +} +EOF +fi + +# Change back to working dir for the remaining output file manipulations. +cd "$working_dir" + +# If necessary, overwrite outdated output file with new one +if [ "x$outfile" != "x-" ] +then + if [ -f "$outfile" ]; then + if [ "x$keep_if_no_repo" = "xyes" ] && [ "x$git_repo" = "xno" ]; then + "$quiet" || echo "$self: Not a git repo, keeping existing $outfile" >&2 + rm -f "$outfile.new" + elif cmp "$outfile" "$outfile.new" > /dev/null; then + "$quiet" || echo "$self: Output is unchanged, keeping $outfile" >&2 + rm -f "$outfile.new" + else + echo "$self: Output has changed, updating $outfile" >&2 + mv -f "$outfile.new" "$outfile" + fi + else + echo "$self: Output is new file, creating $outfile" >&2 + mv -f "$outfile.new" "$outfile" + fi +fi + +# THE END. @@ -19,6 +19,7 @@ #include "cache.h" #include "util.h" #include "coveragedb.h" +#include "git_version.h" #include <iostream> #include <fstream> @@ -47,7 +48,7 @@ version () clog << "SystemTap translator/driver " << "(version " << VERSION << "/" << dwfl_version (NULL) - << " built " << DATE << ")" << endl + << " " << GIT_MESSAGE << ")" << endl << "Copyright (C) 2005-2008 Red Hat, Inc. and others" << endl << "This is free software; see the source for copying conditions." << endl; } @@ -64,9 +65,11 @@ usage (systemtap_session& s, int exitcode) << endl << " or: stap [options] -e SCRIPT Run given script." << endl + << " or: stap [options] -l PROBE List matching probes." + << endl << endl << "Options:" << endl - << " -- no more options after this" << endl + << " -- end of translator options, script options follow" << endl << " -v increase verbosity [" << s.verbose << "]" << endl << " -h show help" << endl << " -V show version" << endl @@ -116,75 +119,118 @@ usage (systemtap_session& s, int exitcode) static void printscript(systemtap_session& s, ostream& o) { - if (s.embeds.size() > 0) - o << "# global embedded code" << endl; - for (unsigned i=0; i<s.embeds.size(); i++) + if (s.listing_mode) { - embeddedcode* ec = s.embeds[i]; - ec->print (o); - o << endl; - } + // We go through some heroic measures to produce clean output. + set<string> seen; - if (s.globals.size() > 0) - o << "# globals" << endl; - for (unsigned i=0; i<s.globals.size(); i++) - { - vardecl* v = s.globals[i]; - v->printsig (o); - if (s.verbose && v->init) + for (unsigned i=0; i<s.probes.size(); i++) { - o << " = "; - v->init->print(o); + derived_probe* p = s.probes[i]; + // NB: p->basest() is not so interesting; + // p->almost_basest() doesn't quite work, so ... + vector<probe*> chain; + p->collect_derivation_chain (chain); + probe* second = (chain.size()>1) ? chain[chain.size()-2] : chain[0]; + + #if 0 + cerr << "\tchain[" << chain.size() << "]:" << endl; + for (unsigned i=0; i<chain.size(); i++) + { cerr << "\t"; chain[i]->printsig(cerr); cerr << endl; } + #endif + + stringstream tmps; + second->printsig (tmps); + string tmp = tmps.str(); + // trim anything other than the "head" of the probe point signature: + // alias1 *CUT* = exp1, exp2 + // probe1 *CUT* /* pc=0xdeadbeef */ /* <- foo */ + string::size_type space_pos = tmp.find(' '); + assert (space_pos != string::npos); + string pp = tmp.substr (0, space_pos); + + // Now duplicate-eliminate. An alias may have expanded to + // several actual derived probe points, but we only want to + // print the alias head name once. + if (seen.find (pp) == seen.end()) + { + o << pp << endl; + seen.insert (pp); + } } - o << endl; } - - if (s.functions.size() > 0) - o << "# functions" << endl; - for (unsigned i=0; i<s.functions.size(); i++) + else { - functiondecl* f = s.functions[i]; - f->printsig (o); - o << endl; - if (f->locals.size() > 0) - o << " # locals" << endl; - for (unsigned j=0; j<f->locals.size(); j++) + if (s.embeds.size() > 0) + o << "# global embedded code" << endl; + for (unsigned i=0; i<s.embeds.size(); i++) { - vardecl* v = f->locals[j]; - o << " "; - v->printsig (o); - o << endl; - } - if (s.verbose) + embeddedcode* ec = s.embeds[i]; + ec->print (o); + o << endl; + } + + if (s.globals.size() > 0) + o << "# globals" << endl; + for (unsigned i=0; i<s.globals.size(); i++) { - f->body->print (o); - o << endl; - } - } - - if (s.probes.size() > 0) - o << "# probes" << endl; - for (unsigned i=0; i<s.probes.size(); i++) - { - derived_probe* p = s.probes[i]; - p->printsig (o); - o << endl; - if (p->locals.size() > 0) - o << " # locals" << endl; - for (unsigned j=0; j<p->locals.size(); j++) + vardecl* v = s.globals[i]; + v->printsig (o); + if (s.verbose && v->init) + { + o << " = "; + v->init->print(o); + } + o << endl; + } + + if (s.functions.size() > 0) + o << "# functions" << endl; + for (unsigned i=0; i<s.functions.size(); i++) { - vardecl* v = p->locals[j]; - o << " "; - v->printsig (o); - o << endl; - } - if (s.verbose) + functiondecl* f = s.functions[i]; + f->printsig (o); + o << endl; + if (f->locals.size() > 0) + o << " # locals" << endl; + for (unsigned j=0; j<f->locals.size(); j++) + { + vardecl* v = f->locals[j]; + o << " "; + v->printsig (o); + o << endl; + } + if (s.verbose) + { + f->body->print (o); + o << endl; + } + } + + if (s.probes.size() > 0) + o << "# probes" << endl; + for (unsigned i=0; i<s.probes.size(); i++) { - p->body->print (o); - o << endl; - } + derived_probe* p = s.probes[i]; + p->printsig (o); + o << endl; + if (p->locals.size() > 0) + o << " # locals" << endl; + for (unsigned j=0; j<p->locals.size(); j++) + { + vardecl* v = p->locals[j]; + o << " "; + v->printsig (o); + o << endl; + } + if (s.verbose) + { + p->body->print (o); + o << endl; + } + } + } } -} int pending_interrupts; @@ -224,6 +270,7 @@ main (int argc, char * const argv []) s.bulk_mode = false; s.unoptimized = false; s.suppress_warnings = false; + s.listing_mode = false; #ifdef ENABLE_PROLOGUES s.prologue_searching = true; @@ -295,7 +342,7 @@ main (int argc, char * const argv []) while (true) { // NB: also see find_hash(), usage(), switch stmt below, stap.1 man page - int grc = getopt (argc, argv, "hVMvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqw"); + int grc = getopt (argc, argv, "hVMvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqwl:"); if (grc < 0) break; switch (grc) @@ -321,6 +368,11 @@ main (int argc, char * const argv []) break; case 'p': + if (s.listing_mode) + { + cerr << "Listing (-l) mode implies pass 2." << endl; + usage (s, 1); + } s.last_pass = atoi (optarg); if (s.last_pass < 1 || s.last_pass > 5) { @@ -453,6 +505,19 @@ main (int argc, char * const argv []) usage (s, 0); break; + case 'l': + s.listing_mode = true; + s.last_pass = 2; + if (have_script) + { + cerr << "Only one script can be given on the command line." + << endl; + usage (s, 1); + } + cmdline_script = string("probe ") + string(optarg) + " {}"; + have_script = true; + break; + default: usage (s, 1); break; @@ -718,7 +783,7 @@ main (int argc, char * const argv []) // PASS 2: ELABORATION rc = semantic_pass (s); - if (rc == 0 && s.last_pass == 2) + if (s.listing_mode || (rc == 0 && s.last_pass == 2)) printscript(s, cout); times (& tms_after); @@ -767,7 +832,7 @@ main (int argc, char * const argv []) } } - if (rc || s.last_pass == 2 || pending_interrupts) goto cleanup; + if (rc || s.listing_mode || s.last_pass == 2 || pending_interrupts) goto cleanup; // PASS 3: TRANSLATION @@ -88,6 +88,7 @@ struct systemtap_session bool timing; bool keep_tmpdir; bool guru_mode; + bool listing_mode; bool bulk_mode; bool unoptimized; bool merge; @@ -45,6 +45,15 @@ stap \- systemtap script translator/driver [ .I ARGUMENTS ] +.br +.B stap +[ +.I OPTIONS +] +.BI \-l " PROBE" +[ +.I ARGUMENTS +] .SH DESCRIPTION @@ -153,6 +162,11 @@ Start the probes, run CMD, and exit when CMD finishes. .BI \-x " PID" Sets target() to PID. This allows scripts to be written that filter on a specific process. +.TP +.BI \-l " PROBE" +Instead of running a probe script, just list all available probe +points matching the given pattern. The pattern may include wildcards +and aliases. .SH ARGUMENTS diff --git a/stapex.5.in b/stapex.5.in index 86e1c87b..2c9ecb60 100644 --- a/stapex.5.in +++ b/stapex.5.in @@ -101,11 +101,9 @@ probe kernel.function("sys_mkdir") { println ("enter") } probe kernel.function("sys_mkdir").return { println ("exit") } .ESAMPLE -To list the probeable functions in the kernel, use the last-pass -option to the translator. That output needs to be filtered because -each inlined function instance is listed separately. +To list the probeable functions in the kernel, use the listings mode. .SAMPLE -% stap \-p2 \-e \[aq]probe kernel.function("*") {}\[aq] | sort | uniq +% stap \-l \[aq]kernel.function("*")\[aq] .ESAMPLE .SH SEE ALSO diff --git a/tapsets.cxx b/tapsets.cxx index c269ce05..a7f8034e 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -2069,7 +2069,7 @@ private: public: void enroll (dwarf_derived_probe* probe); - void emit_module_header (systemtap_session& ) { }; + void emit_module_header (systemtap_session& s); void emit_module_decls (systemtap_session& s); void emit_module_init (systemtap_session& s); void emit_module_exit (systemtap_session& s); @@ -3929,7 +3929,7 @@ dwarf_derived_probe_group::enroll (dwarf_derived_probe* p) void -dwarf_derived_probe_group::emit_module_decls (systemtap_session& s) +dwarf_derived_probe_group::emit_module_header (systemtap_session& s) { if (probes_by_module.empty()) return; @@ -4271,7 +4271,7 @@ struct uprobe_derived_probe: public derived_probe struct uprobe_derived_probe_group: public generic_dpg<uprobe_derived_probe> { public: - void emit_module_header (systemtap_session& ) { }; + void emit_module_header (systemtap_session& s); void emit_module_decls (systemtap_session& s); void emit_module_init (systemtap_session& s); void emit_module_exit (systemtap_session& s); diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index 95c1f117..8bfb1ce4 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-04-10 Frank Ch. Eigler <fche@elastic.org> + + PR 2949 + * systemtap.base/cmd_parse.exp: Add "-l" listing test. + 2008-04-04 Masami Hiramatsu <mhiramat@redhat.com> PR 5528 diff --git a/testsuite/systemtap.base/cmd_parse.exp b/testsuite/systemtap.base/cmd_parse.exp index ff347a9d..cbce0455 100644 --- a/testsuite/systemtap.base/cmd_parse.exp +++ b/testsuite/systemtap.base/cmd_parse.exp @@ -75,3 +75,12 @@ expect { eof {fail "cmd_parse7: unexpected EOF"} } wait + +spawn stap -l {vm.*} +expect { + -timeout 60 + -re "vm.*" {pass "cmd_parse8"} + timeout {fail "cmd_parse8: unexpected timeout"} + eof {fail "cmd_parse8: unexpected EOF"} +} +wait |