summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Brolley <brolley@redhat.com>2009-04-02 12:38:15 -0400
committerDave Brolley <brolley@redhat.com>2009-04-02 12:38:15 -0400
commit2f53f831393d2f0db3d54260c2a7882eff17905c (patch)
treeba140bbad1fd4acaa7c2253949a2b2ade53952a2
parent2f54c4fe5a3aa21b4d5c38edabf83f3cdad0177d (diff)
parent15a78144473940a4e7c685cc57ba09a92f2293c6 (diff)
downloadsystemtap-steved-2f53f831393d2f0db3d54260c2a7882eff17905c.tar.gz
systemtap-steved-2f53f831393d2f0db3d54260c2a7882eff17905c.tar.xz
systemtap-steved-2f53f831393d2f0db3d54260c2a7882eff17905c.zip
Merge branch 'master' of git://sources.redhat.com/git/systemtap
Conflicts: configure
-rw-r--r--Makefile.in7
-rw-r--r--NEWS7
-rw-r--r--buildrun.cxx8
-rwxr-xr-xconfigure51
-rw-r--r--configure.ac3
-rw-r--r--doc/Makefile.in1
-rw-r--r--doc/SystemTap_Tapset_Reference/Makefile.in1
-rw-r--r--hash.cxx1
-rw-r--r--includes/sys/sdt.h48
-rw-r--r--main.cxx77
-rw-r--r--run-stap.in7
-rw-r--r--run-staprun.in13
-rw-r--r--runtime/loc2c-runtime.h6
-rw-r--r--runtime/runtime.h3
-rw-r--r--runtime/sym.c71
-rw-r--r--runtime/task_finder.c64
-rw-r--r--runtime/task_finder_vma.c110
-rw-r--r--tapset/context-symbols.stp7
-rw-r--r--tapset/context-unwind.stp3
-rw-r--r--tapset/i686/syscalls.stp2
-rw-r--r--tapsets.cxx174
-rwxr-xr-xtestsuite/buildok/twentysix.stp7
-rw-r--r--testsuite/lib/stap_run.exp1
-rw-r--r--testsuite/lib/systemtap.exp10
-rwxr-xr-xtestsuite/systemtap.base/bz5274.exp9
-rw-r--r--testsuite/systemtap.base/bz6850.exp9
-rw-r--r--testsuite/systemtap.base/itrace.exp42
-rw-r--r--testsuite/systemtap.base/labels.exp10
-rw-r--r--testsuite/systemtap.base/sdt.exp4
-rw-r--r--testsuite/systemtap.base/static_uprobes.exp12
-rw-r--r--testsuite/systemtap.base/uprobes.exp9
-rw-r--r--testsuite/systemtap.base/uprobes_lib.exp15
-rw-r--r--testsuite/systemtap.base/utrace_p4.exp34
-rw-r--r--testsuite/systemtap.base/utrace_p5.exp21
-rw-r--r--testsuite/systemtap.context/args.tcl2
-rw-r--r--testsuite/systemtap.context/backtrace.tcl2
-rw-r--r--testsuite/systemtap.context/context.exp1
-rw-r--r--testsuite/systemtap.context/num_args.tcl2
-rw-r--r--testsuite/systemtap.context/pid.tcl2
-rw-r--r--testsuite/systemtap.context/usymbols.c39
-rw-r--r--testsuite/systemtap.context/usymbols.exp83
-rw-r--r--testsuite/systemtap.context/usymbols_lib.c29
-rw-r--r--testsuite/systemtap.pass1-4/buildok.exp2
-rw-r--r--testsuite/systemtap.server/server.exp1
-rw-r--r--translate.cxx2
-rw-r--r--util.cxx41
-rw-r--r--util.h2
47 files changed, 689 insertions, 366 deletions
diff --git a/Makefile.in b/Makefile.in
index 495bed87..f14918ee 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -78,7 +78,7 @@ DIST_COMMON = INSTALL NEWS README AUTHORS $(srcdir)/Makefile.in \
$(top_srcdir)/man/stapprobes.tcp.3stap.in \
$(top_srcdir)/man/stapprobes.udp.3stap.in \
$(top_srcdir)/initscript/systemtap.in $(srcdir)/run-stap.in \
- depcomp $(oldinclude_HEADERS)
+ $(srcdir)/run-staprun.in depcomp $(oldinclude_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -95,7 +95,7 @@ CONFIG_CLEAN_FILES = stap.1 stapprobes.3stap stapfuncs.3stap \
man/stapprobes.rpc.3stap man/stapprobes.scsi.3stap \
man/stapprobes.signal.3stap man/stapprobes.socket.3stap \
man/stapprobes.tcp.3stap man/stapprobes.udp.3stap \
- initscript/systemtap run-stap
+ initscript/systemtap run-stap run-staprun
@BUILD_SERVER_TRUE@am__EXEEXT_1 = stap-client-connect$(EXEEXT) \
@BUILD_SERVER_TRUE@ stap-server-connect$(EXEEXT)
am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibexecdir)" \
@@ -238,6 +238,7 @@ PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
PIECFLAGS = @PIECFLAGS@
PIECXXFLAGS = @PIECXXFLAGS@
PIELDFLAGS = @PIELDFLAGS@
@@ -486,6 +487,8 @@ initscript/systemtap: $(top_builddir)/config.status $(top_srcdir)/initscript/sys
cd $(top_builddir) && $(SHELL) ./config.status $@
run-stap: $(top_builddir)/config.status $(srcdir)/run-stap.in
cd $(top_builddir) && $(SHELL) ./config.status $@
+run-staprun: $(top_builddir)/config.status $(srcdir)/run-staprun.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
diff --git a/NEWS b/NEWS
index ec204442..96e14b70 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,10 @@
+* What's new
+
+- The --skip-badvars option now also suppresses run-time error
+ messages that would otherwise result from erroneous memory accesses.
+ Such accesses can originate from $context expressions fueled by
+ erroneous debug data, or by kernel_{long,string,...}() tapset calls.
+
* What's new in version 0.9.5
- New probes process().insn and process().insn.block that allows
diff --git a/buildrun.cxx b/buildrun.cxx
index aafb8a6d..949f0859 100644
--- a/buildrun.cxx
+++ b/buildrun.cxx
@@ -59,7 +59,7 @@ run_make_cmd(systemtap_session& s, string& make_cmd)
make_cmd += " -s >/dev/null 2>&1";
if (s.verbose > 1) clog << "Running " << make_cmd << endl;
- rc = system (make_cmd.c_str());
+ rc = stap_system (make_cmd.c_str());
return rc;
}
@@ -234,7 +234,7 @@ kernel_built_uprobes (systemtap_session& s)
{
string grep_cmd = string ("/bin/grep -q unregister_uprobe ") +
s.kernel_build_tree + string ("/Module.symvers");
- int rc = system (grep_cmd.c_str());
+ int rc = stap_system (grep_cmd.c_str());
return (rc == 0);
}
@@ -285,7 +285,7 @@ copy_uprobes_symbols (systemtap_session& s)
string uprobes_home = s.runtime_path + "/uprobes";
string cp_cmd = string("/bin/cp ") + uprobes_home +
string("/Module.symvers ") + s.tmpdir;
- int rc = system (cp_cmd.c_str());
+ int rc = stap_system (cp_cmd.c_str());
return rc;
}
@@ -350,7 +350,7 @@ run_pass (systemtap_session& s)
if (s.verbose>1) clog << "Running " << staprun_cmd << endl;
- rc = system (staprun_cmd.c_str ());
+ rc = stap_system (staprun_cmd.c_str ());
return rc;
}
diff --git a/configure b/configure
index dd0d730c..a169b87f 100755
--- a/configure
+++ b/configure
@@ -706,6 +706,7 @@ EGREP
U
ANSI2KNR
RANLIB
+PERL
PIELDFLAGS
PIECFLAGS
PIECXXFLAGS
@@ -5824,6 +5825,47 @@ fi
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_PERL+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $PERL in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+PERL=$ac_cv_path_PERL
+if test -n "$PERL"; then
+ { echo "$as_me:$LINENO: result: $PERL" >&5
+echo "${ECHO_T}$PERL" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+
# Check whether --enable-perfmon was given.
if test "${enable_perfmon+set}" = set; then
enableval=$enable_perfmon;
@@ -7882,6 +7924,8 @@ subdirs="$subdirs testsuite"
ac_config_files="$ac_config_files run-stap"
+ac_config_files="$ac_config_files run-staprun"
+
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
@@ -8548,6 +8592,7 @@ do
"man/stapprobes.udp.3stap") CONFIG_FILES="$CONFIG_FILES man/stapprobes.udp.3stap" ;;
"initscript/systemtap") CONFIG_FILES="$CONFIG_FILES initscript/systemtap" ;;
"run-stap") CONFIG_FILES="$CONFIG_FILES run-stap" ;;
+ "run-staprun") CONFIG_FILES="$CONFIG_FILES run-staprun" ;;
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
@@ -8702,11 +8747,11 @@ EGREP!$EGREP$ac_delim
U!$U$ac_delim
ANSI2KNR!$ANSI2KNR$ac_delim
RANLIB!$RANLIB$ac_delim
+PERL!$PERL$ac_delim
PIELDFLAGS!$PIELDFLAGS$ac_delim
PIECFLAGS!$PIECFLAGS$ac_delim
PIECXXFLAGS!$PIECXXFLAGS$ac_delim
sqlite3_LIBS!$sqlite3_LIBS$ac_delim
-staplog_CPPFLAGS!$staplog_CPPFLAGS$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -8748,6 +8793,7 @@ _ACEOF
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
+staplog_CPPFLAGS!$staplog_CPPFLAGS$ac_delim
BUILD_CRASHMOD_TRUE!$BUILD_CRASHMOD_TRUE$ac_delim
BUILD_CRASHMOD_FALSE!$BUILD_CRASHMOD_FALSE$ac_delim
have_latex!$have_latex$ac_delim
@@ -8777,7 +8823,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 27; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 28; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
@@ -9344,6 +9390,7 @@ echo "$as_me: error: cannot create directory $as_dir" >&2;}
done
;;
"run-stap":F) chmod +x run-stap ;;
+ "run-staprun":F) chmod +x run-staprun ;;
esac
done # for ac_tag
diff --git a/configure.ac b/configure.ac
index 0c6a43d1..465d2dd7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,6 +25,8 @@ AC_PROG_MAKE_SET
AC_SUBST(CFLAGS)
AC_SUBST(CXXFLAGS)
+AC_PATH_PROG(PERL, perl)
+
dnl Handle the perfmon option.
AC_ARG_ENABLE([perfmon],
AS_HELP_STRING([--enable-perfmon@<:@=DIRECTORY@:>@],
@@ -362,6 +364,7 @@ AC_CONFIG_HEADERS([config.h:config.in])
AC_CONFIG_FILES(Makefile doc/Makefile doc/SystemTap_Tapset_Reference/Makefile stap.1 stapprobes.3stap stapfuncs.3stap stapvars.3stap stapex.3stap staprun.8 stap-server.8 man/stapprobes.iosched.3stap man/stapprobes.netdev.3stap man/stapprobes.nfs.3stap man/stapprobes.nfsd.3stap man/stapprobes.pagefault.3stap man/stapprobes.process.3stap man/stapprobes.rpc.3stap man/stapprobes.scsi.3stap man/stapprobes.signal.3stap man/stapprobes.socket.3stap man/stapprobes.tcp.3stap man/stapprobes.udp.3stap initscript/systemtap)
AC_CONFIG_SUBDIRS(testsuite)
AC_CONFIG_FILES([run-stap], [chmod +x run-stap])
+AC_CONFIG_FILES([run-staprun], [chmod +x run-staprun])
AC_OUTPUT
if test "${prefix}" = "/usr/local"; then
diff --git a/doc/Makefile.in b/doc/Makefile.in
index eafd7ca7..beb5553e 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -101,6 +101,7 @@ PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
PIECFLAGS = @PIECFLAGS@
PIECXXFLAGS = @PIECXXFLAGS@
PIELDFLAGS = @PIELDFLAGS@
diff --git a/doc/SystemTap_Tapset_Reference/Makefile.in b/doc/SystemTap_Tapset_Reference/Makefile.in
index 30ca4b17..d4bcf8b0 100644
--- a/doc/SystemTap_Tapset_Reference/Makefile.in
+++ b/doc/SystemTap_Tapset_Reference/Makefile.in
@@ -104,6 +104,7 @@ PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
PIECFLAGS = @PIECFLAGS@
PIECXXFLAGS = @PIECXXFLAGS@
PIELDFLAGS = @PIELDFLAGS@
diff --git a/hash.cxx b/hash.cxx
index 3ff6848d..01013c43 100644
--- a/hash.cxx
+++ b/hash.cxx
@@ -174,6 +174,7 @@ find_script_hash (systemtap_session& s, const string& script, const hash &base)
h.add(s.ignore_vmlinux); // --ignore-vmlinux
h.add(s.ignore_dwarf); // --ignore-dwarf
h.add(s.consult_symtab); // --kelf, --kmap
+ h.add(s.skip_badvars); // --skip-badvars
if (!s.kernel_symtab_path.empty()) // --kmap
{
h.add(s.kernel_symtab_path);
diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h
index ba75076b..c3fa16d9 100644
--- a/includes/sys/sdt.h
+++ b/includes/sys/sdt.h
@@ -39,6 +39,19 @@
#endif
#define STAP_LABEL(a,b) STAP_CONCAT(a,b)
+/* Taking the address of a local label and/or referencing alloca prevents the
+ containing function from being inlined, which keeps the parameters visible. */
+
+#if __GNUC__ == 4 && __GNUC_MINOR__ <= 1
+#include <alloca.h>
+#define STAP_UNINLINE alloca((size_t)0)
+#else
+#define STAP_UNINLINE
+#endif
+
+#define STAP_UNINLINE_LABEL(label) \
+ __extension__ static volatile long labelval __attribute__ ((unused)) = (long) &&label
+
#define STAP_PROBE_(probe) \
do { \
STAP_PROBE_DATA(probe); \
@@ -46,13 +59,11 @@ do { \
"\tnop"); \
} while (0)
-/* Taking the address of a local label prevents the containing function
- from being inlined, which keeps the parameters visible. */
-
#define STAP_PROBE1_(probe,label,parm1) \
do { \
- __extension__ static volatile long labelval __attribute__ ((unused)) = (long) &&label; \
+ STAP_UNINLINE_LABEL(label); \
volatile __typeof__((parm1)) arg1 = parm1; \
+ STAP_UNINLINE; \
STAP_PROBE_DATA(probe); \
label: \
__asm__ volatile ("2:\n" \
@@ -61,9 +72,10 @@ do { \
#define STAP_PROBE2_(probe,label,parm1,parm2) \
do { \
- __extension__ static volatile long labelval __attribute__ ((unused)) = (long) &&label; \
+ STAP_UNINLINE_LABEL(label); \
volatile __typeof__((parm1)) arg1 = parm1; \
volatile __typeof__((parm2)) arg2 = parm2; \
+ STAP_UNINLINE; \
STAP_PROBE_DATA(probe); \
label: \
__asm__ volatile ("2:\n" \
@@ -72,10 +84,11 @@ do { \
#define STAP_PROBE3_(probe,label,parm1,parm2,parm3) \
do { \
- __extension__ static volatile long labelval __attribute__ ((unused)) = (long) &&label; \
- volatile __typeof__((parm1)) arg1 = parm1; \
+ STAP_UNINLINE_LABEL(label); \
+ volatile __typeof__((parm1)) arg1 = parm1; \
volatile __typeof__((parm2)) arg2 = parm2; \
volatile __typeof__((parm3)) arg3 = parm3; \
+ STAP_UNINLINE; \
STAP_PROBE_DATA(probe); \
label: \
__asm__ volatile ("2:\n" \
@@ -84,11 +97,12 @@ do { \
#define STAP_PROBE4_(probe,label,parm1,parm2,parm3,parm4) \
do { \
- __extension__ static volatile long labelval __attribute__ ((unused)) = (long) &&label; \
+ STAP_UNINLINE_LABEL(label); \
volatile __typeof__((parm1)) arg1 = parm1; \
volatile __typeof__((parm2)) arg2 = parm2; \
volatile __typeof__((parm3)) arg3 = parm3; \
volatile __typeof__((parm4)) arg4 = parm4; \
+ STAP_UNINLINE; \
STAP_PROBE_DATA(probe); \
label: \
__asm__ volatile ("2:\n" \
@@ -97,12 +111,13 @@ do { \
#define STAP_PROBE5_(probe,label,parm1,parm2,parm3,parm4,parm5) \
do { \
- __extension__ static volatile long labelval __attribute__ ((unused)) = (long) &&label; \
+ STAP_UNINLINE_LABEL(label); \
volatile __typeof__((parm1)) arg1 = parm1; \
volatile __typeof__((parm2)) arg2 = parm2; \
volatile __typeof__((parm3)) arg3 = parm3; \
volatile __typeof__((parm4)) arg4 = parm4; \
volatile __typeof__((parm5)) arg5 = parm5; \
+ STAP_UNINLINE; \
STAP_PROBE_DATA(probe); \
label: \
__asm__ volatile ("2:\n" \
@@ -111,13 +126,14 @@ do { \
#define STAP_PROBE6_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6) \
do { \
- __extension__ static volatile long labelval __attribute__ ((unused)) = (long) &&label; \
+ STAP_UNINLINE_LABEL(label); \
volatile __typeof__((parm1)) arg1 = parm1; \
volatile __typeof__((parm2)) arg2 = parm2; \
volatile __typeof__((parm3)) arg3 = parm3; \
volatile __typeof__((parm4)) arg4 = parm4; \
volatile __typeof__((parm5)) arg5 = parm5; \
volatile __typeof__((parm6)) arg6 = parm6; \
+ STAP_UNINLINE; \
STAP_PROBE_DATA(probe); \
label: \
__asm__ volatile ("2:\n" \
@@ -126,7 +142,7 @@ do { \
#define STAP_PROBE7_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \
do { \
- __extension__ static volatile long labelval __attribute__ ((unused)) = (long) &&label; \
+ STAP_UNINLINE_LABEL(label); \
volatile __typeof__((parm1)) arg1 = parm1; \
volatile __typeof__((parm2)) arg2 = parm2; \
volatile __typeof__((parm3)) arg3 = parm3; \
@@ -134,6 +150,7 @@ do { \
volatile __typeof__((parm5)) arg5 = parm5; \
volatile __typeof__((parm6)) arg6 = parm6; \
volatile __typeof__((parm7)) arg7 = parm7; \
+ STAP_UNINLINE; \
STAP_PROBE_DATA(probe); \
label: \
__asm__ volatile ("2:\n" \
@@ -142,7 +159,7 @@ do { \
#define STAP_PROBE8_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \
do { \
- __extension__ static volatile long labelval __attribute__ ((unused)) = (long) &&label; \
+ STAP_UNINLINE_LABEL(label); \
volatile __typeof__((parm1)) arg1 = parm1; \
volatile __typeof__((parm2)) arg2 = parm2; \
volatile __typeof__((parm3)) arg3 = parm3; \
@@ -151,6 +168,7 @@ do { \
volatile __typeof__((parm6)) arg6 = parm6; \
volatile __typeof__((parm7)) arg7 = parm7; \
volatile __typeof__((parm8)) arg8 = parm8; \
+ STAP_UNINLINE; \
STAP_PROBE_DATA(probe); \
label: \
__asm__ volatile ("2:\n" \
@@ -159,7 +177,7 @@ do { \
#define STAP_PROBE9_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \
do { \
- __extension__ static volatile long labelval __attribute__ ((unused)) = (long) &&label; \
+ STAP_UNINLINE_LABEL(label); \
volatile __typeof__((parm1)) arg1 = parm1; \
volatile __typeof__((parm2)) arg2 = parm2; \
volatile __typeof__((parm3)) arg3 = parm3; \
@@ -169,6 +187,7 @@ do { \
volatile __typeof__((parm7)) arg7 = parm7; \
volatile __typeof__((parm8)) arg8 = parm8; \
volatile __typeof__((parm9)) arg9 = parm9; \
+ STAP_UNINLINE; \
STAP_PROBE_DATA(probe); \
label: \
__asm__ volatile ("2:\n" \
@@ -177,7 +196,7 @@ do { \
#define STAP_PROBE10_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \
do { \
- __extension__ static volatile long labelval __attribute__ ((unused)) = (long) &&label; \
+ STAP_UNINLINE_LABEL(label); \
volatile __typeof__((parm1)) arg1 = parm1; \
volatile __typeof__((parm2)) arg2 = parm2; \
volatile __typeof__((parm3)) arg3 = parm3; \
@@ -188,6 +207,7 @@ do { \
volatile __typeof__((parm8)) arg8 = parm8; \
volatile __typeof__((parm9)) arg9 = parm9; \
volatile __typeof__((parm10)) arg10 = parm10; \
+ STAP_UNINLINE; \
STAP_PROBE_DATA(probe); \
label: \
__asm__ volatile ("2:\n" \
diff --git a/main.cxx b/main.cxx
index cde85226..c9f855c8 100644
--- a/main.cxx
+++ b/main.cxx
@@ -36,8 +36,6 @@ extern "C" {
#include <sys/times.h>
#include <sys/time.h>
#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
#include <time.h>
#include <elfutils/libdwfl.h>
#include <getopt.h>
@@ -297,14 +295,9 @@ int pending_interrupts;
extern "C"
void handle_interrupt (int sig)
{
- if (pending_interrupts == 0)
- kill (0, sig); // Forward signals to child processes if any.
-
+ kill_stap_spawn(sig);
pending_interrupts ++;
- // NB: the "2" below is intended to skip the effect of the self-induced
- // deferred signal coming from the kill() above.
-
- if (pending_interrupts > 2) // XXX: should be configurable? time-based?
+ if (pending_interrupts > 1) // XXX: should be configurable? time-based?
{
char msg[] = "Too many interrupts received, exiting.\n";
int rc = write (2, msg, sizeof(msg)-1);
@@ -328,7 +321,7 @@ setup_signals (sighandler_t handler)
sigaddset (&sa.sa_mask, SIGINT);
sigaddset (&sa.sa_mask, SIGTERM);
}
- sa.sa_flags = 0;
+ sa.sa_flags = SA_RESTART;
sigaction (SIGHUP, &sa, NULL);
sigaction (SIGPIPE, &sa, NULL);
@@ -336,62 +329,10 @@ setup_signals (sighandler_t handler)
sigaction (SIGTERM, &sa, NULL);
}
-pid_t runner_pid;
-int runner (int, char * const []);
-
-// Passes on signals to runner process.
-// In practise passes signal to runner process process group,
-// since run_pass() uses system() to spawn child processes,
-// which makes the process ignore SIGINT during the command run.
-extern "C"
-void waiter_handler (int sig)
-{
- // Process group is negative process id.
- kill (-1 * runner_pid, sig);
-}
-
-// Just sits there till the runner exits and then exits the same way.
-void waiter()
-{
- int status;
- setup_signals (&waiter_handler);
- while (waitpid (runner_pid, &status, 0) != runner_pid);
-
- // Exit as our runner child exitted.
- if (WIFEXITED(status))
- exit (WEXITSTATUS(status));
-
- // Or simulate as if we were killed by the same signal.
- if (WIFSIGNALED(status))
- {
- int sig = WTERMSIG(status);
- signal (sig, SIG_DFL);
- raise (sig);
- }
-
- // Should not happen, exit as if error.
- exit(-1);
-}
int
main (int argc, char * const argv [])
{
- // Fork to make sure runner gets its own process group, while
- // the waiter sits in the original process group of the shell
- // and forwards any signals.
- runner_pid = fork ();
- if (runner_pid == 0)
- return runner (argc, argv);
- if (runner_pid > 0)
- waiter ();
-
- perror ("couldn't fork");
- exit (-1);
-}
-
-int
-runner (int argc, char * const argv [])
-{
string cmdline_script; // -e PROGRAM
string script_file; // FILE
bool have_script = false;
@@ -943,16 +884,6 @@ runner (int argc, char * const argv [])
// directory.
s.translated_source = string(s.tmpdir) + "/" + s.module_name + ".c";
- // We want a new process group so we can use kill (0, sig) to send a
- // signal to all children (but not the parent). As done in
- // handle_interrupt ().
- if (setpgrp() != 0)
- {
- const char* e = strerror (errno);
- if (! s.suppress_warnings)
- cerr << "Warning: failed to set new process group: " << e << endl;
- }
-
// Set up our handler to catch routine signals, to allow clean
// and reasonably timely exit.
setup_signals(&handle_interrupt);
@@ -1311,7 +1242,7 @@ pass_5:
string cleanupcmd = "rm -rf ";
cleanupcmd += s.tmpdir;
if (s.verbose>1) clog << "Running " << cleanupcmd << endl;
- int status = system (cleanupcmd.c_str());
+ int status = stap_system (cleanupcmd.c_str());
if (status != 0 && s.verbose>1)
clog << "Cleanup command failed, status: " << status << endl;
}
diff --git a/run-stap.in b/run-stap.in
index dfb53ab2..1bfb6a77 100644
--- a/run-stap.in
+++ b/run-stap.in
@@ -19,11 +19,8 @@ esac
# Set all the variables to find the source and build trees.
SYSTEMTAP_TAPSET="${srcdir}/tapset"
SYSTEMTAP_RUNTIME="${srcdir}/runtime"
-SYSTEMTAP_STAPIO="${builddir}/stapio"
-SYSTEMTAP_STAPRUN="sudo 'SYSTEMTAP_STAPIO=$SYSTEMTAP_STAPIO' \
- 'SYSTEMTAP_STAPRUN=${builddir}/staprun' \
- ${builddir}/staprun"
-export SYSTEMTAP_TAPSET SYSTEMTAP_RUNTIME SYSTEMTAP_STAPRUN SYSTEMTAP_STAPIO
+SYSTEMTAP_STAPRUN="sudo -P builddir='${builddir}' ${builddir}/run-staprun"
+export SYSTEMTAP_TAPSET SYSTEMTAP_RUNTIME SYSTEMTAP_STAPRUN
# If there were private elfutils libs built, use them.
if [ -d "$rundir/lib-elfutils" ]; then
diff --git a/run-staprun.in b/run-staprun.in
new file mode 100644
index 00000000..0b5f795b
--- /dev/null
+++ b/run-staprun.in
@@ -0,0 +1,13 @@
+#!@PERL@ -w
+
+# Reset real IDs to those we had before we were sudo-invoked.
+# This gives staprun the IDs it expects from a setuid exec.
+$< = $ENV{'SUDO_UID'};
+$( = $ENV{'SUDO_GID'};
+
+$ENV{'SYSTEMTAP_STAPRUN'} = "sudo '$ENV{'builddir'}/staprun'";
+$ENV{'SYSTEMTAP_STAPIO'} = "$ENV{'builddir'}/stapio";
+
+exec { "$ENV{'builddir'}/staprun" } ('staprun', @ARGV);
+
+exit;
diff --git a/runtime/loc2c-runtime.h b/runtime/loc2c-runtime.h
index 16ddb950..eaf47cad 100644
--- a/runtime/loc2c-runtime.h
+++ b/runtime/loc2c-runtime.h
@@ -62,6 +62,10 @@
must work right for kernel addresses, and can use whatever existing
machine-specific kernel macros are convenient. */
+#if STP_SKIP_BADVARS
+#define DEREF_FAULT(addr) ({0; })
+#define STORE_DEREF_FAULT(addr) ({0; })
+#else
#define DEREF_FAULT(addr) ({ \
snprintf(c->error_buffer, sizeof(c->error_buffer), \
"kernel read fault at 0x%p (%s)", (void *)(intptr_t)(addr), #addr); \
@@ -75,7 +79,7 @@
c->last_error = c->error_buffer; \
goto deref_fault; \
})
-
+#endif
#if defined (STAPCONF_X86_UNIREGS) && defined (__i386__)
diff --git a/runtime/runtime.h b/runtime/runtime.h
index fc5d454f..822562a2 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -86,6 +86,9 @@ static struct
#include "io.c"
#include "arith.c"
#include "copy.c"
+
+#include "task_finder.c"
+
#include "sym.c"
#ifdef STP_PERFMON
#include "perf.c"
diff --git a/runtime/sym.c b/runtime/sym.c
index 1d88a862..d0c5d9fd 100644
--- a/runtime/sym.c
+++ b/runtime/sym.c
@@ -20,6 +20,40 @@
* @{
*/
+/* Callback that needs to be registered (in tapsets.cxx for
+ emit_module_init) for every user task path or pid for which we
+ might need symbols or unwind info. */
+static int _stp_tf_vm_cb(struct stap_task_finder_target *tgt,
+ struct task_struct *tsk,
+ int map_p, char *vm_path,
+ unsigned long vm_start, unsigned long vm_end,
+ unsigned long vm_pgoff)
+{
+ int i;
+#ifdef DEBUG_TASK_FINDER_VMA
+ _stp_dbug(__FUNCTION__, __LINE__, "vm_cb: tsk %d:%d path %s, start 0x%08lx, end 0x%08lx, offset 0x%lx\n", tsk->pid, map_p, vm_path, vm_start, vm_end, vm_pgoff);
+#endif
+ if (map_p)
+ {
+ struct _stp_module *module = NULL;
+ if (vm_path != NULL)
+ for (i = 0; i < _stp_num_modules; i++)
+ if (strcmp(vm_path, _stp_modules[i]->path) == 0)
+ {
+#ifdef DEBUG_TASK_FINDER_VMA
+ _stp_dbug(__FUNCTION__, __LINE__, "vm_cb: matched path %s to module\n", vm_path);
+#endif
+ module = _stp_modules[i];
+ break;
+ }
+ stap_add_vma_map_info(tsk, vm_start, vm_end, vm_pgoff, module);
+ }
+ else
+ stap_remove_vma_map_info(tsk, vm_start, vm_end, vm_pgoff);
+
+ return 0;
+}
+
/* XXX: this needs to be address-space-specific. */
static unsigned long _stp_module_relocate(const char *module, const char *section, unsigned long offset)
{
@@ -76,11 +110,33 @@ static unsigned long _stp_module_relocate(const char *module, const char *sectio
if found, return NULL otherwise.
XXX: needs to be address-space-specific. */
static struct _stp_module *_stp_mod_sec_lookup(unsigned long addr,
+ struct task_struct *task,
struct _stp_section **sec)
{
+ void *user = NULL;
struct _stp_module *m = NULL;
unsigned midx = 0;
unsigned long closest_section_offset = ~0;
+
+ // Try vma matching first if task given.
+ if (task)
+ {
+ unsigned long vm_start = 0;
+ if (stap_find_vma_map_info(task, addr,
+ &vm_start, NULL,
+ NULL, &user) == 0)
+ if (user != NULL)
+ {
+ m = (struct _stp_module *)user;
+ *sec = &m->sections[0]; // XXX check actual section and relocate
+ dbug_sym(1, "found section %s in module %s at 0x%lx\n",
+ m->sections[0].name, m->name, vm_start);
+ if (strcmp(".dynamic", m->sections[0].name) == 0)
+ m->sections[0].addr = vm_start; // cheat...
+ return m;
+ }
+ }
+
for (midx = 0; midx < _stp_num_modules; midx++)
{
unsigned secidx;
@@ -108,14 +164,15 @@ static const char *_stp_kallsyms_lookup(unsigned long addr, unsigned long *symbo
unsigned long *offset,
const char **modname,
/* char ** secname? */
- char *namebuf)
+ char *namebuf,
+ struct task_struct *task)
{
struct _stp_module *m = NULL;
struct _stp_section *sec = NULL;
struct _stp_symbol *s = NULL;
unsigned end, begin = 0;
- m = _stp_mod_sec_lookup(addr, &sec);
+ m = _stp_mod_sec_lookup(addr, task, &sec);
if (unlikely (m == NULL || sec == NULL))
return NULL;
@@ -240,7 +297,7 @@ static void _stp_symbol_print(unsigned long address)
const char *name;
unsigned long offset, size;
- name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL);
+ name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL, NULL);
_stp_printf("%p", (int64_t) address);
@@ -265,7 +322,7 @@ static int _stp_func_print(unsigned long address, int verbose, int exact)
else
exstr = " (inexact)";
- name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL);
+ name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL, NULL);
if (name) {
if (verbose) {
@@ -281,13 +338,15 @@ static int _stp_func_print(unsigned long address, int verbose, int exact)
return 0;
}
-static void _stp_symbol_snprint(char *str, size_t len, unsigned long address)
+static void _stp_symbol_snprint(char *str, size_t len, unsigned long address,
+ struct task_struct *task)
{
const char *modname;
const char *name;
unsigned long offset, size;
- name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL);
+ name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL,
+ task);
if (name)
strlcpy(str, name, len);
else
diff --git a/runtime/task_finder.c b/runtime/task_finder.c
index 7949a81f..3507c669 100644
--- a/runtime/task_finder.c
+++ b/runtime/task_finder.c
@@ -2,8 +2,32 @@
#define TASK_FINDER_C
#if ! defined(CONFIG_UTRACE)
-#error "Need CONFIG_UTRACE!"
-#endif
+/* Dummy definitions for use in sym.c */
+struct stap_task_finder_target { };
+
+static int
+stap_add_vma_map_info(struct task_struct *tsk, unsigned long vm_start,
+ unsigned long vm_end, unsigned long vm_pgoff,
+ void *user)
+{
+ return 0;
+}
+
+static int
+stap_remove_vma_map_info(struct task_struct *tsk, unsigned long vm_start,
+ unsigned long vm_end, unsigned long vm_pgoff)
+{
+ return 0;
+}
+
+static int
+stap_find_vma_map_info(struct task_struct *tsk, unsigned long vm_addr,
+ unsigned long *vm_start, unsigned long *vm_end,
+ unsigned long *vm_pgoff, void **user)
+{
+ return ESRCH;
+}
+#else
#include <linux/utrace.h>
@@ -69,40 +93,6 @@ typedef int (*stap_task_finder_vm_callback)(struct stap_task_finder_target *tgt,
unsigned long vm_end,
unsigned long vm_pgoff);
-static int __stp_tf_vm_cb(struct stap_task_finder_target *tgt,
- struct task_struct *tsk,
- int map_p, char *vm_path,
- unsigned long vm_start,
- unsigned long vm_end,
- unsigned long vm_pgoff)
-{
- int i;
-#ifdef DEBUG_TASK_FINDER_VMA
- _stp_dbug(__FUNCTION__, __LINE__,
- "vm_cb: tsk %d:%d path %s, start 0x%08lx, end 0x%08lx, offset 0x%lx\n",
- tsk->pid, map_p, vm_path, vm_start, vm_end, vm_pgoff);
-#endif
- if (map_p) {
- struct _stp_module *module = NULL;
- if (vm_path != NULL)
- for (i = 0; i < _stp_num_modules; i++)
- if (strcmp(vm_path, _stp_modules[i]->path) == 0)
- {
-#ifdef DEBUG_TASK_FINDER_VMA
- _stp_dbug(__FUNCTION__, __LINE__,
- "vm_cb: matched path %s to module\n", vm_path);
-#endif
- module = _stp_modules[i];
- break;
- }
- stap_add_vma_map_info(tsk, vm_start, vm_end, vm_pgoff, module);
- }
- else {
- stap_remove_vma_map_info(tsk, vm_start, vm_end, vm_pgoff);
- }
- return 0;
-}
-
struct stap_task_finder_target {
/* private: */
struct list_head list; /* __stp_task_finder_list linkage */
@@ -1392,4 +1382,6 @@ stap_stop_task_finder(void)
}
+#endif /* defined(CONFIG_UTRACE) */
+
#endif /* TASK_FINDER_C */
diff --git a/runtime/task_finder_vma.c b/runtime/task_finder_vma.c
index 83b206e5..ed9c6f4f 100644
--- a/runtime/task_finder_vma.c
+++ b/runtime/task_finder_vma.c
@@ -1,13 +1,19 @@
#include <linux/list.h>
#include <linux/jhash.h>
-#include <linux/mutex.h>
+#include <linux/spinlock.h>
// When handling memcpy() syscall tracing to notice memory map
// changes, we need to cache memcpy() entry parameter values for
// processing at memcpy() exit.
-// __stp_tf_vma_mutex protects the hash table.
-static DEFINE_MUTEX(__stp_tf_vma_mutex);
+// __stp_tf_vma_lock protects the hash table.
+// Documentation/spinlocks.txt suggest we can be a bit more clever
+// if we guarantee that in interrupt context we only read, not write
+// the datastructures. We should never change the hash table or the
+// contents in interrupt context (which should only ever call
+// stap_find_vma_map_info for getting stored vma info). So we might
+// want to look into that if this seems a bottleneck.
+static DEFINE_RWLOCK(__stp_tf_vma_lock);
#define __STP_TF_HASH_BITS 4
#define __STP_TF_TABLE_SIZE (1 << __STP_TF_HASH_BITS)
@@ -26,8 +32,8 @@ struct __stp_tf_vma_entry {
unsigned long vm_pgoff;
// Is that enough? Should we store a dcookie for vm_file?
- // Module that this vma entry is mapped from, if any.
- struct _stp_module *module;
+ // User data (possibly stp_module)
+ void *user;
};
static struct __stp_tf_vma_entry
@@ -40,23 +46,24 @@ static struct hlist_head __stp_tf_vma_table[__STP_TF_TABLE_SIZE];
static struct hlist_head __stp_tf_vma_map[__STP_TF_TABLE_SIZE];
// __stp_tf_vma_initialize(): Initialize the free list. Grabs the
-// mutex.
+// spinlock.
static void
__stp_tf_vma_initialize(void)
{
int i;
struct hlist_head *head = &__stp_tf_vma_free_list[0];
- mutex_lock(&__stp_tf_vma_mutex);
+ unsigned long flags;
+ write_lock_irqsave(&__stp_tf_vma_lock, flags);
for (i = 0; i < TASK_FINDER_VMA_ENTRY_ITEMS; i++) {
hlist_add_head(&__stp_tf_vma_free_list_items[i].hlist, head);
}
- mutex_unlock(&__stp_tf_vma_mutex);
+ write_unlock_irqrestore(&__stp_tf_vma_lock, flags);
}
// __stp_tf_vma_get_free_entry(): Returns an entry from the free list
-// or NULL. The __stp_tf_vma_mutex must be locked before calling this
+// or NULL. The __stp_tf_vma_lock must be write locked before calling this
// function.
static struct __stp_tf_vma_entry *
__stp_tf_vma_get_free_entry(void)
@@ -77,7 +84,7 @@ __stp_tf_vma_get_free_entry(void)
// __stp_tf_vma_put_free_entry(): Puts an entry back on the free
-// list. The __stp_tf_vma_mutex must be locked before calling this
+// list. The __stp_tf_vma_lock must be write locked before calling this
// function.
static void
__stp_tf_vma_put_free_entry(struct __stp_tf_vma_entry *entry)
@@ -101,7 +108,7 @@ __stp_tf_vma_hash(struct task_struct *tsk, unsigned long addr)
// Get vma_entry if the vma is present in the vma hash table.
-// Returns NULL if not present.
+// Returns NULL if not present. Takes a read lock on __stp_tf_vma_lock.
static struct __stp_tf_vma_entry *
__stp_tf_get_vma_entry(struct task_struct *tsk, unsigned long addr)
{
@@ -109,20 +116,22 @@ __stp_tf_get_vma_entry(struct task_struct *tsk, unsigned long addr)
struct hlist_node *node;
struct __stp_tf_vma_entry *entry;
- mutex_lock(&__stp_tf_vma_mutex);
+ unsigned long flags;
+ read_lock_irqsave(&__stp_tf_vma_lock, flags);
head = &__stp_tf_vma_table[__stp_tf_vma_hash(tsk, addr)];
hlist_for_each_entry(entry, node, head, hlist) {
if (tsk->pid == entry->pid
&& addr == entry->addr) {
- mutex_unlock(&__stp_tf_vma_mutex);
+ read_unlock_irqrestore(&__stp_tf_vma_lock, flags);
return entry;
}
}
- mutex_unlock(&__stp_tf_vma_mutex);
+ read_unlock_irqrestore(&__stp_tf_vma_lock, flags);
return NULL;
}
// Add the vma info to the vma hash table.
+// Takes a write lock on __stp_tf_vma_lock.
static int
__stp_tf_add_vma(struct task_struct *tsk, unsigned long addr,
struct vm_area_struct *vma)
@@ -131,7 +140,8 @@ __stp_tf_add_vma(struct task_struct *tsk, unsigned long addr,
struct hlist_node *node;
struct __stp_tf_vma_entry *entry;
- mutex_lock(&__stp_tf_vma_mutex);
+ unsigned long flags;
+ write_lock_irqsave(&__stp_tf_vma_lock, flags);
head = &__stp_tf_vma_table[__stp_tf_vma_hash(tsk, addr)];
hlist_for_each_entry(entry, node, head, hlist) {
if (tsk->pid == entry->pid
@@ -141,7 +151,7 @@ __stp_tf_add_vma(struct task_struct *tsk, unsigned long addr,
"vma (pid: %d, vm_start: 0x%lx) present?\n",
tsk->pid, vma->vm_start);
#endif
- mutex_unlock(&__stp_tf_vma_mutex);
+ write_unlock_irqrestore(&__stp_tf_vma_lock, flags);
return -EBUSY; /* Already there */
}
}
@@ -149,7 +159,7 @@ __stp_tf_add_vma(struct task_struct *tsk, unsigned long addr,
// Get an element from the free list.
entry = __stp_tf_vma_get_free_entry();
if (!entry) {
- mutex_unlock(&__stp_tf_vma_mutex);
+ write_unlock_irqrestore(&__stp_tf_vma_lock, flags);
return -ENOMEM;
}
entry->pid = tsk->pid;
@@ -158,11 +168,12 @@ __stp_tf_add_vma(struct task_struct *tsk, unsigned long addr,
entry->vm_end = vma->vm_end;
entry->vm_pgoff = vma->vm_pgoff;
hlist_add_head(&entry->hlist, head);
- mutex_unlock(&__stp_tf_vma_mutex);
+ write_unlock_irqrestore(&__stp_tf_vma_lock, flags);
return 0;
}
// Remove the vma entry from the vma hash table.
+// Takes a write lock on __stp_tf_vma_lock.
static int
__stp_tf_remove_vma_entry(struct __stp_tf_vma_entry *entry)
{
@@ -171,10 +182,11 @@ __stp_tf_remove_vma_entry(struct __stp_tf_vma_entry *entry)
int found = 0;
if (entry != NULL) {
- mutex_lock(&__stp_tf_vma_mutex);
+ unsigned long flags;
+ write_lock_irqsave(&__stp_tf_vma_lock, flags);
hlist_del(&entry->hlist);
__stp_tf_vma_put_free_entry(entry);
- mutex_unlock(&__stp_tf_vma_mutex);
+ write_unlock_irqrestore(&__stp_tf_vma_lock, flags);
}
return 0;
}
@@ -189,7 +201,7 @@ __stp_tf_vma_map_hash(struct task_struct *tsk)
}
// Get vma_entry if the vma is present in the vma map hash table.
-// Returns NULL if not present. The __stp_tf_vma_mutex must be locked
+// Returns NULL if not present. The __stp_tf_vma_lock must be read locked
// before calling this function.
static struct __stp_tf_vma_entry *
__stp_tf_get_vma_map_entry_internal(struct task_struct *tsk,
@@ -214,13 +226,16 @@ __stp_tf_get_vma_map_entry_internal(struct task_struct *tsk,
static int
stap_add_vma_map_info(struct task_struct *tsk, unsigned long vm_start,
unsigned long vm_end, unsigned long vm_pgoff,
- struct _stp_module *module)
+ void *user)
{
struct hlist_head *head;
struct hlist_node *node;
struct __stp_tf_vma_entry *entry;
- mutex_lock(&__stp_tf_vma_mutex);
+ unsigned long flags;
+ // Take a write lock, since we are most likely going to write
+ // after reading.
+ write_lock_irqsave(&__stp_tf_vma_lock, flags);
entry = __stp_tf_get_vma_map_entry_internal(tsk, vm_start);
if (entry != NULL) {
#if 0
@@ -228,14 +243,14 @@ stap_add_vma_map_info(struct task_struct *tsk, unsigned long vm_start,
"vma (pid: %d, vm_start: 0x%lx) present?\n",
tsk->pid, entry->vm_start);
#endif
- mutex_unlock(&__stp_tf_vma_mutex);
+ write_unlock_irqrestore(&__stp_tf_vma_lock, flags);
return -EBUSY; /* Already there */
}
// Get an element from the free list.
entry = __stp_tf_vma_get_free_entry();
if (!entry) {
- mutex_unlock(&__stp_tf_vma_mutex);
+ write_unlock_irqrestore(&__stp_tf_vma_lock, flags);
return -ENOMEM;
}
@@ -245,11 +260,11 @@ stap_add_vma_map_info(struct task_struct *tsk, unsigned long vm_start,
entry->vm_start = vm_start;
entry->vm_end = vm_end;
entry->vm_pgoff = vm_pgoff;
- entry->module = module;
+ entry->user = user;
head = &__stp_tf_vma_map[__stp_tf_vma_map_hash(tsk)];
hlist_add_head(&entry->hlist, head);
- mutex_unlock(&__stp_tf_vma_mutex);
+ write_unlock_irqrestore(&__stp_tf_vma_lock, flags);
return 0;
}
@@ -263,23 +278,26 @@ stap_remove_vma_map_info(struct task_struct *tsk, unsigned long vm_start,
struct hlist_node *node;
struct __stp_tf_vma_entry *entry;
- mutex_lock(&__stp_tf_vma_mutex);
+ // Take a write lock since we are most likely going to delete
+ // after reading.
+ unsigned long flags;
+ write_lock_irqsave(&__stp_tf_vma_lock, flags);
entry = __stp_tf_get_vma_map_entry_internal(tsk, vm_start);
if (entry != NULL) {
hlist_del(&entry->hlist);
__stp_tf_vma_put_free_entry(entry);
}
- mutex_unlock(&__stp_tf_vma_mutex);
+ write_unlock_irqrestore(&__stp_tf_vma_lock, flags);
return 0;
}
// Finds vma info if the vma is present in the vma map hash table.
-// Returns ESRCH if not present. The __stp_tf_vma_mutex must *not* be
+// Returns ESRCH if not present. The __stp_tf_vma_lock must *not* be
// locked before calling this function.
static int
stap_find_vma_map_info(struct task_struct *tsk, unsigned long vm_addr,
unsigned long *vm_start, unsigned long *vm_end,
- unsigned long *vm_pgoff)
+ unsigned long *vm_pgoff, void **user)
{
struct hlist_head *head;
struct hlist_node *node;
@@ -287,7 +305,8 @@ stap_find_vma_map_info(struct task_struct *tsk, unsigned long vm_addr,
struct __stp_tf_vma_entry *found_entry = NULL;
int rc = ESRCH;
- mutex_lock(&__stp_tf_vma_mutex);
+ unsigned long flags;
+ read_lock_irqsave(&__stp_tf_vma_lock, flags);
head = &__stp_tf_vma_map[__stp_tf_vma_map_hash(tsk)];
hlist_for_each_entry(entry, node, head, hlist) {
if (tsk->pid == entry->pid
@@ -304,31 +323,10 @@ stap_find_vma_map_info(struct task_struct *tsk, unsigned long vm_addr,
*vm_end = found_entry->vm_end;
if (vm_pgoff != NULL)
*vm_pgoff = found_entry->vm_pgoff;
+ if (user != NULL)
+ *user = found_entry->user;
rc = 0;
}
- mutex_unlock(&__stp_tf_vma_mutex);
+ read_unlock_irqrestore(&__stp_tf_vma_lock, flags);
return rc;
}
-
-// Get vma_entry of the address (vm_start/vm_end) if the vma is
-// present in the vma hash table containing.
-// Returns NULL if not present.
-static struct __stp_tf_vma_entry *
-__stp_tf_get_vma_entry_addr(struct task_struct *tsk, unsigned long addr)
-{
- struct hlist_head *head;
- struct hlist_node *node;
- struct __stp_tf_vma_entry *entry;
-
- mutex_lock(&__stp_tf_vma_mutex);
- head = &__stp_tf_vma_map[__stp_tf_vma_map_hash(tsk)];
- hlist_for_each_entry(entry, node, head, hlist) {
- if (tsk->pid == entry->pid
- && addr >= entry->vm_start && addr < entry->vm_end) {
- mutex_unlock(&__stp_tf_vma_mutex);
- return entry;
- }
- }
- mutex_unlock(&__stp_tf_vma_mutex);
- return NULL;
-}
diff --git a/tapset/context-symbols.stp b/tapset/context-symbols.stp
index a3aae408..4c200aa8 100644
--- a/tapset/context-symbols.stp
+++ b/tapset/context-symbols.stp
@@ -66,7 +66,7 @@ function probefunc:string () %{ /* pure */
#else
((unsigned long)REG_IP(CONTEXT->regs) >= (unsigned long)PAGE_OFFSET)) {
#endif
- _stp_symbol_snprint(THIS->__retvalue, MAXSTRINGLEN, REG_IP(CONTEXT->regs));
+ _stp_symbol_snprint(THIS->__retvalue, MAXSTRINGLEN, REG_IP(CONTEXT->regs), current);
if (THIS->__retvalue[0] == '.') /* powerpc symbol has a dot*/
strlcpy(THIS->__retvalue,THIS->__retvalue + 1,MAXSTRINGLEN);
} else {
@@ -94,3 +94,8 @@ function probemod:string () %{ /* pure */
THIS->__retvalue[0] = '\0';
}
%}
+
+function symbolname:string (addr:long) %{ /* pure */
+ _stp_symbol_snprint(THIS->__retvalue, MAXSTRINGLEN, THIS->addr,
+ current);
+%}
diff --git a/tapset/context-unwind.stp b/tapset/context-unwind.stp
index 90d4e0f4..a976f8b6 100644
--- a/tapset/context-unwind.stp
+++ b/tapset/context-unwind.stp
@@ -56,7 +56,8 @@ function backtrace:string () %{ /* pure */
function caller:string() %{ /* pure */
if (CONTEXT->pi)
_stp_symbol_snprint( THIS->__retvalue, MAXSTRINGLEN,
- (unsigned long)_stp_ret_addr_r(CONTEXT->pi));
+ (unsigned long)_stp_ret_addr_r(CONTEXT->pi),
+ current);
else
strlcpy(THIS->__retvalue,"unknown",MAXSTRINGLEN);
%}
diff --git a/tapset/i686/syscalls.stp b/tapset/i686/syscalls.stp
index 8e69f622..2a89c19d 100644
--- a/tapset/i686/syscalls.stp
+++ b/tapset/i686/syscalls.stp
@@ -119,7 +119,7 @@ probe syscall.set_zone_reclaim.return =
#
probe syscall.sigaltstack = kernel.function("sys_sigaltstack") {
name = "sigaltstack"
- ussp = %( kernel_vr < "2.6.25" %? $ebx %: $bx %)
+ ussp = %( kernel_vr < "2.6.25" %? $ebx %: %( kernel_vr < "2.6.29" %? $bx %: $regs->bx %) %)
argstr = sprintf("%p", ussp)
}
probe syscall.sigaltstack.return = kernel.function("sys_sigaltstack").return {
diff --git a/tapsets.cxx b/tapsets.cxx
index 50ee563a..1b55684b 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -5812,7 +5812,8 @@ dwarf_builder::build(systemtap_session & sess,
&& dw->function_name_matches_pattern
(probe_name.c_str(),
location->components[1]->arg->tok->content.c_str())))
- ;
+ {
+ }
else
continue;
const token* sv_tok = location->components[1]->arg->tok;
@@ -5833,7 +5834,7 @@ dwarf_builder::build(systemtap_session & sess,
return;
}
- if (probe_type == dwarf_no_probes)
+ else if (probe_type == dwarf_no_probes)
{
location->components[1]->functor = TOK_FUNCTION;
location->components[1]->arg = new literal_string("*");
@@ -6229,6 +6230,27 @@ module_info::~module_info()
delete sym_table;
}
+// Helper function to emit vma tracker callback _stp_tf_vm_cb.
+static void
+emit_vma_callback_probe_decl (systemtap_session& s,
+ string path,
+ int64_t pid)
+{
+ s.op->newline() << "{";
+ if (pid == 0)
+ {
+ s.op->line() << " .pathname=\"" << path << "\",";
+ s.op->line() << " .pid=0,";
+ }
+ else
+ {
+ s.op->line() << " .pathname=NULL,";
+ s.op->line() << " .pid=" << pid << ",";
+ }
+ s.op->line() << " .callback=NULL,";
+ s.op->line() << " .vm_callback=&_stp_tf_vm_cb,";
+ s.op->line() << " },";
+}
// ------------------------------------------------------------------------
@@ -6432,7 +6454,6 @@ itrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline();
s.op->newline() << "/* ---- itrace probes ---- */";
- s.op->newline() << "#include \"task_finder.c\"";
s.op->newline() << "struct stap_itrace_probe {";
s.op->indent(1);
s.op->newline() << "struct stap_task_finder_target tgt;";
@@ -6474,6 +6495,25 @@ itrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline(-1) << "return rc;";
s.op->newline(-1) << "}";
+ // Emit vma callbacks.
+ s.op->newline() << "#ifdef STP_NEED_VMA_TRACKER";
+ s.op->newline() << "static struct stap_task_finder_target stap_itrace_vmcbs[] = {";
+ s.op->indent(1);
+ if (! probes_by_path.empty())
+ {
+ for (p_b_path_iterator it = probes_by_path.begin();
+ it != probes_by_path.end(); it++)
+ emit_vma_callback_probe_decl (s, it->first, (int64_t)0);
+ }
+ if (! probes_by_pid.empty())
+ {
+ for (p_b_pid_iterator it = probes_by_pid.begin();
+ it != probes_by_pid.end(); it++)
+ emit_vma_callback_probe_decl (s, "", it->first);
+ }
+ s.op->newline(-1) << "};";
+ s.op->newline() << "#endif";
+
s.op->newline() << "static struct stap_itrace_probe stap_itrace_probes[] = {";
s.op->indent(1);
@@ -6515,11 +6555,37 @@ itrace_derived_probe_group::emit_module_init (systemtap_session& s)
return;
s.op->newline();
+ s.op->newline() << "#ifdef STP_NEED_VMA_TRACKER";
+ s.op->newline() << "/* ---- itrace vma callbacks ---- */";
+ s.op->newline() << "for (i=0; i<ARRAY_SIZE(stap_itrace_vmcbs); i++) {";
+ s.op->indent(1);
+ s.op->newline() << "struct stap_task_finder_target *r = &stap_itrace_vmcbs[i];";
+ s.op->newline() << "rc = stap_register_task_finder_target(r);";
+ s.op->newline(-1) << "}";
+ s.op->newline() << "#endif";
+
+ s.op->newline();
s.op->newline() << "/* ---- itrace probes ---- */";
s.op->newline() << "for (i=0; i<" << num_probes << "; i++) {";
s.op->indent(1);
s.op->newline() << "struct stap_itrace_probe *p = &stap_itrace_probes[i];";
+
+ // 'arch_has_single_step' needs to be defined for either single step mode
+ // or branch mode.
+ s.op->newline() << "if (!arch_has_single_step()) {";
+ s.op->indent(1);
+ s.op->newline() << "_stp_error (\"insn probe init: arch does not support step mode\");";
+ s.op->newline() << "rc = -EPERM;";
+ s.op->newline() << "break;";
+ s.op->newline(-1) << "}";
+ s.op->newline() << "if (!p->single_step && !arch_has_block_step()) {";
+ s.op->indent(1);
+ s.op->newline() << "_stp_error (\"insn probe init: arch does not support block step mode\");";
+ s.op->newline() << "rc = -EPERM;";
+ s.op->newline() << "break;";
+ s.op->newline(-1) << "}";
+
s.op->newline() << "rc = stap_register_task_finder_target(&p->tgt);";
s.op->newline(-1) << "}";
}
@@ -6580,9 +6646,6 @@ private:
bool flags_seen[UDPF_NFLAGS];
void emit_probe_decl (systemtap_session& s, utrace_derived_probe *p);
- void emit_vm_callback_probe_decl (systemtap_session& s, bool has_path,
- string path, int64_t pid,
- string vm_callback);
public:
utrace_derived_probe_group(): num_probes(0), flags_seen() { }
@@ -6964,40 +7027,6 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
void
-utrace_derived_probe_group::emit_vm_callback_probe_decl (systemtap_session& s,
- bool has_path,
- string path,
- int64_t pid,
- string vm_callback)
-{
- s.op->newline() << "{";
- s.op->line() << " .tgt={";
-
- if (has_path)
- {
- s.op->line() << " .pathname=\"" << path << "\",";
- s.op->line() << " .pid=0,";
- }
- else
- {
- s.op->line() << " .pathname=NULL,";
- s.op->line() << " .pid=" << pid << ",";
- }
-
- s.op->line() << " .callback=NULL,";
- s.op->line() << " .vm_callback=&" << vm_callback << ",";
- s.op->line() << " },";
- s.op->line() << " .pp=\"internal\",";
- s.op->line() << " .ph=NULL,";
- s.op->line() << " .flags=(UDPF_NONE),";
- s.op->line() << " .ops={ NULL },";
- s.op->line() << " .events=0,";
- s.op->line() << " .engine_attached=0,";
- s.op->line() << " },";
-}
-
-
-void
utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
{
if (probes_by_path.empty() && probes_by_pid.empty())
@@ -7005,7 +7034,6 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline();
s.op->newline() << "/* ---- utrace probes ---- */";
- s.op->newline() << "#include \"task_finder.c\"";
s.op->newline() << "enum utrace_derived_probe_flags {";
s.op->indent(1);
@@ -7213,6 +7241,25 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "return rc;";
s.op->newline(-1) << "}";
+ // Emit vma callbacks.
+ s.op->newline() << "#ifdef STP_NEED_VMA_TRACKER";
+ s.op->newline() << "static struct stap_task_finder_target stap_utrace_vmcbs[] = {";
+ s.op->indent(1);
+ if (! probes_by_path.empty())
+ {
+ for (p_b_path_iterator it = probes_by_path.begin();
+ it != probes_by_path.end(); it++)
+ emit_vma_callback_probe_decl (s, it->first, (int64_t)0);
+ }
+ if (! probes_by_pid.empty())
+ {
+ for (p_b_pid_iterator it = probes_by_pid.begin();
+ it != probes_by_pid.end(); it++)
+ emit_vma_callback_probe_decl (s, "", it->first);
+ }
+ s.op->newline(-1) << "};";
+ s.op->newline() << "#endif";
+
s.op->newline() << "static struct stap_utrace_probe stap_utrace_probes[] = {";
s.op->indent(1);
@@ -7222,12 +7269,6 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
for (p_b_path_iterator it = probes_by_path.begin();
it != probes_by_path.end(); it++)
{
- // Emit a "fake" probe decl that is really a hook for to get
- // our vm_callback called.
- string path = it->first;
- emit_vm_callback_probe_decl (s, true, path, (int64_t)0,
- "__stp_tf_vm_cb");
-
for (unsigned i = 0; i < it->second.size(); i++)
{
utrace_derived_probe *p = it->second[i];
@@ -7242,11 +7283,6 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
for (p_b_pid_iterator it = probes_by_pid.begin();
it != probes_by_pid.end(); it++)
{
- // Emit a "fake" probe decl that is really a hook for to get
- // our vm_callback called.
- emit_vm_callback_probe_decl (s, false, "", it->first,
- "__stp_tf_vm_cb");
-
for (unsigned i = 0; i < it->second.size(); i++)
{
utrace_derived_probe *p = it->second[i];
@@ -7265,6 +7301,15 @@ utrace_derived_probe_group::emit_module_init (systemtap_session& s)
return;
s.op->newline();
+ s.op->newline() << "#ifdef STP_NEED_VMA_TRACKER";
+ s.op->newline() << "/* ---- utrace vma callbacks ---- */";
+ s.op->newline() << "for (i=0; i<ARRAY_SIZE(stap_utrace_vmcbs); i++) {";
+ s.op->indent(1);
+ s.op->newline() << "struct stap_task_finder_target *r = &stap_utrace_vmcbs[i];";
+ s.op->newline() << "rc = stap_register_task_finder_target(r);";
+ s.op->newline(-1) << "}";
+ s.op->newline() << "#endif";
+
s.op->newline() << "/* ---- utrace probes ---- */";
s.op->newline() << "for (i=0; i<ARRAY_SIZE(stap_utrace_probes); i++) {";
s.op->indent(1);
@@ -7494,7 +7539,6 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "#else";
s.op->newline() << "#include \"uprobes/uprobes.h\"";
s.op->newline() << "#endif";
- s.op->newline() << "#include \"task_finder.c\"";
s.op->newline() << "#ifndef MULTIPLE_UPROBES";
s.op->newline() << "#define MULTIPLE_UPROBES 256"; // maximum possible armed uprobes per process() probe point
@@ -7512,6 +7556,21 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline(-1) << "} stap_uprobes [MAXUPROBES];";
s.op->newline() << "DEFINE_MUTEX(stap_uprobes_lock);"; // protects against concurrent registration/unregistration
+ // Emit vma callbacks.
+ s.op->newline() << "#ifdef STP_NEED_VMA_TRACKER";
+ s.op->newline() << "static struct stap_task_finder_target stap_uprobe_vmcbs[] = {";
+ s.op->indent(1);
+ for (unsigned i = 0; i < probes.size(); i++)
+ {
+ uprobe_derived_probe* p = probes[i];
+ if (p->pid != 0)
+ emit_vma_callback_probe_decl (s, "", p->pid);
+ else
+ emit_vma_callback_probe_decl (s, p->module, (int64_t)0);
+ }
+ s.op->newline(-1) << "};";
+ s.op->newline() << "#endif";
+
s.op->newline() << "static struct stap_uprobe_spec {";
s.op->newline(1) << "struct stap_task_finder_target finder;";
s.op->newline() << "unsigned long address;";
@@ -7712,6 +7771,15 @@ void
uprobe_derived_probe_group::emit_module_init (systemtap_session& s)
{
if (probes.empty()) return;
+ s.op->newline() << "#ifdef STP_NEED_VMA_TRACKER";
+ s.op->newline() << "/* ---- uprobe vma callbacks ---- */";
+ s.op->newline() << "for (i=0; i<ARRAY_SIZE(stap_uprobe_vmcbs); i++) {";
+ s.op->indent(1);
+ s.op->newline() << "struct stap_task_finder_target *r = &stap_uprobe_vmcbs[i];";
+ s.op->newline() << "rc = stap_register_task_finder_target(r);";
+ s.op->newline(-1) << "}";
+ s.op->newline() << "#endif";
+
s.op->newline() << "/* ---- user probes ---- */";
s.op->newline() << "for (j=0; j<MAXUPROBES; j++) {";
diff --git a/testsuite/buildok/twentysix.stp b/testsuite/buildok/twentysix.stp
deleted file mode 100755
index 3fb7526f..00000000
--- a/testsuite/buildok/twentysix.stp
+++ /dev/null
@@ -1,7 +0,0 @@
-#! stap -up4
-
-global a
-probe begin
-{
- a [1,2,3,4,5,6] = 0
-}
diff --git a/testsuite/lib/stap_run.exp b/testsuite/lib/stap_run.exp
index a4beaa12..3043eeed 100644
--- a/testsuite/lib/stap_run.exp
+++ b/testsuite/lib/stap_run.exp
@@ -30,6 +30,7 @@ proc stap_run { TEST_NAME {LOAD_GEN_FUNCTION ""} {OUTPUT_CHECK_STRING ""} args }
if [file readable $test_file_name] {
lappend cmd $test_file_name
}
+ send_log "executing: $cmd\n"
eval spawn $cmd
expect {
-timeout 180
diff --git a/testsuite/lib/systemtap.exp b/testsuite/lib/systemtap.exp
index 554e88ed..5311be7b 100644
--- a/testsuite/lib/systemtap.exp
+++ b/testsuite/lib/systemtap.exp
@@ -16,6 +16,16 @@ proc use_server_p {} {
}
+proc utrace_p {} {
+ set path "/proc/kallsyms"
+ if {! [catch {exec grep -q utrace_attach $path} dummy]} {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+
proc print_systemtap_version {} {
set version [exec /bin/uname -r]
set location "/boot/vmlinux-$version"
diff --git a/testsuite/systemtap.base/bz5274.exp b/testsuite/systemtap.base/bz5274.exp
index 92441e9e..2f76a43f 100755
--- a/testsuite/systemtap.base/bz5274.exp
+++ b/testsuite/systemtap.base/bz5274.exp
@@ -17,14 +17,7 @@ if {! [installtest_p]} {
return
}
-# Try to find utrace_attach symbol in /proc/kallsyms
-# copy from utrace_p5.exp
-set utrace_support_found 0
-set path "/proc/kallsyms"
-if {! [catch {exec grep -q utrace_attach $path} dummy]} {
- set utrace_support_found 1
-}
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
catch {exec rm -f $test}
untested "$test -p5"
return
diff --git a/testsuite/systemtap.base/bz6850.exp b/testsuite/systemtap.base/bz6850.exp
index b96ed95c..32ecdaf5 100644
--- a/testsuite/systemtap.base/bz6850.exp
+++ b/testsuite/systemtap.base/bz6850.exp
@@ -3,14 +3,7 @@ set test bz6850
catch {exec gcc -g -o bz6850 $srcdir/$subdir/bz6850.c} err
if {$err == "" && [file exists bz6850]} then { pass "$test compile" } else { fail "$test compile" }
-# Try to find utrace_attach symbol in /proc/kallsyms
-# copy from utrace_p5.exp
-set utrace_support_found 0
-set path "/proc/kallsyms"
-if {! [catch {exec grep -q utrace_attach $path} dummy]} {
- set utrace_support_found 1
-}
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
catch {exec rm -f $test}
untested "$test -p4"
untested "$test -p5"
diff --git a/testsuite/systemtap.base/itrace.exp b/testsuite/systemtap.base/itrace.exp
index e215bfe7..5da0dfaf 100644
--- a/testsuite/systemtap.base/itrace.exp
+++ b/testsuite/systemtap.base/itrace.exp
@@ -2,7 +2,6 @@
# Initialize variables
-set utrace_support_found 0
set exepath "[pwd]/ls_[pid]"
set itrace1_script {
@@ -48,6 +47,26 @@ set itrace2_script {
}
set itrace2_script_output "itraced = 5\r\n"
+set itrace3_script {
+ global branches = 0
+ probe begin
+ {
+ printf("systemtap starting probe\n")
+ }
+ probe process("%s").insn.block
+ {
+ branches += 1
+ if (branches == 5)
+ exit()
+ }
+
+
+ probe end { printf("systemtap ending probe\n")
+ printf("itraced block mode = %%d\n", branches)
+ }
+}
+set itrace3_script_output "itraced block mode = 5\r\n"
+
# Set up our own copy of /bin/ls, to make testing for a particular
# executable easy. We can't use 'ln' here, since we might be creating
@@ -72,14 +91,8 @@ proc run_ls_5_sec {} {
}
-# Try to find utrace_attach symbol in /proc/kallsyms
-set path "/proc/kallsyms"
-if {! [catch {exec grep -q utrace_attach $path} dummy]} {
- set utrace_support_found 1
-}
-
set TEST_NAME "itrace1"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} elseif {![installtest_p]} {
untested $TEST_NAME
@@ -90,7 +103,7 @@ if {$utrace_support_found == 0} {
set TEST_NAME "itrace2"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} elseif {![installtest_p]} {
untested $TEST_NAME
@@ -99,5 +112,16 @@ if {$utrace_support_found == 0} {
stap_run $TEST_NAME run_ls_5_sec $itrace2_script_output -e $script
}
+set TEST_NAME "itrace3"
+if {![utrace_p]} {
+ untested "$TEST_NAME : no kernel utrace support found"
+} elseif {![installtest_p]} {
+ untested $TEST_NAME
+} else {
+ send_log "ATTENTION: if arch_has_block_step is not defined for this arch, this testcase will fail\n"
+ set script [format $itrace3_script $exepath]
+ stap_run $TEST_NAME run_ls_5_sec $itrace3_script_output -e $script
+}
+
# Cleanup
exec rm -f $exepath
diff --git a/testsuite/systemtap.base/labels.exp b/testsuite/systemtap.base/labels.exp
index 6db81c54..2f79a502 100644
--- a/testsuite/systemtap.base/labels.exp
+++ b/testsuite/systemtap.base/labels.exp
@@ -1,14 +1,6 @@
set test "labels"
if {![installtest_p]} {untested $test; return}
-
-# Try to find utrace_attach symbol in /proc/kallsyms
-# copy from utrace_p5.exp
-set utrace_support_found 0
-set path "/proc/kallsyms"
-if {! [catch {exec grep -q utrace_attach $path} dummy]} {
- set utrace_support_found 1
-}
-if {$utrace_support_found == 0} { untested "$test"; return }
+if {![utrace_p]} { untested $test; return }
# Compile a C program to use as the user-space probing target
set label_srcpath "[pwd]/labels.c"
diff --git a/testsuite/systemtap.base/sdt.exp b/testsuite/systemtap.base/sdt.exp
index 46fa5a28..c3aed91e 100644
--- a/testsuite/systemtap.base/sdt.exp
+++ b/testsuite/systemtap.base/sdt.exp
@@ -36,7 +36,7 @@ if { $res != "" } {
pass "compiling $test.c $extra_flag"
}
-if {[installtest_p]} {
+if {[installtest_p] && [utrace_p]} {
stap_run3 "$test $extra_flag" $srcdir/$subdir/$test.stp $testprog -c ./$testprog
} else {
untested "$test $extra_flag"
@@ -61,7 +61,7 @@ if { $res != "" } {
pass "compiling $test.c c++ $extra_flag"
}
-if {[installtest_p]} {
+if {[installtest_p] && [utrace_p]} {
stap_run3 "$test c++ $extra_flag" $srcdir/$subdir/$test.stp $testprog -c ./$testprog
} else {
untested "$test c++ $extra_flag"
diff --git a/testsuite/systemtap.base/static_uprobes.exp b/testsuite/systemtap.base/static_uprobes.exp
index 820626b8..07ff83e9 100644
--- a/testsuite/systemtap.base/static_uprobes.exp
+++ b/testsuite/systemtap.base/static_uprobes.exp
@@ -124,15 +124,7 @@ if { $res != "" } {
}
if {![installtest_p]} {untested $test; return}
-
-# Try to find utrace_attach symbol in /proc/kallsyms
-# copy from utrace_p5.exp
-set utrace_support_found 0
-set path "/proc/kallsyms"
-if {! [catch {exec grep -q utrace_attach $path} dummy]} {
- set utrace_support_found 1
-}
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$test"
catch {exec rm -f $sup_srcpath}
return
@@ -196,7 +188,7 @@ set ok 0
spawn stap -l "process(\"./sdt_types.x\").mark(\"*\")"
expect {
-timeout 180
- -re {mark\(\".*\"\)} { incr ok; exp_continue }
+ -re {mark\(\"[a-z_]+\"\)} { incr ok; exp_continue }
timeout { fail "$test C (timeout)" }
eof { }
}
diff --git a/testsuite/systemtap.base/uprobes.exp b/testsuite/systemtap.base/uprobes.exp
index 89250e7b..6344cbf0 100644
--- a/testsuite/systemtap.base/uprobes.exp
+++ b/testsuite/systemtap.base/uprobes.exp
@@ -18,14 +18,7 @@ if [file exists $path] then { pass "$test prep" } else { fail "$test prep" }
catch {exec gcc -g -o jennie jennie.c} err
if {$err == "" && [file exists jennie]} then { pass "$test compile" } else { fail "$test compile" }
-# Try to find utrace_attach symbol in /proc/kallsyms
-# copy from utrace_p5.exp
-set utrace_support_found 0
-set path "/proc/kallsyms"
-if {! [catch {exec grep -q utrace_attach $path} dummy]} {
- set utrace_support_found 1
-}
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$test -p4"; untested "$test -p5"
catch {exec rm -f jennie.c jennie}
return
diff --git a/testsuite/systemtap.base/uprobes_lib.exp b/testsuite/systemtap.base/uprobes_lib.exp
index ae1b72e8..63ef957a 100644
--- a/testsuite/systemtap.base/uprobes_lib.exp
+++ b/testsuite/systemtap.base/uprobes_lib.exp
@@ -10,21 +10,23 @@ set testflags "additional_flags=-g additional_flags=-O"
set testlibflags "$testflags additional_flags=-fPIC additional_flags=-shared"
set maintestflags "$testflags additional_flags=-L$testlibdir additional_flags=-l$testlibname additional_flags=-Wl,-rpath,$testlibdir"
-# Only run on make installcheck
-if {! [installtest_p]} { untested "$test"; return }
-
# Compile our test program and library.
set res [target_compile $testsrclib $testso executable $testlibflags]
if { $res != "" } {
verbose "target_compile for $testso failed: $res" 2
- fail "unable to compile $testsrclib"
+ fail "$test compile $testsrclib"
return
+} else {
+ pass "$test compile $testsrclib"
}
+
set res [target_compile $testsrc $testexe executable $maintestflags]
if { $res != "" } {
verbose "target_compile failed: $res" 2
- fail "unable to compile $testsrc"
+ fail "$test compile $testsrc"
return
+} else {
+ pass "$test compile $testsrc"
}
# XXX main_func needs another/extra test. Disabled for now.
@@ -33,6 +35,9 @@ if { $res != "" } {
# lib_func}
set ::result_string {lib_func}
+# Only run on make installcheck
+if {! [installtest_p]} { untested "$test"; return }
+if {! [utrace_p]} { untested $test; return }
stap_run2 $srcdir/$subdir/$test.stp -c $testexe
#exec rm -f $testexe $testso
diff --git a/testsuite/systemtap.base/utrace_p4.exp b/testsuite/systemtap.base/utrace_p4.exp
index 1467d9c8..8d323a8a 100644
--- a/testsuite/systemtap.base/utrace_p4.exp
+++ b/testsuite/systemtap.base/utrace_p4.exp
@@ -7,8 +7,6 @@
# utrace doesn't exist in the kernel, marks the tests as 'untested'.
# Initialize variables
-set utrace_support_found 0
-
set begin_script {"probe process(\"/bin/ls\").begin { print(\"ls begin\") }"}
set end_script {"probe process(\"/bin/ls\").end { print(\"ls end\") }"}
set syscall_script {"probe process(\"/bin/ls\").syscall { printf(\"|%d\", \$syscall) }"}
@@ -24,18 +22,12 @@ set pid_syscall_return_script {"probe process(123).syscall.return { printf(\"|%d
set pid_thread_begin_script {"probe process(123).thread.begin { print(\"123 thread.begin\") }"}
set pid_thread_end_script {"probe process(123).thread.end { print(\"123 thread.end\") }"}
-# Try to find utrace_attach symbol in /proc/kallsyms
-set path "/proc/kallsyms"
-if {! [catch {exec grep -q utrace_attach $path} dummy]} {
- set utrace_support_found 1
-}
-
#
# Do some utrace compile tests.
#
set TEST_NAME "UTRACE_P4_01"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
# Try compiling a begin script using a path
@@ -43,7 +35,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P4_01_pid"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
# Try compiling a begin script using a pid
@@ -51,7 +43,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P4_02"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
# Try compiling a end script using a path
@@ -59,7 +51,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P4_02_pid"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
# Try compiling a end script using a pid
@@ -67,7 +59,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P4_03"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
# Try compiling a syscall script using a path
@@ -75,7 +67,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P4_03_pid"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
# Try compiling a syscall script using a pid
@@ -83,7 +75,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P4_04"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
# Try compiling a syscall return script using a path
@@ -91,7 +83,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P4_04_pid"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
# Try compiling a syscall return script using a pid
@@ -99,7 +91,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P4_05"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
# Try compiling an thread.begin script using a path
@@ -107,7 +99,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P4_05_pid"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
# Try compiling an thread.begin script using a pid
@@ -115,7 +107,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P4_06"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
# Try compiling an thread.end script using a path
@@ -123,7 +115,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P4_06_pid"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
# Try compiling an thread.end script using a pid
@@ -131,7 +123,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P4_07"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
# Try compiling an system-wide begin script
diff --git a/testsuite/systemtap.base/utrace_p5.exp b/testsuite/systemtap.base/utrace_p5.exp
index 33281350..3d432dc3 100644
--- a/testsuite/systemtap.base/utrace_p5.exp
+++ b/testsuite/systemtap.base/utrace_p5.exp
@@ -1,7 +1,6 @@
# Utrace run (pass 5) tests.
# Initialize variables
-set utrace_support_found 0
set exepath "[pwd]/cat_[pid]"
set multi_srcpath "$srcdir/systemtap.base/utrace_p5_multi.c"
set multi_exepath "[pwd]/utrace_p5_multi_[pid]"
@@ -90,12 +89,6 @@ set bz6841_script {
}
set bz6841_script_output ".+ issues syscall \\d+ times\r\n"
-# Try to find utrace_attach symbol in /proc/kallsyms
-set path "/proc/kallsyms"
-if {! [catch {exec grep -q utrace_attach $path} dummy]} {
- set utrace_support_found 1
-}
-
# Set up our own copy of /bin/cat, to make testing for a particular
# executable easy. We can't use 'ln' here, since we might be creating
# a cross-device link. We can't use 'ln -s' here, since the kernel
@@ -138,7 +131,7 @@ proc run_utrace_p5_multi {} {
}
set TEST_NAME "UTRACE_P5_01"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} elseif {![installtest_p]} {
untested "$TEST_NAME"
@@ -148,7 +141,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P5_02"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} elseif {![installtest_p]} {
untested "$TEST_NAME"
@@ -158,7 +151,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P5_03"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} elseif {![installtest_p]} {
untested "$TEST_NAME"
@@ -168,7 +161,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P5_04"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} elseif {![installtest_p]} {
untested "$TEST_NAME"
@@ -178,7 +171,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P5_05"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} elseif {![installtest_p]} {
untested "$TEST_NAME"
@@ -189,7 +182,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P5_06"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} elseif {![installtest_p]} {
untested "$TEST_NAME"
@@ -200,7 +193,7 @@ if {$utrace_support_found == 0} {
}
set TEST_NAME "UTRACE_P5_07"
-if {$utrace_support_found == 0} {
+if {![utrace_p]} {
untested "$TEST_NAME : no kernel utrace support found"
} elseif {![installtest_p]} {
untested "$TEST_NAME"
diff --git a/testsuite/systemtap.context/args.tcl b/testsuite/systemtap.context/args.tcl
index 7cb79cdf..cffaeaef 100644
--- a/testsuite/systemtap.context/args.tcl
+++ b/testsuite/systemtap.context/args.tcl
@@ -1,6 +1,6 @@
spawn stap $srcdir/$subdir/args.stp
expect {
- -timeout 240
+ -timeout 60
"READY" {
exec echo 1 > /proc/stap_test_cmd
expect {
diff --git a/testsuite/systemtap.context/backtrace.tcl b/testsuite/systemtap.context/backtrace.tcl
index ca60c369..6edda812 100644
--- a/testsuite/systemtap.context/backtrace.tcl
+++ b/testsuite/systemtap.context/backtrace.tcl
@@ -8,7 +8,7 @@ set m6 0
spawn stap -DMAXSTRINGLEN=256 $srcdir/$subdir/backtrace.stp
#exp_internal 1
expect {
- -timeout 240
+ -timeout 60
"Systemtap probe: begin\r\n" {
pass "backtrace of begin probe"
exec echo 0 > /proc/stap_test_cmd
diff --git a/testsuite/systemtap.context/context.exp b/testsuite/systemtap.context/context.exp
index 010db445..cec09b29 100644
--- a/testsuite/systemtap.context/context.exp
+++ b/testsuite/systemtap.context/context.exp
@@ -80,6 +80,7 @@ if {[build_modules] == 0} {
}
foreach test $testlist {
+ send_log "sourcing: $srcdir/$subdir/$test.tcl\n"
source $srcdir/$subdir/$test.tcl
}
diff --git a/testsuite/systemtap.context/num_args.tcl b/testsuite/systemtap.context/num_args.tcl
index 7d12b433..62ac8dd3 100644
--- a/testsuite/systemtap.context/num_args.tcl
+++ b/testsuite/systemtap.context/num_args.tcl
@@ -3,7 +3,7 @@ foreach arglist $arglists {
set tag [concat numeric $arglist]
eval spawn stap $arglist $srcdir/$subdir/num_args.stp
expect {
- -timeout 240
+ -timeout 60
"READY" {
exec echo 1 > /proc/stap_test_cmd
expect {
diff --git a/testsuite/systemtap.context/pid.tcl b/testsuite/systemtap.context/pid.tcl
index a2c091f1..70a87345 100644
--- a/testsuite/systemtap.context/pid.tcl
+++ b/testsuite/systemtap.context/pid.tcl
@@ -2,7 +2,7 @@ set tests [list execname pexecname pid ppid tid uid euid gid egid]
spawn stap $srcdir/$subdir/pid.stp
#exp_internal 1
expect {
- -timeout 240
+ -timeout 60
"READY" {
set pid [exec echo 1 > /proc/stap_test_cmd &]
set ppid {[0-9]*}
diff --git a/testsuite/systemtap.context/usymbols.c b/testsuite/systemtap.context/usymbols.c
new file mode 100644
index 00000000..7c590724
--- /dev/null
+++ b/testsuite/systemtap.context/usymbols.c
@@ -0,0 +1,39 @@
+/* usymbol test case
+ * Copyright (C) 2008, Red Hat Inc.
+ *
+ * This file is part of systemtap, and is free software. You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ *
+ * Uses signal to tranfer user space addresses into the kernel where a
+ * probe on sigaction will extract them and produce the symbols. To
+ * poke into the executable we get the sa_handler from the main executable,
+ * and then the library through calling signal.
+ *
+ * FIXME. We call into the library to get the right symbol. If we
+ * register the handler from the main executable. We need to handle
+ * @plt symbols (setting a handler in the main executable that is in a
+ * shared library will have the @plt address, not the address inside
+ * the shared library).
+ */
+
+#include <signal.h>
+typedef void (*sighandler_t)(int);
+
+// function from our library
+int lib_main (void);
+
+void
+main_handler (int signum)
+{
+ /* dummy handler, just used for the address... */
+}
+
+int
+main (int argc, char *argv[], char *envp[])
+{
+ // Use SIGFPE since we never expect that to be triggered.
+ signal(SIGFPE, main_handler);
+ lib_main();
+}
diff --git a/testsuite/systemtap.context/usymbols.exp b/testsuite/systemtap.context/usymbols.exp
new file mode 100644
index 00000000..82f68b67
--- /dev/null
+++ b/testsuite/systemtap.context/usymbols.exp
@@ -0,0 +1,83 @@
+set test "./usymbols"
+set testpath "$srcdir/$subdir"
+set testsrc "$testpath/usymbols.c"
+set testsrclib "$testpath/usymbols_lib.c"
+set testexe "[pwd]/usymbols"
+set testlibname "usymbols"
+set testlibdir "[pwd]"
+set testso "$testlibdir/lib${testlibname}.so"
+set testflags "additional_flags=-g additional_flags=-O"
+set testlibflags "testflags additional_flags=-fPIC additional_flags=-shared"
+set maintestflags "$testflags additional_flags=-L$testlibdir additional_flags=-l$testlibname additional_flags=-Wl,-rpath,$testlibdir"
+
+# Only run on make installcheck and utrace present.
+if {! [installtest_p]} { untested "$test"; return }
+if {! [utrace_p]} { untested "$test"; return }
+
+# Compile our test program and library.
+set res [target_compile $testsrclib $testso executable $testlibflags]
+if { $res != "" } {
+ verbose "target_compile for $testso failed: $res" 2
+ fail "unable to compile $testsrclib"
+ return
+}
+set res [target_compile $testsrc $testexe executable $maintestflags]
+if { $res != "" } {
+ verbose "target_compile failed: $res" 2
+ fail "unable to compile $testsrc"
+ return
+}
+
+# We need the execname() trick to work around (the workaround of) PR6964
+# otherwise we get also the rt_sigactions of stapio. Get the handler
+# (comes from the executable or the library).
+set testscript {
+ probe syscall.rt_sigaction {
+ if (pid() == target() && execname() == "%s") {
+ handler = $act->sa_handler;
+ printf("handler: %%s\n", symbolname(handler));
+ }
+ }
+ /* track through uprobes, so as to make sure we have the symbols */
+ probe process("%s").function("*") { printf(""); }
+}
+
+set output {handler: main_handler
+handler: lib_handler}
+
+# Got to run stap with both the exe and the libraries used as -d args.
+# XXX Note how we need the fully resolved (absolute) path...
+set script [format $testscript usymbols $testexe]
+catch {eval exec [concat ldd $testexe | grep $testlibname]} libpath
+set libpath [lindex [split $libpath " "] 2]
+send_log "libpath: $libpath\n"
+if {[string equal "link" [file type $libpath]]} {
+ set libpath [file join [file dirname $libpath] [file readlink $libpath]]
+}
+send_log "libpath: $libpath\n"
+
+# XXX Cheat, explicitly add STP_NEED_VMA_TRACKER
+set cmd [concat stap -DSTP_NEED_VMA_TRACKER -d $libpath -d $testexe -c $testexe -e {$script}]
+send_log "cmd: $cmd\n"
+catch {eval exec $cmd} res
+send_log "cmd output: $res\n"
+
+set n 0
+set m [llength [split $output "\n"]]
+set expected [split $output "\n"]
+foreach line [split $res "\n"] {
+ if {![string equal $line [lindex $expected $n]]} {
+ fail usymbols
+ send_log "line [expr $n + 1]: expected \"[lindex $expected $n]\", "
+ send_log "Got \"$line\"\n"
+ return
+ }
+ incr n
+}
+if { $n != $m } {
+ fail usymbols
+ send_log "Got \"$n\" lines, expected \"$m\" lines\n"
+} else {
+ pass usymbols
+}
+exec rm -f $testexe $testso
diff --git a/testsuite/systemtap.context/usymbols_lib.c b/testsuite/systemtap.context/usymbols_lib.c
new file mode 100644
index 00000000..faccb39b
--- /dev/null
+++ b/testsuite/systemtap.context/usymbols_lib.c
@@ -0,0 +1,29 @@
+/* usymbol test case - library helper
+ * Copyright (C) 2008, Red Hat Inc.
+ *
+ * This file is part of systemtap, and is free software. You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ *
+ * Uses signal to tranfer user space addresses into the kernel where a
+ * probe on sigaction will extract them and produce the symbols. To
+ * poke into the executable we get the sa_handler set through signal
+ * from this library.
+ */
+
+#include <signal.h>
+typedef void (*sighandler_t)(int);
+
+void
+lib_handler (int signum)
+{
+ /* dummy handler, just used for the address... */
+}
+
+void
+lib_main ()
+{
+ // Use SIGFPE since we never expect that to be triggered.
+ signal(SIGFPE, lib_handler);
+}
diff --git a/testsuite/systemtap.pass1-4/buildok.exp b/testsuite/systemtap.pass1-4/buildok.exp
index 08d50fb5..12275c1d 100644
--- a/testsuite/systemtap.pass1-4/buildok.exp
+++ b/testsuite/systemtap.pass1-4/buildok.exp
@@ -6,12 +6,12 @@ foreach file [lsort [glob -nocomplain $srcdir/$self/*.stp]] {
# some tests are known to fail.
switch $test {
buildok/perfmon01.stp {setup_kfail 909 *-*-*}
- buildok/twentysix.stp {setup_kfail 4105 *-*-*}
buildok/twentyseven.stp {setup_kfail 4166 *-*-*}
buildok/sched_test.stp {setup_kfail 1155 *-*-*}
buildok/process_test.stp {setup_kfail 1155 *-*-*}
buildok/rpc-all-probes.stp {setup_kfail 4413 *-*-*}
buildok/nfs-all-probes.stp {setup_kfail 4413 *-*-*}
+ buildok/per-process-syscall.stp {if {![utrace_p]} { setup_kfail 9999 *-*-*} }
}
if {$rc == 0} { pass $test } else { fail $test }
}
diff --git a/testsuite/systemtap.server/server.exp b/testsuite/systemtap.server/server.exp
index c2c60b97..d2dd0f16 100644
--- a/testsuite/systemtap.server/server.exp
+++ b/testsuite/systemtap.server/server.exp
@@ -16,7 +16,6 @@ foreach file [lsort [glob -nocomplain $srcdir/$self/*.stp]] {
# some tests are known to fail.
switch $test {
"buildok/perfmon01.stp with server" {setup_kfail 909 *-*-*}
- "buildok/twentysix.stp with server" {setup_kfail 4105 *-*-*}
"buildok/twentyseven.stp with server" {setup_kfail 4166 *-*-*}
"buildok/sched_test.stp with server" {setup_kfail 1155 *-*-*}
"buildok/process_test.stp with server" {setup_kfail 1155 *-*-*}
diff --git a/translate.cxx b/translate.cxx
index 47fffd1e..9085349e 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -4955,6 +4955,8 @@ translate_pass (systemtap_session& s)
s.op->newline() << "#define STP_OVERLOAD";
s.op->newline() << "#endif";
+ s.op->newline() << "#define STP_SKIP_BADVARS " << (s.skip_badvars ? 1 : 0);
+
if (s.bulk_mode)
s.op->newline() << "#define STP_BULKMODE";
diff --git a/util.cxx b/util.cxx
index a20e8292..5c05a1dd 100644
--- a/util.cxx
+++ b/util.cxx
@@ -20,13 +20,15 @@
#include <cerrno>
extern "C" {
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <fcntl.h>
#include <pwd.h>
-#include <unistd.h>
+#include <spawn.h>
#include <stdio.h>
#include <stdlib.h>
-#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
}
using namespace std;
@@ -294,4 +296,35 @@ git_revision(const string& path)
return revision;
}
+
+static pid_t spawned_pid = 0;
+
+// Runs a command with a saved PID, so we can kill it from the signal handler
+int
+stap_system(const char *command)
+{
+ const char * argv[] = { "sh", "-c", command, NULL };
+ int ret, status;
+
+ spawned_pid = 0;
+ ret = posix_spawn(&spawned_pid, "/bin/sh", NULL, NULL,
+ const_cast<char **>(argv), environ);
+ if (ret == 0)
+ {
+ if (waitpid(spawned_pid, &status, 0) == spawned_pid)
+ ret = WIFEXITED(status) ? WEXITSTATUS(status) : 128 + WTERMSIG(status);
+ else
+ ret = errno;
+ }
+ spawned_pid = 0;
+ return ret;
+}
+
+// Send a signal to our spawned command
+int
+kill_stap_spawn(int sig)
+{
+ return spawned_pid ? kill(spawned_pid, sig) : 0;
+}
+
/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
diff --git a/util.h b/util.h
index de5ebe5f..175f1f40 100644
--- a/util.h
+++ b/util.h
@@ -14,6 +14,8 @@ void tokenize(const std::string& str, std::vector<std::string>& tokens,
std::string find_executable(const std::string& name);
const std::string cmdstr_quoted(const std::string& cmd);
std::string git_revision(const std::string& path);
+int stap_system(const char *command);
+int kill_stap_spawn(int sig);
// stringification generics