summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog29
-rw-r--r--config.in3
-rwxr-xr-xconfigure412
-rw-r--r--configure.ac5
-rw-r--r--elaborate.cxx108
-rw-r--r--main.cxx1
-rw-r--r--staptree.cxx38
-rw-r--r--tapset/ChangeLog36
-rw-r--r--tapset/aux_syscalls.stp112
-rw-r--r--tapset/ctime.stp39
-rw-r--r--tapset/nfs.stp2
-rw-r--r--tapset/signal.stp4
-rw-r--r--tapset/syscalls2.stp26
-rw-r--r--tapset/vfs.stp14
-rw-r--r--tapset/x86_64/syscalls.stp2
-rw-r--r--tapsets.cxx9
-rw-r--r--testsuite/ChangeLog46
-rwxr-xr-xtestsuite/buildok/aux_syscalls-embedded.stp6
-rwxr-xr-xtestsuite/buildok/eleven.stp14
-rwxr-xr-xtestsuite/buildok/ioscheduler.stp4
-rwxr-xr-xtestsuite/buildok/nine.stp2
-rwxr-xr-xtestsuite/buildok/scsi.stp2
-rwxr-xr-xtestsuite/buildok/sixteen.stp2
-rwxr-xr-xtestsuite/buildok/socket.stp4
-rwxr-xr-xtestsuite/buildok/stat_insert.stp4
-rw-r--r--testsuite/systemtap.base/ctime.exp18
-rw-r--r--testsuite/systemtap.base/ctime.stp55
-rw-r--r--testsuite/systemtap.base/optim_arridx.exp77
-rw-r--r--testsuite/systemtap.base/optim_arridx.stp45
-rw-r--r--testsuite/systemtap.base/warnings.exp2
-rw-r--r--testsuite/systemtap.base/warnings.stp7
-rw-r--r--testsuite/systemtap.examples/ChangeLog8
-rw-r--r--testsuite/systemtap.examples/disktop.meta13
-rw-r--r--testsuite/systemtap.examples/disktop.stp69
-rw-r--r--testsuite/systemtap.examples/io_submit.meta13
-rw-r--r--testsuite/systemtap.examples/io_submit.stp71
-rw-r--r--testsuite/systemtap.examples/iotop.meta13
-rw-r--r--testsuite/systemtap.examples/iotop.stp25
-rw-r--r--testsuite/systemtap.examples/sigkill.meta14
-rw-r--r--testsuite/systemtap.examples/sigkill.stp23
-rw-r--r--testsuite/systemtap.examples/traceio.meta13
-rw-r--r--testsuite/systemtap.examples/traceio.stp32
-rw-r--r--testsuite/systemtap.maps/absentstats.stp4
-rw-r--r--testsuite/systemtap.maps/linear_empty.exp3
-rw-r--r--testsuite/systemtap.samples/args.exp2
-rwxr-xr-xtestsuite/systemtap.samples/poll_map.stp2
-rw-r--r--testsuite/systemtap.string/strtol.stp1
-rw-r--r--testsuite/systemtap.syscall/futimes.c2
-rw-r--r--testsuite/systemtap.syscall/stat.c4
-rwxr-xr-xtestsuite/transok/three.stp1
50 files changed, 1311 insertions, 130 deletions
diff --git a/ChangeLog b/ChangeLog
index 92aad43b..38d28928 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2008-05-20 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6538
+ * elaborate.cxx (semantic_pass_opt2): Warn about read-only locals and
+ globals.
+ (visit_foreach_loop): Belatedly recognize index symbols as lvalues.
+
+2008-05-21 Stan Cox <scox@redhat.com>
+
+ * elaborate.cxx (dead_assignment_remover::visit_binary_expression): New.
+ (dead_assignment_remover::visit_assignment): Allow rhs simplification.
+
+2008-05-20 Tim Moore <timoore@redhat.com>
+
+ * configure.ac: Check for tr1/unordered_map header.
+ * tapsets.cxx: Use tr1::unordered_map if available.
+ * configure, config.in: Regenerated.
+
+2008-05-19 Stan Cox <scox@redhat.com>
+
+ * elaborate.cxx (dead_assignment_remover::visit_arrayindex): New method.
+ (dead_assignment_remover::visit_functioncall): New method.
+ (dead_assignment_remover::visit_if_statement): New method.
+ (dead_assignment_remover::visit_for_loop): New method.
+
+2008-05-19 William Cohen <wcohen@redhat.com>
+
+ * main.cxx (setup_signals): Remove sa_restorer initialization.
+
2008-05-17 Frank Ch. Eigler <fche@elastic.org>
* elaborate.cxx (semantic_pass): Error on #probes=0, but not in
diff --git a/config.in b/config.in
index 6ad1527e..11232f02 100644
--- a/config.in
+++ b/config.in
@@ -51,6 +51,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the <tr1/unordered_map> header file. */
+#undef HAVE_TR1_UNORDERED_MAP
+
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
diff --git a/configure b/configure
index 866e9b16..7d2a0b41 100755
--- a/configure
+++ b/configure
@@ -723,6 +723,7 @@ stap_LIBS
DATE
PROCFLAGS
cap_LIBS
+CXXCPP
subdirs
LIBOBJS
LTLIBOBJS'
@@ -738,7 +739,8 @@ CPPFLAGS
CXX
CXXFLAGS
CCC
-CPP'
+CPP
+CXXCPP'
ac_subdirs_all='testsuite'
# Initialize some variables set by options.
@@ -1352,6 +1354,7 @@ Some influential environment variables:
CXX C++ compiler command
CXXFLAGS C++ compiler flags
CPP C preprocessor
+ CXXCPP C++ preprocessor
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
@@ -6875,6 +6878,393 @@ cap_LIBS="$LIBS"
LIBS="$SAVE_LIBS"
CFLAGS="$SAVE_CFLAGS"
+# Use tr1/unordered_map if available
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
+echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; }
+if test -z "$CXXCPP"; then
+ if test "${ac_cv_prog_CXXCPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CXXCPP needs to be expanded
+ for CXXCPP in "$CXX -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+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_cpp conftest.$ac_ext") 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); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+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_cpp conftest.$ac_ext") 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); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+ CXXCPP=$ac_cv_prog_CXXCPP
+else
+ ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ echo "$as_me:$LINENO: result: $CXXCPP" >&5
+echo "${ECHO_T}$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+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_cpp conftest.$ac_ext") 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); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+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_cpp conftest.$ac_ext") 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); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+for ac_header in tr1/unordered_map
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_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_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+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_cpp conftest.$ac_ext") 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); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## ------------------------------------------- ##
+## Report this to systemtap@sources.redhat.com ##
+## ------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
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"
@@ -7735,12 +8125,13 @@ stap_LIBS!$stap_LIBS$ac_delim
DATE!$DATE$ac_delim
PROCFLAGS!$PROCFLAGS$ac_delim
cap_LIBS!$cap_LIBS$ac_delim
+CXXCPP!$CXXCPP$ac_delim
subdirs!$subdirs$ac_delim
LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 15; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 16; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
@@ -8141,22 +8532,21 @@ echo "$as_me: $ac_file is unchanged" >&6;}
fi
rm -f "$tmp/out12"
# Compute $ac_file's index in $config_headers.
-_am_arg=$ac_file
_am_stamp_count=1
for _am_header in $config_headers :; do
case $_am_header in
- $_am_arg | $_am_arg:* )
+ $ac_file | $ac_file:* )
break ;;
* )
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
esac
done
-echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
-$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$_am_arg" : 'X\(//\)[^/]' \| \
- X"$_am_arg" : 'X\(//\)$' \| \
- X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$_am_arg" |
+echo "timestamp for $ac_file" >`$as_dirname -- $ac_file ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X$ac_file : 'X\(//\)[^/]' \| \
+ X$ac_file : 'X\(//\)$' \| \
+ X$ac_file : 'X\(/\)' \| . 2>/dev/null ||
+echo X$ac_file |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
@@ -8193,7 +8583,7 @@ echo "$as_me: executing $ac_file commands" >&6;}
# each Makefile.in and add a new line on top of each file to say so.
# Grep'ing the whole file is not good either: AIX grep has a line
# limit of 2048, but all sed's we know have understand at least 4000.
- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then
dirpart=`$as_dirname -- "$mf" ||
$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$mf" : 'X\(//\)[^/]' \| \
diff --git a/configure.ac b/configure.ac
index 4d0a4263..b7c1bc47 100644
--- a/configure.ac
+++ b/configure.ac
@@ -227,6 +227,11 @@ AC_SUBST(cap_LIBS)
LIBS="$SAVE_LIBS"
CFLAGS="$SAVE_CFLAGS"
+# Use tr1/unordered_map if available
+AC_LANG_PUSH(C++)
+AC_CHECK_HEADERS([tr1/unordered_map])
+AC_LANG_POP(C++)
+
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 9a817cba..2f246e2c 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -1624,7 +1624,13 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
// don't increment j
}
else
- j++;
+ {
+ if (vut.written.find (l) == vut.written.end())
+ if (! s.suppress_warnings)
+ clog << "WARNING: read-only local variable " << *l->tok << endl;
+
+ j++;
+ }
}
for (unsigned i=0; i<s.functions.size(); i++)
for (unsigned j=0; j<s.functions[i]->locals.size(); /* see below */)
@@ -1649,7 +1655,12 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
// don't increment j
}
else
- j++;
+ {
+ if (vut.written.find (l) == vut.written.end())
+ if (! s.suppress_warnings)
+ clog << "WARNING: read-only local variable " << *l->tok << endl;
+ j++;
+ }
}
for (unsigned i=0; i<s.globals.size(); /* see below */)
{
@@ -1671,7 +1682,13 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
// don't increment i
}
else
- i++;
+ {
+ if (vut.written.find (l) == vut.written.end() &&
+ ! l->init) // no initializer
+ if (! s.suppress_warnings)
+ clog << "WARNING: read-only global variable " << *l->tok << endl;
+ i++;
+ }
}
}
@@ -1696,6 +1713,11 @@ struct dead_assignment_remover: public traversing_visitor
// called with null current_expr.
void visit_assignment (assignment* e);
+ void visit_binary_expression (binary_expression* e);
+ void visit_arrayindex (arrayindex* e);
+ void visit_functioncall (functioncall* e);
+ void visit_if_statement (if_statement* e);
+ void visit_for_loop (for_loop* e);
};
@@ -1720,6 +1742,11 @@ dead_assignment_remover::visit_assignment (assignment* e)
*current_expr == e && // we're not nested any deeper than expected
leftvar) // not unresolved $target; intended sideeffect cannot be elided
{
+ expression** last_expr = current_expr;
+ e->left->visit (this);
+ current_expr = &e->right;
+ e->right->visit (this);
+ current_expr = last_expr;
if (vut.read.find(leftvar) == vut.read.end()) // var never read?
{
// NB: Not so fast! The left side could be an array whose
@@ -1750,6 +1777,71 @@ dead_assignment_remover::visit_assignment (assignment* e)
}
}
+void
+dead_assignment_remover::visit_binary_expression (binary_expression* e)
+{
+ expression** last_expr = current_expr;
+ current_expr = &e->left;
+ e->left->visit (this);
+ current_expr = &e->right;
+ e->right->visit (this);
+ current_expr = last_expr;
+}
+
+void
+dead_assignment_remover::visit_arrayindex (arrayindex *e)
+{
+ symbol *array = NULL;
+ hist_op *hist = NULL;
+ classify_indexable(e->base, array, hist);
+
+ if (array)
+ {
+ expression** last_expr = current_expr;
+ for (unsigned i=0; i < e->indexes.size(); i++)
+ {
+ current_expr = & e->indexes[i];
+ e->indexes[i]->visit (this);
+ }
+ current_expr = last_expr;
+ }
+}
+
+void
+dead_assignment_remover::visit_functioncall (functioncall* e)
+{
+ expression** last_expr = current_expr;
+ for (unsigned i=0; i<e->args.size(); i++)
+ {
+ current_expr = & e->args[i];
+ e->args[i]->visit (this);
+ }
+ current_expr = last_expr;
+}
+
+void
+dead_assignment_remover::visit_if_statement (if_statement* s)
+{
+ expression** last_expr = current_expr;
+ current_expr = & s->condition;
+ s->condition->visit (this);
+ s->thenblock->visit (this);
+ if (s->elseblock)
+ s->elseblock->visit (this);
+ current_expr = last_expr;
+}
+
+void
+dead_assignment_remover::visit_for_loop (for_loop* s)
+{
+ expression** last_expr = current_expr;
+ if (s->init) s->init->visit (this);
+ current_expr = & s->cond;
+ s->cond->visit (this);
+ if (s->incr) s->incr->visit (this);
+ s->block->visit (this);
+ current_expr = last_expr;
+}
// Let's remove assignments to variables that are never read. We
// rewrite "(foo = expr)" as "(expr)". This makes foo a candidate to
@@ -1772,6 +1864,8 @@ void semantic_pass_opt3 (systemtap_session& s, bool& relaxed_p)
for (unsigned i=0; i<s.functions.size(); i++)
s.functions[i]->body->visit (& dar);
// The rewrite operation is performed within the visitor.
+
+ // XXX: we could also zap write-only globals here
}
@@ -1995,6 +2089,8 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
p->body = new null_statement();
p->body->tok = p->tok;
+
+ // XXX: possible duplicate warnings; see below
}
}
for (unsigned i=0; i<s.functions.size(); i++)
@@ -2018,6 +2114,12 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
fn->body = new null_statement();
fn->body->tok = fn->tok;
+
+ // XXX: the next iteration of the outer optimization loop may
+ // take this new null_statement away again, and thus give us a
+ // fresh warning. It would be better if this fixup was performed
+ // only after the relaxation iterations.
+ // XXX: or else see bug #6469.
}
}
}
diff --git a/main.cxx b/main.cxx
index dc638459..81935207 100644
--- a/main.cxx
+++ b/main.cxx
@@ -287,7 +287,6 @@ setup_signals (sighandler_t handler)
sigaddset (&sa.sa_mask, SIGTERM);
}
sa.sa_flags = 0;
- sa.sa_restorer = NULL;
sigaction (SIGHUP, &sa, NULL);
sigaction (SIGPIPE, &sa, NULL);
diff --git a/staptree.cxx b/staptree.cxx
index 02a6c8dc..347d799f 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -1713,6 +1713,15 @@ varuse_collecting_visitor::visit_symbol (symbol *e)
if (e->referent == 0)
throw semantic_error ("symbol without referent", e->tok);
+ // We could handle initialized globals by marking them as "written".
+ // However, this current visitor may be called for a function or
+ // probe body, from the point of view of which this global is
+ // already initialized, so not written.
+ /*
+ if (e->referent->init)
+ written.insert (e->referent);
+ */
+
if (current_lvalue == e || current_lrvalue == e)
{
written.insert (e->referent);
@@ -1789,10 +1798,19 @@ varuse_collecting_visitor::visit_post_crement (post_crement *e)
void
varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
{
- functioncall_traversing_visitor::visit_foreach_loop (s);
+ // NB: we duplicate so don't bother call
+ // functioncall_traversing_visitor::visit_foreach_loop (s);
+
+ symbol *array = NULL;
+ hist_op *hist = NULL;
+ classify_indexable (s->base, array, hist);
+ if (array)
+ array->visit(this);
+ else
+ hist->visit(this);
+
// If the collection is sorted, imply a "write" access to the
- // array in addition to the "read" one already noted in the
- // base class call above.
+ // array in addition to the "read" one already noted above.
if (s->sort_direction)
{
symbol *array = NULL;
@@ -1801,6 +1819,20 @@ varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
if (array) this->written.insert (array->referent);
// XXX: Can hist_op iterations be sorted?
}
+
+ // NB: don't forget to visit the index expressions, which are lvalues.
+ for (unsigned i=0; i<s->indexes.size(); i++)
+ {
+ expression* last_lvalue = current_lvalue;
+ current_lvalue = s->indexes[i]; // leave a mark for ::visit_symbol
+ s->indexes[i]->visit (this);
+ current_lvalue = last_lvalue;
+ }
+
+ if (s->limit)
+ s->limit->visit (this);
+
+ s->block->visit (this);
}
diff --git a/tapset/ChangeLog b/tapset/ChangeLog
index 70d75b83..4b37471c 100644
--- a/tapset/ChangeLog
+++ b/tapset/ChangeLog
@@ -1,3 +1,39 @@
+2008-05-21 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6538
+ * nfs.stp (nfs.aop.readpage): Fix rsize.
+
+2008-05-20 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6538
+ * signal.stp (_signal.send.part[23]): Initialize dummy sinfo.
+ * syscalls2.stp (syscall.compat_sys_semtimedop): Fix sops_uaddr.
+ * vfs.stp (__find_bdevname): Rewrite.
+ * x86_64/syscalls.stp (syscall.pipe32): Fix argstr.
+
+2008-05-21 Mark Wielaard <mwielaard@redhat.com>
+
+ * syscalls2.stp (syscall.utime): Use pointer_arg to fetch arguments.
+ (syscall.compat_utime): Likewise.
+
+2008-05-20 Mark Wielaard <mwielaard@redhat.com>
+
+ PR 5001
+ * aux_syscalls.stp (_stp_ctime): Removed.
+ (_struct_utimbuf_u): Removed.
+ (_struct_compat_utimbuf_u): Removed.
+ (_struct_utimbuf_actime): New function.
+ (_struct_utimbuf_modtime): New function.
+ (_struct_compat_utimbuf_actime): New function.
+ (_struct_compat_utimbuf_modtime): New function.
+ * syscalls2.stp (syscall.utime): Use new functions and ctime.
+ (syscall.compat_utime): Likewise.
+
+2008-05-19 Mark Wielaard <mwielaard@redhat.com>
+
+ PR 6524
+ * ctime.stp: Don't try to convert values that won't fit in 32bits.
+
2008-05-08 Ananth N Mavinakayanahalli <ananth@in.ibm.com>
PR 5231
diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp
index da72a7ff..ec7fdcb0 100644
--- a/tapset/aux_syscalls.stp
+++ b/tapset/aux_syscalls.stp
@@ -60,77 +60,77 @@ function _struct_timezone_u:string(uaddr:long)
%}
%{
-static const int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-static void _stp_ctime(time_t t, char *buf, int buflen)
-{
- int mon=1, day, hour, min, sec, num, d, year = 1970;
-
- sec = t % 60;
- min = t/60 % 60;
- hour = t/(60*60) % 24;
- day = t/(24*60*60);
-
- while(1) {
- d = (!(year % 4) && ((year % 100) || !(year % 400))) ? 366 : 365;
- if (day >= d)
- day -= d;
- else
- break;
- year++;
- }
- while (mon < 12) {
- num = days_in_month[mon-1];
- if (mon == 2 && d == 366)
- num++;
- if (day >= num)
- day -= num;
- else
- break;
- mon++;
- }
-
- snprintf(buf, buflen, "%4d/%02d/%02d-%02d:%02d:%02d", year, mon, day+1, hour, min, sec);
- buf[buflen-1] = 0;
-}
+ // Needed for the following four functions
+ // _struct_utimbuf_actime, _struct_utimbuf_modtime,
+ // _struct_compat_utimbuf_actime, _struct_compat_utimbuf_modtime
+ #include <linux/utime.h>
%}
-function _struct_utimbuf_u:string(uaddr:long)
+// Returns the value of the actime field of a utimbuf in user space
+// at the given address, or zero on when userspace data is not accessible.
+function _struct_utimbuf_actime:long(uaddr:long)
%{ /* pure */
- #include <linux/utime.h>
struct utimbuf ubuf;
- static char abuf[24], mbuf[24];
char *ptr = (char *)(unsigned long)THIS->uaddr;
if (ptr == NULL)
- strlcpy (THIS->__retvalue, "NULL", MAXSTRINGLEN);
- else {
- if(_stp_copy_from_user((char*)&ubuf,ptr,sizeof(ubuf)) == 0) {
- _stp_ctime(ubuf.actime, abuf, 24);
- _stp_ctime(ubuf.modtime, mbuf, 24);
- snprintf(THIS->__retvalue, MAXSTRINGLEN, "[%s, %s]", abuf, mbuf);
- } else
- strlcpy (THIS->__retvalue, "UNKNOWN", MAXSTRINGLEN);
- }
+ THIS->__retvalue = 0;
+ else
+ if(_stp_copy_from_user((char*)&ubuf,ptr,sizeof(ubuf)) == 0)
+ THIS->__retvalue = ubuf.actime;
+ else
+ THIS->__retvalue = 0;
%}
-function _struct_compat_utimbuf_u:string(uaddr:long)
+// Returns the value of the modtime field of a utimbuf in user space
+// at the given address, or zero on when userspace data is not accessible.
+function _struct_utimbuf_modtime:long(uaddr:long)
+%{ /* pure */
+ struct utimbuf ubuf;
+ char *ptr = (char *)(unsigned long)THIS->uaddr;
+
+ if (ptr == NULL)
+ THIS->__retvalue = 0;
+ else
+ if(_stp_copy_from_user((char*)&ubuf,ptr,sizeof(ubuf)) == 0)
+ THIS->__retvalue = ubuf.modtime;
+ else
+ THIS->__retvalue = 0;
+%}
+
+// Returns the value of the actime field of a compat_utimbuf in user space
+// at the given address, or zero on when userspace data is not accessible.
+function _struct_compat_utimbuf_actime:long(uaddr:long)
%{ /* pure */
#ifdef CONFIG_COMPAT
- #include <linux/utime.h>
struct compat_utimbuf ubuf;
- static char abuf[24], mbuf[24];
char *ptr = (char *)(unsigned long)THIS->uaddr;
if (ptr == NULL)
- strlcpy (THIS->__retvalue, "NULL", MAXSTRINGLEN);
- else {
- if(_stp_copy_from_user((char*)&ubuf,ptr,sizeof(ubuf)) == 0) {
- _stp_ctime(ubuf.actime, abuf, 24);
- _stp_ctime(ubuf.modtime, mbuf, 24);
- snprintf(THIS->__retvalue, MAXSTRINGLEN, "[%s, %s]", abuf, mbuf);
- } else
- strlcpy (THIS->__retvalue, "UNKNOWN", MAXSTRINGLEN);
- }
+ THIS->__retvalue = 0;
+ else
+ if(_stp_copy_from_user((char*)&ubuf,ptr,sizeof(ubuf)) == 0)
+ THIS->__retvalue = ubuf.actime;
+ else
+ THIS->__retvalue = 0;
+#endif
+%}
+
+// Returns the value of the modtime field of a compat_utimbuf in user space
+// at the given address, or zero on when userspace data is not accessible.
+function _struct_compat_utimbuf_modtime:long(uaddr:long)
+%{ /* pure */
+#ifdef CONFIG_COMPAT
+ struct compat_utimbuf ubuf;
+ char *ptr = (char *)(unsigned long)THIS->uaddr;
+
+ if (ptr == NULL)
+ THIS->__retvalue = 0;
+ else
+ if(_stp_copy_from_user((char*)&ubuf,ptr,sizeof(ubuf)) == 0)
+ THIS->__retvalue = ubuf.modtime;
+ else
+ THIS->__retvalue = 0;
#endif
%}
diff --git a/tapset/ctime.stp b/tapset/ctime.stp
index cd8e5026..96af4d47 100644
--- a/tapset/ctime.stp
+++ b/tapset/ctime.stp
@@ -4,7 +4,23 @@
* Takes an argument of seconds since the epoch as returned by
* gettimeofday_s(). Returns a string of the form
*
- * "Wed Jun 30 21:49:008 1993"
+ * "Wed Jun 30 21:49:08 1993"
+ *
+ * The string will always be exactly 24 characters. If the time would
+ * be unreasonable far in the past (before what can be represented
+ * with a 32 bit offset in seconds from the epoch) the returned string
+ * will be "a long, long time ago...". If the time would be
+ * unreasonable far in the future the returned string will be "far far
+ * in the future..." (both these strings are also 24 characters wide).
+ *
+ * Note that the epoch (zero) corresponds to
+ *
+ * "Thu Jan 1 00:00:00 1970"
+ *
+ * The earliest full date given by ctime, corresponding to epochsecs
+ * -2147483648 is "Fri Dec 13 20:45:52 1901". The latest full date
+ * given by ctime, corresponding to epachsecs 2147483647 is
+ * "Tue Jan 19 03:14:07 2038".
*
* The abbreviations for the days of the week are ‘Sun’, ‘Mon’, ‘Tue’,
* ‘Wed’, ‘Thu’, ‘Fri’, and ‘Sat’. The abbreviations for the months
@@ -21,7 +37,7 @@
* tzcode maintained by Arthur David Olson. In newlib, asctime_r.c
* doesn't have any author/copyright information.
*
- * Changes copyright (C) 2006 Red Hat Inc.
+ * Changes copyright (C) 2006, 2008 Red Hat Inc.
*/
function ctime:string(epochsecs:long)
@@ -70,6 +86,25 @@ function ctime:string(epochsecs:long)
int tm_year; /* year */
int tm_wday; /* day of the week */
+ // Check that the numer of seconds is "reasonable".
+ // Otherwise (especially on 64bit machines) we will be spending
+ // way too much time calculating the correct year, month and
+ // day. Also we would like the returned string to always be 24 chars.
+ // So cap to what can be represented normally on a 32bit machine.
+ int64_t MAX_POS_SECS = 2147483647LL;
+ int64_t MIN_NEG_SECS = -2147483648LL;
+
+ if (THIS->epochsecs > MAX_POS_SECS)
+ {
+ strlcpy(THIS->__retvalue, "far far in the future...", MAXSTRINGLEN);
+ return;
+ }
+ if (THIS->epochsecs < MIN_NEG_SECS)
+ {
+ strlcpy(THIS->__retvalue, "a long, long time ago...", MAXSTRINGLEN);
+ return;
+ }
+
lcltime = THIS->epochsecs;
days = ((long)lcltime) / SECSPERDAY;
diff --git a/tapset/nfs.stp b/tapset/nfs.stp
index 87a2f4cc..ba6bde5f 100644
--- a/tapset/nfs.stp
+++ b/tapset/nfs.stp
@@ -890,7 +890,7 @@ probe nfs.aop.readpage = kernel.function ("nfs_readpage") ?,
rsize = __nfs_server_rsize(__inode)
name = "nfs.aop.readpage"
- argstr = sprintf("%d,%d" , page_index,r_size)
+ argstr = sprintf("%d,%d" , page_index,rsize)
size = 1
units = "pages"
diff --git a/tapset/signal.stp b/tapset/signal.stp
index ec947eb7..72ba9520 100644
--- a/tapset/signal.stp
+++ b/tapset/signal.stp
@@ -63,7 +63,7 @@ probe _signal.send.part2 = kernel.function("send_group_sigqueue")
{
name = "send_group_sigqueue"
task = $p
- # sinfo = $q->info
+ sinfo = 0 # $q->info
shared = 1
send2queue = 1
}
@@ -72,7 +72,7 @@ probe _signal.send.part3 = kernel.function("send_sigqueue")
{
name = "send_sigqueue"
task = $p
- # sinfo = $q->info
+ sinfo = 0 # $q->info
shared = 0
send2queue = 1
}
diff --git a/tapset/syscalls2.stp b/tapset/syscalls2.stp
index 558e89bb..0db50347 100644
--- a/tapset/syscalls2.stp
+++ b/tapset/syscalls2.stp
@@ -1364,7 +1364,7 @@ probe syscall.semtimedop.return = kernel.function("sys_semtimedop").return ? {
probe syscall.compat_sys_semtimedop = kernel.function("compat_sys_semtimedop") ? {
name = "compat_sys_semtimedop"
semid = $semid
- sops_uaddr = tsems
+ sops_uaddr = $tsems
nsops = $nsops
timeout_uaddr = $timeout
argstr = sprintf("%d, %p, %d, %s", $semid, $tsems, $nsops,
@@ -2897,11 +2897,13 @@ probe syscall.ustat.return =
# long sys_utime(char __user * filename, struct utimbuf __user * times)
probe syscall.utime = kernel.function("sys_utime") ? {
name = "utime"
- filename_uaddr = $filename
- filename = user_string($filename)
- buf_uaddr = $times
- buf_str = _struct_utimbuf_u($times)
- argstr = sprintf("%s, %s", user_string_quoted($filename), buf_str)
+ filename_uaddr = pointer_arg(1)
+ filename = user_string_quoted(filename_uaddr)
+ buf_uaddr = pointer_arg(2)
+ actime = _struct_utimbuf_actime(buf_uaddr)
+ modtime = _struct_utimbuf_modtime(buf_uaddr)
+ argstr = sprintf("%s, [%s, %s]", filename,
+ ctime(actime), ctime(modtime))
}
probe syscall.utime.return = kernel.function("sys_utime").return ? {
name = "utime"
@@ -2911,11 +2913,13 @@ probe syscall.utime.return = kernel.function("sys_utime").return ? {
# long compat_sys_utime(char __user *filename, struct compat_utimbuf __user *t)
probe syscall.compat_utime = kernel.function("compat_sys_utime") ? {
name = "utime"
- filename_uaddr = $filename
- filename = user_string($filename)
- buf_uaddr = $t
- buf_str = _struct_compat_utimbuf_u($t)
- argstr = sprintf("%s, %s", user_string_quoted($filename), _struct_compat_utimbuf_u($t))
+ filename_uaddr = pointer_arg(1)
+ filename = user_string_quoted(filename_uaddr)
+ buf_uaddr = pointer_arg(2)
+ actime = _struct_compat_utimbuf_actime(buf_uaddr)
+ modtime = _struct_compat_utimbuf_modtime(buf_uaddr)
+ argstr = sprintf("%s, [%s, %s]", filename,
+ ctime(actime), ctime(modtime))
}
probe syscall.compat_utime.return = kernel.function("compat_sys_utime").return ? {
name = "utime"
diff --git a/tapset/vfs.stp b/tapset/vfs.stp
index 75b1b279..6073dffc 100644
--- a/tapset/vfs.stp
+++ b/tapset/vfs.stp
@@ -33,16 +33,10 @@ function __bdevname:string (bdev:long) %{ /* pure */
global __devnames
function __find_bdevname:string(dev:long, bdev:long)
{
-# return ""
-
- __devname = __devnames[dev]
-
- if (__devname != null)
- return __devname
-
- __devname = __devnames[dev] = __bdevname(bdev)
-
- return __devname
+ if (dev in __devnames)
+ return __devnames[dev]
+ else
+ return __devnames[dev] = __bdevname(bdev)
}
function ppos_pos:long (ppos:long) %{ /* pure */
diff --git a/tapset/x86_64/syscalls.stp b/tapset/x86_64/syscalls.stp
index 418aaf23..c9ab617f 100644
--- a/tapset/x86_64/syscalls.stp
+++ b/tapset/x86_64/syscalls.stp
@@ -131,7 +131,7 @@ probe syscall.vm86_warning.return = kernel.function("sys32_vm86_warning").return
#
probe syscall.pipe32 = kernel.function("sys32_pipe") {
name = "pipe"
- argstr = sprintf("%p", fd)
+ argstr = sprintf("%p", $fd)
}
probe syscall.pipe32.return = kernel.function("sys32_pipe").return {
name = "pipe"
diff --git a/tapsets.cxx b/tapsets.cxx
index 0ba22331..7207c072 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -20,7 +20,11 @@
#include <deque>
#include <iostream>
#include <map>
+#ifdef HAVE_TR1_UNORDERED_MAP
+#include <tr1/unordered_map>
+#else
#include <ext/hash_map>
+#endif
#include <set>
#include <sstream>
#include <stdexcept>
@@ -537,12 +541,17 @@ module_cache
};
typedef struct module_cache module_cache_t;
+#ifdef HAVE_TR1_UNORDERED_MAP
+typedef tr1::unordered_map<string,Dwarf_Die> cu_function_cache_t;
+typedef tr1::unordered_map<string,cu_function_cache_t*> mod_cu_function_cache_t; // module:cu -> function -> die
+#else
struct stringhash {
size_t operator() (const string& s) const { hash<const char*> h; return h(s.c_str()); }
};
typedef hash_map<string,Dwarf_Die,stringhash> cu_function_cache_t;
typedef hash_map<string,cu_function_cache_t*,stringhash> mod_cu_function_cache_t; // module:cu -> function -> die
+#endif
struct
symbol_table
diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog
index c951971b..fa6e4fad 100644
--- a/testsuite/ChangeLog
+++ b/testsuite/ChangeLog
@@ -1,3 +1,49 @@
+2008-05-21 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6538
+ * buildok/ioscheduler.stp, nine.stp, scsi.stp, sixteen.stp,
+ socket.stp, stat_insert.stp: Adapt to new warnings.
+ * systemtap.maps/linear_empty.exp, systemtap.samples/args.exp,
+ systemtap.samples/poll_map.stp, systemtap.string/strtol.stp: Ditto.
+
+2008-05-20 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6538
+ * systemtap.base/warnings.*: New tests.
+ * buildok/eleven.stp, systemtap.examples/disktop.stp,
+ transok/three.stp: Adapt to new warnings.
+
+2008-05-21 Stan Cox <scox@redhat.com>
+
+ * systemtap.base/optim_arridx.stp: Test compound assignment and
+ binary expression.
+ * systemtap.base/optim_arridx.exp: Likewise.
+ (optim_arridx_run): Don't check warnings.
+
+2008-05-21 Mark Wielaard <mwielaard@redhat.com>
+
+ * buildok/aux_syscalls-embedded.stp: Don't check _struct_utimbuf_u
+ and _struct_compat_utimbuf_u. Check new _struct_utimbuf_actime,
+ _struct_utimbuf_modtime, _struct_compat_utimbuf_actime and
+ _struct_compat_utimbuf_modtime.
+
+2008-05-20 Mark Wielaard <mwielaard@redhat.com>
+
+ PR 5001
+ * systemtap.syscall/futimes.c (utime): Expect new time format.
+ * systemtap.syscall/stat.c (utime): Likewise.
+
+2008-05-19 Mark Wielaard <mwielaard@redhat.com>
+
+ PR 6524
+ * systemtap.base/ctime.stp: New test.
+ * systemtap.base/ctime.exp: New expect file.
+
+2008-05-19 Stan Cox <scox@redhat.com>
+
+ * systemtap.base/optim_arridx.stp: New test.
+ * systemtap.base/optim_arridx.exp: New test.
+
2008-04-29 Frank Ch. Eigler <fche@elastic.org>
PR 6466.
diff --git a/testsuite/buildok/aux_syscalls-embedded.stp b/testsuite/buildok/aux_syscalls-embedded.stp
index 2b552801..ce00893d 100755
--- a/testsuite/buildok/aux_syscalls-embedded.stp
+++ b/testsuite/buildok/aux_syscalls-embedded.stp
@@ -4,8 +4,10 @@ probe begin {
print (_struct_timeval_u(0,0))
print (_struct_compat_timeval_u(0,0))
print (_struct_timezone_u (0))
- print (_struct_utimbuf_u(0))
- print (_struct_compat_utimbuf_u(0))
+ print (_struct_utimbuf_actime(0))
+ print (_struct_utimbuf_modtime(0))
+ print (_struct_compat_utimbuf_actime(0))
+ print (_struct_compat_utimbuf_modtime(0))
print (_struct_timespec_u(0,0))
print (_struct_compat_timespec_u(0,0))
print (_struct_itimerspec_u(0))
diff --git a/testsuite/buildok/eleven.stp b/testsuite/buildok/eleven.stp
index 66d4a318..e6627fdc 100755
--- a/testsuite/buildok/eleven.stp
+++ b/testsuite/buildok/eleven.stp
@@ -3,15 +3,17 @@
probe begin
{
a = -1 / -1;
- b = 2147483647;
- c = 4294967295 / a;
+ b = 2147483647 + a;
+ c = 4294967295 / b;
d = (-2147483647-1) % c;
- e = 9223372036854775807 * b;
- d /= b % e;
- b %= 0 / f;
- x = 1 / 0;
+ e = 9223372036854775807 * d;
+ f /= b % e;
+ g %= 0 / f;
+ h = 1 / 0;
+ println (h)
}
probe end
{
y %= 0;
+ println (y)
}
diff --git a/testsuite/buildok/ioscheduler.stp b/testsuite/buildok/ioscheduler.stp
index 7a39c455..2d88d2d5 100755
--- a/testsuite/buildok/ioscheduler.stp
+++ b/testsuite/buildok/ioscheduler.stp
@@ -1,4 +1,6 @@
-#! stap -p4
+#! stap -wp4
+
+# PR6538: "-w" is above since disk_major/disk_minor are not defined by all aliases.
probe ioscheduler.*
{
diff --git a/testsuite/buildok/nine.stp b/testsuite/buildok/nine.stp
index d9a15276..a0ca1d40 100755
--- a/testsuite/buildok/nine.stp
+++ b/testsuite/buildok/nine.stp
@@ -4,5 +4,5 @@ function f () { }
function g (arg) { }
probe begin {
- true ? f() : g(1);
+ (true=1) ? f() : g(1);
}
diff --git a/testsuite/buildok/scsi.stp b/testsuite/buildok/scsi.stp
index 6f60de2f..dfe855de 100755
--- a/testsuite/buildok/scsi.stp
+++ b/testsuite/buildok/scsi.stp
@@ -23,7 +23,7 @@ probe scsi.iodispatching
{
printf("ppname: %s, %d, %d, %d, %d, %d, %d, %p, %d\n", probefunc(),
host_no, channel, lun, dev_id, device_state, data_direction,
- request_buffer, req_bufflen)
+ request_buffer, request_bufflen)
}
diff --git a/testsuite/buildok/sixteen.stp b/testsuite/buildok/sixteen.stp
index 0e313fa8..97721a2d 100755
--- a/testsuite/buildok/sixteen.stp
+++ b/testsuite/buildok/sixteen.stp
@@ -3,7 +3,7 @@
global a
function foo () {
- if (a[k] == "sayonara") { return 2 }
+ if (a[4] == "sayonara") { return 2 }
}
diff --git a/testsuite/buildok/socket.stp b/testsuite/buildok/socket.stp
index 4b9142a9..5ada4018 100755
--- a/testsuite/buildok/socket.stp
+++ b/testsuite/buildok/socket.stp
@@ -1,4 +1,4 @@
-#! stap -p4
+#! stap -wp4
probe socket.send, socket.receive,
socket.sendmsg, socket.sendmsg.return,
@@ -33,7 +33,7 @@ probe socket.send, socket.receive,
typ = sock_type_str2num(tstr)
log(sprintf("%d, %d, %s", type, typ, tstr))
- log(sprintf("%d", success))
+ log(sprintf("%d", success)) # -w since success is not universally defined
}
diff --git a/testsuite/buildok/stat_insert.stp b/testsuite/buildok/stat_insert.stp
index 4039a190..7d7eb98e 100755
--- a/testsuite/buildok/stat_insert.stp
+++ b/testsuite/buildok/stat_insert.stp
@@ -15,8 +15,8 @@ function wibble()
i = 0
logmap[i++, "stewed"] <<< 1
logmap[i++, "boiled"] <<< 1 + 2
- logmap[i++, "baked"] <<< x
- logmap[i++, "fried"] <<< (x * y) + 3
+ logmap[i++, "baked"] <<< (x = 0)
+ logmap[i++, "fried"] <<< (x * (y=2)) + 3
}
function wobble()
diff --git a/testsuite/systemtap.base/ctime.exp b/testsuite/systemtap.base/ctime.exp
new file mode 100644
index 00000000..f6db096a
--- /dev/null
+++ b/testsuite/systemtap.base/ctime.exp
@@ -0,0 +1,18 @@
+set test "ctime"
+set ::result_string {Thu Jan 1 00:00:00 1970
+Wed Dec 31 23:59:59 1969
+Thu Jan 1 00:00:01 1970
+Sat Mar 3 09:46:40 1973
+Fri Feb 13 23:31:30 2009
+Sat Jan 10 13:37:04 2004
+Fri Jul 13 11:01:20 2012
+a long, long time ago...
+far far in the future...
+Fri Dec 13 20:45:52 1901
+a long, long time ago...
+Tue Jan 19 03:14:07 2038
+far far in the future...
+a long, long time ago...
+far far in the future...
+}
+stap_run2 $srcdir/$subdir/$test.stp
diff --git a/testsuite/systemtap.base/ctime.stp b/testsuite/systemtap.base/ctime.stp
new file mode 100644
index 00000000..680baff7
--- /dev/null
+++ b/testsuite/systemtap.base/ctime.stp
@@ -0,0 +1,55 @@
+probe begin
+{
+ // epoch
+ println(ctime(0))
+
+ // epoch - 1
+ println(ctime(-1))
+
+ // epoch + 1
+ println(ctime(1))
+
+ // Some funny numbers
+ println(ctime(100000000))
+ println(ctime(1234567890))
+ println(ctime(1073741824))
+ println(ctime(0x50000000))
+
+ // some time really long ago
+ secspermin = 60
+ minsperhour = 60
+ hoursperday = 24
+ secsperhour = secspermin * minsperhour
+ secsperday = secsperhour * hoursperday
+ epoch_year = 1970
+ time = -1 * (epoch_year - 1000) * 365 * secsperday
+ println(ctime(time))
+
+ // some time in the far future
+ time = (9999 - epoch_year) * 365 * secsperday
+ println(ctime(time))
+
+ // min 32 bit
+ time = -2147483648
+ println(ctime(time))
+
+ // over the edge, a long, long time ago...
+ time--
+ println(ctime(time))
+
+ // max 32 bit
+ time = 2147483647
+ println(ctime(time))
+
+ // over the edge, far far in the future...
+ time++
+ println(ctime(time))
+
+ // min 64 bit
+ println(ctime(-9223372036854775808))
+
+ // max 64 bit
+ println(ctime(9223372036854775807))
+
+ exit()
+}
diff --git a/testsuite/systemtap.base/optim_arridx.exp b/testsuite/systemtap.base/optim_arridx.exp
new file mode 100644
index 00000000..0987dec6
--- /dev/null
+++ b/testsuite/systemtap.base/optim_arridx.exp
@@ -0,0 +1,77 @@
+# test integer limits. Set and print variables and print constants.
+
+set test "optim_arridx"
+set ::result_string {# globals
+arr1:long [long, long]
+arr2:long [long]
+arr3:long [long]
+# functions
+fna:long (a:long)
+return a
+fnb:long (a:long, b:long)
+return (a) + (b)
+exit:unknown ()
+%{
+ atomic_set (&session_state, STAP_SESSION_STOPPING);
+ _stp_exit ();
+%}
+# probes
+begin /* <- begin */
+ # locals
+ idx2:long
+ j:long
+ k:long
+ b:long
+ m:long
+ arr1:long [long]
+ arr2:long [long, long]
+ aa:long
+ bb:long
+ cc:long
+ dd:long
+ ee:long
+{
+(arr2[(idx2) = (2)]) = (20)
+(arr2[(j) = (4)]) = (40)
+(arr1[fna((k) = (0)), k]) = (1)
+(arr1[(b) = (1), b]) = (2)
+fnb((arr3[0]) = (4), arr3[0])
+(m) = (1)
+for (2; (m) <= (10); (m)++) ;
+printf("%d %d %d %d\\n", arr1[0], arr2[0, 0], idx2, j)
+(aa) = (fna(1))
+(bb) = (fnb((cc) = (1), 2))
+for (1; (bb) < (10); (bb)++) (cc) += (bb)
+for ((dd) = (1); (dd) < (10); 1) (dd) += (1)
+if (1) (ee) = (1)
+
+(cc) = ((dd) = (5))
+(cc) = ((4) + ((cc) = (1)))
+printf("%d %d %d %d %d", aa, bb, cc, dd, ee)
+exit()
+}
+}
+
+proc optim_arridx_run { TEST_NAME args } {
+ # zap the srcdir prefix
+ set test_file_name $TEST_NAME
+ set TEST_NAME [regsub {.*/testsuite/} $TEST_NAME ""]
+
+ set cmd [concat stap $args $test_file_name]
+ catch {eval exec $cmd} res
+
+ set n 0
+ set expected [split $::result_string "\n"]
+ foreach line [split $res "\n"] {
+ if {![string equal $line [lindex $expected $n]]} {
+ fail "$TEST_NAME"
+ send_log "line [expr $n + 1]: expected \"[lindex $expected $n]\"\n"
+ send_log "Got \"$line\"\n"
+ return
+ }
+ incr n
+ }
+ pass "$TEST_NAME"
+}
+
+optim_arridx_run $srcdir/$subdir/$test.stp -p2 -v 2>/dev/null
diff --git a/testsuite/systemtap.base/optim_arridx.stp b/testsuite/systemtap.base/optim_arridx.stp
new file mode 100644
index 00000000..20710c7f
--- /dev/null
+++ b/testsuite/systemtap.base/optim_arridx.stp
@@ -0,0 +1,45 @@
+global arr1, arr2, arr3, elide_idx1, elide_global_a, elide_global_b
+
+function fna(a:long) {return a}
+function fnb(a:long, b:long) {return a+b}
+
+probe begin {
+ // array indices
+ arr2[elide_idx1 = 1] = 10
+ arr2[idx2 = 2] = 20
+ arr2[elide_i=3] = 30
+ arr2[j=4] = 40
+ arr1[fna(k = 0), k] = 1
+ arr1[b = 1, b] = 2
+ arr1[elide_c = 2,2] = 3
+ fnb(arr3[0] = 4, arr3[0])
+ m = 1
+ for (elide_n=2; m <= 10; m++)
+ arr2[m] = m * 10
+ printf ("%d %d %d %d\n", arr1[0], arr2[0,0], idx2, j)
+
+ // function args
+ aa = fna(elide_aa = 1)
+ bb = fnb(cc = 1, elide_global_a = 2)
+
+ // loop
+ for (elide_bb = 1; bb < 10; bb++)
+ cc += bb
+ for (dd = 1; dd < 10; elide_ee = 1)
+ dd += 1
+
+ // conditional
+ if (elide_ff = 0)
+ elide_ff = 1
+ if (elide_global_b = 1)
+ ee = 1
+
+ // compound assignment
+ cc = elide_gg=dd=5
+
+ // binary expression
+ cc = ((elide_hh = 4) + (cc = 1))
+
+ printf("%d %d %d %d %d", aa, bb, cc, dd, ee)
+ exit ()
+}
diff --git a/testsuite/systemtap.base/warnings.exp b/testsuite/systemtap.base/warnings.exp
index 025bde89..6cff723d 100644
--- a/testsuite/systemtap.base/warnings.exp
+++ b/testsuite/systemtap.base/warnings.exp
@@ -9,7 +9,7 @@ expect {
eof { }
}
wait
-if {$ok == 9} {
+if {$ok == 22} {
pass $test
} else {
fail "$test ($ok)"
diff --git a/testsuite/systemtap.base/warnings.stp b/testsuite/systemtap.base/warnings.stp
index a0ce8d8d..a2ac5afc 100644
--- a/testsuite/systemtap.base/warnings.stp
+++ b/testsuite/systemtap.base/warnings.stp
@@ -1,9 +1,8 @@
-# PR 1119
+# PR 1119, 6538
global elide_me1
-
function elide_me2 () {}
-
function foo:long () { elide_me3 = 1 }
-
+function bar() { print(elide+me1) ; ; ; }
probe never { elide_me4 = 1; (elide_me5+5); print (foo()) }
+probe never { print(elide+me1) bar () }
diff --git a/testsuite/systemtap.examples/ChangeLog b/testsuite/systemtap.examples/ChangeLog
index 41b70135..743e7adf 100644
--- a/testsuite/systemtap.examples/ChangeLog
+++ b/testsuite/systemtap.examples/ChangeLog
@@ -1,3 +1,11 @@
+2008-05-20 William Cohen <wcohen@redhat.com>
+
+ * io_submit.stp, io_submit.meta:
+ * traceio.stp, traceio.meta:
+ * iotop.stp, iotop.meta:
+ * disktop.stp, disktop.meta:
+ * sigkill.stp, sigkill.meta: New.
+
2008-05-09 William Cohen <wcohen@redhat.com>
* syscalls_by_pid.meta, syscalls_by_proc.meta:
diff --git a/testsuite/systemtap.examples/disktop.meta b/testsuite/systemtap.examples/disktop.meta
new file mode 100644
index 00000000..b063075b
--- /dev/null
+++ b/testsuite/systemtap.examples/disktop.meta
@@ -0,0 +1,13 @@
+title: Summarize Disk Read/Write Traffic
+name: disktop.stp
+version: 1.0
+author: Oracle
+keywords: disk
+subsystem: disk
+status: production
+exit: user-controlled
+output: timed
+scope: system-wide
+description: Get the status of reading/writing disk every 5 seconds, output top ten entries during that period.
+test_check: stap -p4 disktop.stp
+test_installcheck: stap disktop.stp -c "sleep 1"
diff --git a/testsuite/systemtap.examples/disktop.stp b/testsuite/systemtap.examples/disktop.stp
new file mode 100644
index 00000000..2637d735
--- /dev/null
+++ b/testsuite/systemtap.examples/disktop.stp
@@ -0,0 +1,69 @@
+#!/usr/bin/env stap
+#
+# Copyright (C) 2007 Oracle Corp.
+#
+# Get the status of reading/writing disk every 5 seconds, output top ten entries
+#
+# This is free software,GNU General Public License (GPL); either version 2, or (at your option) any
+# later version.
+#
+# Usage:
+# ./disktop.stp
+#
+
+global io_stat,device
+global read_bytes,write_bytes
+
+probe kernel.function("vfs_read").return {
+ if ($return>0) {
+ dev = __file_dev($file)
+ devname = __find_bdevname(dev,__file_bdev($file))
+
+ if (devname!="N/A") {/*skip read from cache*/
+ io_stat[pid(),execname(),uid(),ppid(),"R"] += $return
+ device[pid(),execname(),uid(),ppid(),"R"] = devname
+ read_bytes += $return
+ }
+ }
+}
+
+probe kernel.function("vfs_write").return {
+ if ($return>0) {
+ dev = __file_dev($file)
+ devname = __find_bdevname(dev,__file_bdev($file))
+
+ if (devname!="N/A") { /*skip update cache*/
+ io_stat[pid(),execname(),uid(),ppid(),"W"] += $return
+ device[pid(),execname(),uid(),ppid(),"W"] = devname
+ write_bytes += $return
+ }
+ }
+}
+
+probe timer.ms(5000) {
+ /* skip non-read/write disk */
+ if (read_bytes+write_bytes) {
+
+ printf("\n%-25s, %-8s%4dKb/sec, %-7s%6dKb, %-7s%6dKb\n\n",ctime(gettimeofday_s()),"Average:",
+ ((read_bytes+write_bytes)/1024)/5,"Read:",read_bytes/1024,"Write:",write_bytes/1024)
+
+ /* print header */
+ printf("%8s %8s %8s %25s %8s %4s %12s\n","UID","PID","PPID","CMD","DEVICE","T","BYTES")
+ }
+ /* print top ten I/O */
+ foreach ([process,cmd,userid,parent,action] in io_stat- limit 10)
+ printf("%8d %8d %8d %25s %8s %4s %12d\n",userid,process,parent,cmd,device[process,cmd,userid,parent,action],action,io_stat[process,cmd,userid,parent,action])
+
+ /* clear data */
+ delete io_stat
+ delete device
+ read_bytes = 0
+ write_bytes = 0
+}
+
+probe end{
+ delete io_stat
+ delete device
+ delete read_bytes
+ delete write_bytes
+}
diff --git a/testsuite/systemtap.examples/io_submit.meta b/testsuite/systemtap.examples/io_submit.meta
new file mode 100644
index 00000000..911cb837
--- /dev/null
+++ b/testsuite/systemtap.examples/io_submit.meta
@@ -0,0 +1,13 @@
+title: Tally Reschedule Reason During AIO io_submit Call
+name: io_submit.stp
+version: 1.0
+author: Oracle
+keywords: io backtrace
+subsystem: io
+status: production
+exit: user-controlled
+output: sorted on-exit
+scope: system-wide
+description: When a reschedule occurs during an AIO io_submit call, accumulate the traceback in a histogram. When the script exits prints out a sorted list from most common to least common backtrace.
+test_check: stap -p4 io_submit.stp
+test_installcheck: stap io_submit.stp -c "sleep 1"
diff --git a/testsuite/systemtap.examples/io_submit.stp b/testsuite/systemtap.examples/io_submit.stp
new file mode 100644
index 00000000..735dd6f9
--- /dev/null
+++ b/testsuite/systemtap.examples/io_submit.stp
@@ -0,0 +1,71 @@
+#!/bin/env stap
+#
+# Copyright (C) 2007 Oracle Corp. Chris Mason <chris.mason@oracle.com>
+#
+# This was implemented to find the most common causes of schedule during
+# the AIO io_submit call. It does this by recording which pids are inside
+# AIO, and recording the current stack trace if one of those pids is
+# inside schedule.
+# When the probe exits, it prints out the 30 most common call stacks for
+# schedule().
+#
+# This file is free software. You can redistribute it and/or modify it under
+# the terms of the GNU General Public License (GPL); either version 2, or (at
+# your option) any later version.
+
+global in_iosubmit
+global traces
+
+/*
+ * add a probe to sys_io_submit, on entry, record in the in_iosubmit
+ * hash table that this proc is in io_submit
+ */
+probe syscall.io_submit {
+ in_iosubmit[tid()] = 1
+}
+
+/*
+ * when we return from sys_io_submit, record that we're no longer there
+ */
+probe syscall.io_submit.return {
+ /* this assumes a given proc will do lots of io_submit calls, and
+ * so doesn't do the more expensive "delete in_iosubmit[p]". If
+ * there are lots of procs doing small number of io_submit calls,
+ * the hash may grow pretty big, so using delete may be better
+ */
+ in_iosubmit[tid()] = 0
+}
+
+/*
+ * every time we call schedule, check to see if we started off in
+ * io_submit. If so, record our backtrace into the traces histogram
+ */
+probe kernel.function("schedule") {
+ if (tid() in in_iosubmit) {
+ traces[backtrace()]++
+
+ /*
+ * change this to if (1) if you want a backtrace every time
+ * you go into schedule from io_submit. Unfortunately, the traces
+ * saved into the traces histogram above are truncated to just a
+ * few lines. so the only way to see the full trace is via the
+ * more verbose print_backtrace() right here.
+ */
+ if (0) {
+ printf("schedule in io_submit!\n")
+ print_backtrace()
+ }
+ }
+}
+
+/*
+ * when stap is done (via ctrl-c) go through the record of all the
+ * trace paths and print the 30 most common.
+ */
+probe end {
+ foreach (stack in traces- limit 30) {
+ printf("%d:", traces[stack])
+ print_stack(stack);
+ }
+}
+
diff --git a/testsuite/systemtap.examples/iotop.meta b/testsuite/systemtap.examples/iotop.meta
new file mode 100644
index 00000000..4eba0130
--- /dev/null
+++ b/testsuite/systemtap.examples/iotop.meta
@@ -0,0 +1,13 @@
+title: Periodically Print I/O Activity by Process Name
+name: iotop.stp
+version: 1.0
+author: anonymous
+keywords: io
+subsystem: io
+status: production
+exit: user-controlled
+output: timed
+scope: system-wide
+description: Every five seconds print out the top ten executables generating I/O traffic during that interval sorted in decending order.
+test_check: stap -p4 iotop.stp
+test_installcheck: stap iotop.stp -c "sleep 1"
diff --git a/testsuite/systemtap.examples/iotop.stp b/testsuite/systemtap.examples/iotop.stp
new file mode 100644
index 00000000..6050343c
--- /dev/null
+++ b/testsuite/systemtap.examples/iotop.stp
@@ -0,0 +1,25 @@
+global reads, writes, total_io
+
+probe kernel.function("vfs_read") {
+ reads[execname()] += $count
+}
+
+probe kernel.function("vfs_write") {
+ writes[execname()] += $count
+}
+
+# print top 10 IO processes every 5 seconds
+probe timer.s(5) {
+ foreach (name in writes)
+ total_io[name] += writes[name]
+ foreach (name in reads)
+ total_io[name] += reads[name]
+ printf ("%16s\t%10s\t%10s\n", "Process", "KB Read", "KB Written")
+ foreach (name in total_io- limit 10)
+ printf("%16s\t%10d\t%10d\n", name,
+ reads[name]/1024, writes[name]/1024)
+ delete reads
+ delete writes
+ delete total_io
+ print("\n")
+}
diff --git a/testsuite/systemtap.examples/sigkill.meta b/testsuite/systemtap.examples/sigkill.meta
new file mode 100644
index 00000000..57032224
--- /dev/null
+++ b/testsuite/systemtap.examples/sigkill.meta
@@ -0,0 +1,14 @@
+title: Track SIGKILL Signals
+name: sigkill.stp
+version: 1.0
+author: Red Hat
+keywords: signals
+subsystem: signals
+status: production
+exit: user-controlled
+output: trace
+scope: systemwide
+description: The script traces any SIGKILL signals. When that SIGKILL signal is sent to a process, the script prints out the signal name, the desination executable and process ID, the executable name user ID that sent the signal.
+arg_1: The name of the signal to look for on selected process.
+test_check: stap -p4 sigkill.stp
+test_installcheck: stap sigkill.stp -c "sleep 1"
diff --git a/testsuite/systemtap.examples/sigkill.stp b/testsuite/systemtap.examples/sigkill.stp
new file mode 100644
index 00000000..8f754219
--- /dev/null
+++ b/testsuite/systemtap.examples/sigkill.stp
@@ -0,0 +1,23 @@
+#!/usr/bin/env stap
+# sigkill.stp
+# Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# /usr/share/systemtap/tapset/signal.stp:
+# [...]
+# probe signal.send = _signal.send.*
+# {
+# sig=$sig
+# sig_name = _signal_name($sig)
+# sig_pid = task_pid(task)
+# pid_name = task_execname(task)
+# [...]
+
+probe signal.send {
+ if (sig_name == "SIGKILL")
+ printf("%s was sent to %s (pid:%d) by %s uid:%d\n",
+ sig_name, pid_name, sig_pid, execname(), uid())
+}
diff --git a/testsuite/systemtap.examples/traceio.meta b/testsuite/systemtap.examples/traceio.meta
new file mode 100644
index 00000000..a82a26aa
--- /dev/null
+++ b/testsuite/systemtap.examples/traceio.meta
@@ -0,0 +1,13 @@
+title: Track Cumulative I/O Activity by Process Name
+name: traceio.stp
+version: 1.0
+author: Red Hat
+keywords: io
+subsystem: io
+status: production
+exit: user-controlled
+output: timed
+scope: system-wide
+description: Every second print out the top ten executables sorted in decending order based on cumulative I/O traffic observed.
+test_check: stap -p4 traceio.stp
+test_installcheck: stap traceio.stp -c "sleep 1"
diff --git a/testsuite/systemtap.examples/traceio.stp b/testsuite/systemtap.examples/traceio.stp
new file mode 100644
index 00000000..d3757c23
--- /dev/null
+++ b/testsuite/systemtap.examples/traceio.stp
@@ -0,0 +1,32 @@
+#!/usr/bin/env stap
+# traceio.stp
+# Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+
+global reads, writes, total_io
+
+probe kernel.function("vfs_read").return {
+ reads[execname()] += $return
+}
+
+probe kernel.function("vfs_write").return {
+ writes[execname()] += $return
+}
+
+probe timer.s(1) {
+ foreach (p in reads)
+ total_io[p] += reads[p]
+ foreach (p in writes)
+ total_io[p] += writes[p]
+ foreach(p in total_io- limit 10)
+ printf("%15s r: %8d KiB w: %8d KiB\n",
+ p, reads[p]/1024,
+ writes[p]/1024)
+ printf("\n")
+ # Note we don't zero out reads, writes and total_io,
+ # so the values are cumulative since the script started.
+}
diff --git a/testsuite/systemtap.maps/absentstats.stp b/testsuite/systemtap.maps/absentstats.stp
index aeb176a1..0968cd58 100644
--- a/testsuite/systemtap.maps/absentstats.stp
+++ b/testsuite/systemtap.maps/absentstats.stp
@@ -1,5 +1,9 @@
# stap -DMAXERRORS=40
+# NB: PR 6538 will cause systemtap to warn about the read-only globals;
+# we can't help that though since the point of this test is to see what
+# happens when an empty (never written-to) aggregate is queried.
+
global sc
probe begin { println(@count(sc)) }
probe begin { print(@sum(sc)) }
diff --git a/testsuite/systemtap.maps/linear_empty.exp b/testsuite/systemtap.maps/linear_empty.exp
index 9bcc64eb..88a53a31 100644
--- a/testsuite/systemtap.maps/linear_empty.exp
+++ b/testsuite/systemtap.maps/linear_empty.exp
@@ -4,6 +4,5 @@ set test "linear_empty"
set ::result_string {count=0
}
-stap_run2 $srcdir/$subdir/$test.stp
-
+stap_run2 $srcdir/$subdir/$test.stp -w
diff --git a/testsuite/systemtap.samples/args.exp b/testsuite/systemtap.samples/args.exp
index 8bed7c9e..6b1fd3d0 100644
--- a/testsuite/systemtap.samples/args.exp
+++ b/testsuite/systemtap.samples/args.exp
@@ -12,7 +12,7 @@ if [file exists $staprunpath] {
}
set modname "args_[pid]"
-spawn stap -k -p4 -m $modname $srcdir/$subdir/args.stp
+spawn stap -w -k -p4 -m $modname $srcdir/$subdir/args.stp
set tmpdir NO_SUCH_FILE
expect {
-timeout 120
diff --git a/testsuite/systemtap.samples/poll_map.stp b/testsuite/systemtap.samples/poll_map.stp
index fb6b16e6..cd39b433 100755
--- a/testsuite/systemtap.samples/poll_map.stp
+++ b/testsuite/systemtap.samples/poll_map.stp
@@ -6,7 +6,7 @@
global called, num_polls
probe kernel.function( "sys_*" ).call {
- called[execname(),name]++
+ called[execname(),probefunc()]++
}
probe timer.ms(1000)
diff --git a/testsuite/systemtap.string/strtol.stp b/testsuite/systemtap.string/strtol.stp
index dcd1fe71..4f579e7d 100644
--- a/testsuite/systemtap.string/strtol.stp
+++ b/testsuite/systemtap.string/strtol.stp
@@ -23,7 +23,6 @@ probe begin
printf("%d\n", strtol(teststr9, 16))
printf("%d\n", strtol(teststr9, 8))
printf("%d\n", strtol(teststr9, 2))
- printf("%d\n", strtol(teststr10, 2))
exit()
}
diff --git a/testsuite/systemtap.syscall/futimes.c b/testsuite/systemtap.syscall/futimes.c
index 359afad3..eca1efc7 100644
--- a/testsuite/systemtap.syscall/futimes.c
+++ b/testsuite/systemtap.syscall/futimes.c
@@ -31,7 +31,7 @@ int main()
times.actime = 1000000000;
times.modtime = 2000000000;
syscall(__NR_utime, "foobar", &times );
- // utime ("foobar", \[2001/09/09-01:46:40, 2033/05/18-03:33:20\])
+ // utime ("foobar", \[Sun Sep 9 01:46:40 2001, Wed May 18 03:33:20 2033])
#endif /* __NR_utimes */
#ifdef __NR_utimes
diff --git a/testsuite/systemtap.syscall/stat.c b/testsuite/systemtap.syscall/stat.c
index deade3e0..6be5cc79 100644
--- a/testsuite/systemtap.syscall/stat.c
+++ b/testsuite/systemtap.syscall/stat.c
@@ -39,7 +39,7 @@ int main()
#ifdef __ia64__
// utimes ("foobar", \[1.000000\]\[1135641600.000000\]) =
#else
- // utime ("foobar", \[1970/01/01-00:00:01, 2005/12/27-00:00:00\]) = 0
+ // utime ("foobar", \[Thu Jan 1 00:00:01 1970, Tue Dec 27 00:00:00 2005\]) = 0
#endif
ubuf.actime = 1135690000;
@@ -48,7 +48,7 @@ int main()
#ifdef __ia64__
// utimes ("foobar", \[1135690000.000000\]\[1135700000.000000\]) =
#else
- // utime ("foobar", \[2005/12/27-13:26:40, 2005/12/27-16:13:20\]) = 0
+ // utime ("foobar", \[Tue Dec 27 13:26:40 2005, Tue Dec 27 16:13:20 2005\]) = 0
#endif
return 0;
}
diff --git a/testsuite/transok/three.stp b/testsuite/transok/three.stp
index 6e99b640..a7406db4 100755
--- a/testsuite/transok/three.stp
+++ b/testsuite/transok/three.stp
@@ -7,6 +7,7 @@ function f1 (a, b) {
d = "hello";
# poo[c] = bab[d] = "hi"
bab = "hi";
+ poo [c+1] = c+2;
bab = poo[c];
return 0
}