summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@elastic.org>2008-01-24 23:48:06 -0500
committerFrank Ch. Eigler <fche@elastic.org>2008-01-24 23:48:06 -0500
commita1732c4f7856621604a1cc45a29af618aaa502e0 (patch)
tree29e3f9c4405e1fd1f81b8c87ac2e485855541a66
parent7ee3e80ec0b7880c33d0ca3018025855d9dd5123 (diff)
parent674427d3a018d0f89c9669db8dcf952aab8b4423 (diff)
downloadsystemtap-steved-a1732c4f7856621604a1cc45a29af618aaa502e0.tar.gz
systemtap-steved-a1732c4f7856621604a1cc45a29af618aaa502e0.tar.xz
systemtap-steved-a1732c4f7856621604a1cc45a29af618aaa502e0.zip
Merge branch 'master' of git://sources.redhat.com/git/systemtap
-rw-r--r--ChangeLog93
-rw-r--r--Makefile.am2
-rw-r--r--Makefile.in3
-rw-r--r--NEWS2
-rw-r--r--buildrun.cxx3
-rwxr-xr-xconfigure65
-rw-r--r--configure.ac32
-rw-r--r--elaborate.cxx316
-rw-r--r--elaborate.h3
-rw-r--r--runtime/autoconf-nameidata.c4
-rw-r--r--runtime/autoconf-x86-uniregs.c6
-rw-r--r--runtime/loc2c-runtime.h32
-rw-r--r--runtime/procfs.c6
-rw-r--r--runtime/regs.c79
-rw-r--r--runtime/regs.h5
-rw-r--r--runtime/stack-i386.c4
-rw-r--r--runtime/staprun/ChangeLog5
-rw-r--r--runtime/staprun/staprun_funcs.c2
-rw-r--r--runtime/staprun/symbols.c13
-rw-r--r--runtime/uprobes/uprobes.c72
-rw-r--r--stap.1.in9
-rw-r--r--staptree.cxx50
-rw-r--r--staptree.h29
-rw-r--r--systemtap.spec.in15
-rw-r--r--tapset/ChangeLog7
-rw-r--r--tapset/syscalls.stp33
-rw-r--r--tapsets.cxx47
-rw-r--r--testsuite/ChangeLog26
-rw-r--r--testsuite/Makefile.am3
-rw-r--r--testsuite/Makefile.in6
-rwxr-xr-xtestsuite/configure20
-rw-r--r--testsuite/configure.ac2
-rw-r--r--testsuite/lib/systemtap.exp3
-rwxr-xr-xtestsuite/semko/forty.stp4
-rwxr-xr-xtestsuite/semko/fortyone.stp3
-rwxr-xr-xtestsuite/semko/fortytwo.stp10
-rw-r--r--testsuite/semok/twentynine.stp6
-rw-r--r--testsuite/systemtap.base/debugpath.exp18
-rw-r--r--testsuite/systemtap.samples/crash.exp45
-rwxr-xr-xtestsuite/systemtap.samples/crash.sh8
-rw-r--r--testsuite/systemtap.samples/testlog.stp6
-rw-r--r--translate.cxx44
42 files changed, 868 insertions, 273 deletions
diff --git a/ChangeLog b/ChangeLog
index 71cb2001..810a4d1d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,96 @@
+2008-01-24 Frank Ch. Eigler <fche@elastic.org>
+
+ * Makefile.am: Make another $(MKDIR) call visible.
+ * Makefile.in: Regenerated.
+
+2008-01-24 David Smith <dsmith@redhat.com>
+
+ PR 5661 (reverted).
+ * configure.ac: Removed elfutils version number check.
+ * configure: Regenerated.
+ * acsite.m4: Removed.
+ * systemtap.spec.in: Minimum elfutils version number is no longer
+ filled in by configure.
+
+ PR 5650 (partial).
+ * configure.ac: Handles sqlite optional functionality correctly.
+ If enabled/disabled by the user, do the right thing. If not
+ specified by the user, use it if present.
+ * configure: Regenerated.
+ * systemtap.spec.in: Always specify to configure whether to use
+ sqlite or not.
+
+2008-01-24 Dave Brolley <brolley@redhat.com>
+
+ PR 5017.
+ * staptree.cxx (<cstring>): #include it.
+ (required <indexable *>): Remove 'static' from instantiation and
+ move instantiation to here from...
+ * staptree.h: ...here.
+
+2008-01-23 David Smith <dsmith@redhat.com>
+
+ PR 5661.
+ * configure.ac: Checks elfutils version number.
+ * acsite.m4: New file containing macro to return elfutils version
+ number.
+ * configure: Regenerated.
+ * systemtap.spec.in: Minimum elfutils version number is now filled
+ in by configure.
+
+2008-01-23 Dave Brolley <brolley@redhat.com>
+
+ PR 5613.
+ * translate.cxx (var::fini): New method.
+ (c_unparser::emit_module_init): Call var::fini when deregistering
+ variables without indices.
+ (c_unparser::emit_module_exit): Likewise.
+
+2008-01-23 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 2151.
+ * tapsets.cxx (dwflpp::setup): Parametrize debuginfo_path.
+ * stap.1.in: Document this.
+
+2008-01-22 Jim Keniston <jkenisto@us.ibm.com>
+
+ * runtime/uprobes/uprobes.c: Fix from Srinivasa: Recast
+ rcu_dereferences of engine->data to resync with kernel.org
+ builds.
+
+2008-01-18 Jim Keniston <jkenisto@us.ibm.com>
+
+ * runtime/uprobes/uprobes.c: Added static copy of
+ access_process_vm(), for kernels that don't export it.
+
+2008-01-18 Frank Ch. Eigler <fche@elastic.org>
+
+ * configure.ac, systemtap.spec.in: Update version to 0.6.1
+ * configure: Regenerated.
+
+2008-01-17 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 4935.
+ Reorganize probe condition implementation.
+ * elaborate.cxx (add_condition): New function.
+ (derived_probe): Remove condition member.
+ (derived_probe ctors): Assert non-null incoming probe/location ptrs.
+ (insert_condition_statement): Remove; turn into ...
+ (semantic_pass_conditions): New pass-2 subpass.
+ (semantic_pass_symbols, visit_symbol, visit_functioncall, find_var):
+ Detect some condition-related error cases.
+ (match_key): Change type to exp_type from tok_type. Update callers.
+ (alias_expansion_builder): Propagate probe conditions.
+ * staptree.cxx (probe): Remove condition field and related functions.
+ * tapsets.cxx (dwarf_derived_probe ctor): Compute replacement
+ wildcard-expanded probe_point preserving more of the original
+ location.
+ (mark_derived_probe ctor): Make similar to others - take location
+ rather than condition parameters.
+ * translate.cxx (emit_common_header): Tweak ordering of tmpcounter
+ traversal and hashkey expression generation.
+ * elaborate.h: Corresponding changes.
+
2008-01-17 David Smith <dsmith@redhat.com>
* tapsets.cxx
diff --git a/Makefile.am b/Makefile.am
index df86dc80..291adfd9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -91,7 +91,7 @@ $(STAPLOG): staplog.c
$(CC) -Wall -shared -rdynamic $(LDFLAGS) $(CFLAGS) -fPIC -o $@ $<
all-local: $(STAPLOG)
install-exec-local: $(STAPLOG)
- -$(MKDIR_P) $(DESTDIR)$(pkglibdir)
+ $(MKDIR_P) $(DESTDIR)$(pkglibdir)
$(INSTALL) $(STAPLOG) $(DESTDIR)$(pkglibdir)
else
endif
diff --git a/Makefile.in b/Makefile.in
index 27577e66..d92d7a94 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -181,6 +181,7 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
+ELFUTILS_REQUIRED_VERSION = @ELFUTILS_REQUIRED_VERSION@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL = @INSTALL@
@@ -1476,7 +1477,7 @@ install-exec-hook:
@BUILD_CRASHMOD_TRUE@ $(CC) -Wall -shared -rdynamic $(LDFLAGS) $(CFLAGS) -fPIC -o $@ $<
@BUILD_CRASHMOD_TRUE@all-local: $(STAPLOG)
@BUILD_CRASHMOD_TRUE@install-exec-local: $(STAPLOG)
-@BUILD_CRASHMOD_TRUE@ -$(MKDIR_P) $(DESTDIR)$(pkglibdir)
+@BUILD_CRASHMOD_TRUE@ $(MKDIR_P) $(DESTDIR)$(pkglibdir)
@BUILD_CRASHMOD_TRUE@ $(INSTALL) $(STAPLOG) $(DESTDIR)$(pkglibdir)
# Copy some of the testsuite sample scripts to the distdir
diff --git a/NEWS b/NEWS
index 7b3e3265..05d11eca 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-* What's new in version 0.6 / since version 0.5.15?
+* What's new in version 0.6 / 0.6.1
- Crash utility can retrieve systemtap's relay buffer from a kernel dump
image by using staplog which is a crash extension module. To use this
diff --git a/buildrun.cxx b/buildrun.cxx
index 2f7c358d..b41b9545 100644
--- a/buildrun.cxx
+++ b/buildrun.cxx
@@ -88,6 +88,9 @@ compile_pass (systemtap_session& s)
o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-constant-tsc.c, -DSTAPCONF_CONSTANT_TSC,)" << endl;
o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-tsc-khz.c, -DSTAPCONF_TSC_KHZ,)" << endl;
o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-ktime-get-real.c, -DSTAPCONF_KTIME_GET_REAL,)" << endl;
+ o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-x86-uniregs.c, -DSTAPCONF_X86_UNIREGS,)" << endl;
+
+ o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-nameidata.c, -DSTAPCONF_NAMEIDATA_CLEANUP,)" << endl;
for (unsigned i=0; i<s.macros.size(); i++)
o << "EXTRA_CFLAGS += -D " << lex_cast_qstring(s.macros[i]) << endl;
diff --git a/configure b/configure
index 1a547523..b0fdfdcf 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for systemtap 0.6.
+# Generated by GNU Autoconf 2.61 for systemtap 0.6.1.
#
# Report bugs to <systemtap@sources.redhat.com>.
#
@@ -574,8 +574,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='systemtap'
PACKAGE_TARNAME='systemtap'
-PACKAGE_VERSION='0.6'
-PACKAGE_STRING='systemtap 0.6'
+PACKAGE_VERSION='0.6.1'
+PACKAGE_STRING='systemtap 0.6.1'
PACKAGE_BUGREPORT='systemtap@sources.redhat.com'
# Factoring default headers for most tests.
@@ -1233,7 +1233,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures systemtap 0.6 to adapt to many kinds of systems.
+\`configure' configures systemtap 0.6.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1299,7 +1299,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of systemtap 0.6:";;
+ short | recursive ) echo "Configuration of systemtap 0.6.1:";;
esac
cat <<\_ACEOF
@@ -1313,6 +1313,7 @@ Optional Features:
--enable-perfmon enable perfmon support (default is disabled)
--enable-prologues make -P prologue-searching default
--enable-ssp enable gcc stack-protector
+ --enable-sqlite build with sqlite support
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -1398,7 +1399,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-systemtap configure 0.6
+systemtap configure 0.6.1
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1412,7 +1413,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by systemtap $as_me 0.6, which was
+It was created by systemtap $as_me 0.6.1, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
@@ -1767,7 +1768,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
am__api_version='1.10'
ac_aux_dir=
@@ -2105,7 +2105,7 @@ fi
# Define the identity of the package.
PACKAGE='systemtap'
- VERSION='0.6'
+ VERSION='0.6.1'
cat >>confdefs.h <<_ACEOF
@@ -5823,8 +5823,6 @@ fi
-
-
# Check whether --enable-perfmon was given.
if test "${enable_perfmon+set}" = set; then
enableval=$enable_perfmon; perfmon_support=$enableval
@@ -5959,10 +5957,28 @@ fi
fi
+# Check whether --enable-ssp was given.
+if test "${enable_ssp+set}" = set; then
+ enableval=$enable_ssp;
+fi
+
+if test "x$enable_ssp" == xyes; then
+ CFLAGS="$CFLAGS -fstack-protector-all -D_FORTIFY_SOURCE=2"
+ CXXFLAGS="$CXXFLAGS -fstack-protector-all -D_FORTIFY_SOURCE=2"
+ { echo "$as_me:$LINENO: Compiling with gcc -fstack-protector-all et al." >&5
+echo "$as_me: Compiling with gcc -fstack-protector-all et al." >&6;}
+fi
-SAVE_LIBS="$LIBS"
-{ echo "$as_me:$LINENO: checking for sqlite3_open in -lsqlite3" >&5
+# Check whether --enable-sqlite was given.
+if test "${enable_sqlite+set}" = set; then
+ enableval=$enable_sqlite;
+else
+ enable_sqlite=check
+fi
+ sqlite3_LIBS=
+if test "x$enable_sqlite" != xno; then
+ { echo "$as_me:$LINENO: checking for sqlite3_open in -lsqlite3" >&5
echo $ECHO_N "checking for sqlite3_open in -lsqlite3... $ECHO_C" >&6; }
if test "${ac_cv_lib_sqlite3_sqlite3_open+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -6024,17 +6040,19 @@ fi
{ echo "$as_me:$LINENO: result: $ac_cv_lib_sqlite3_sqlite3_open" >&5
echo "${ECHO_T}$ac_cv_lib_sqlite3_sqlite3_open" >&6; }
if test $ac_cv_lib_sqlite3_sqlite3_open = yes; then
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBSQLITE3 1
-_ACEOF
-
- LIBS="-lsqlite3 $LIBS"
+ sqlite3_LIBS=-lsqlite3
+else
+ if test "x$enable_sqlite" != xcheck; then
+ { { echo "$as_me:$LINENO: error: --enable-sqlite was given, but test for sqlite failed
+See \`config.log' for more details." >&5
+echo "$as_me: error: --enable-sqlite was given, but test for sqlite failed
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
fi
-sqlite3_LIBS="$LIBS"
-
-LIBS="$SAVE_LIBS"
+fi
# Check whether --enable-ssp was given.
@@ -6454,6 +6472,7 @@ echo "$as_me: error: missing elfutils development headers/libraries (ebl 0.123+)
{ (exit 1); exit 1; }; }
fi
+
stap_LIBS="$LIBS"
LIBS="$SAVE_LIBS"
else
@@ -7031,7 +7050,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by systemtap $as_me 0.6, which was
+This file was extended by systemtap $as_me 0.6.1, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -7084,7 +7103,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-systemtap config.status 0.6
+systemtap config.status 0.6.1
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
diff --git a/configure.ac b/configure.ac
index 256155a8..f53fca84 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,10 +1,9 @@
dnl configure.ac --- autoconf input file for systemtap
dnl Process this file with autoconf to produce a configure script.
-AC_INIT([systemtap], 0.6, systemtap@sources.redhat.com, systemtap)
+AC_INIT([systemtap], 0.6.1, systemtap@sources.redhat.com, systemtap)
dnl ^^^ see also NEWS, testsuite/configure.ac
-
AC_PREREQ(2.59)
AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE
@@ -25,8 +24,6 @@ AC_PROG_MAKE_SET
AC_SUBST(CFLAGS)
AC_SUBST(CXXFLAGS)
-
-
dnl enable option to generate code for using perfmon
AC_ARG_ENABLE(perfmon,
[ --enable-perfmon enable perfmon support (default is disabled)],
@@ -76,13 +73,27 @@ if test "$enable_prologues" = yes; then
AC_DEFINE([ENABLE_PROLOGUES],[],[make -P prologue-searching default])
fi])
+AC_ARG_ENABLE([ssp],
+ [AC_HELP_STRING([--enable-ssp], [enable gcc stack-protector])])
+AS_IF([test "x$enable_ssp" == xyes],
+ [CFLAGS="$CFLAGS -fstack-protector-all -D_FORTIFY_SOURCE=2"
+ CXXFLAGS="$CXXFLAGS -fstack-protector-all -D_FORTIFY_SOURCE=2"
+ AC_MSG_NOTICE([Compiling with gcc -fstack-protector-all et al.])])
-SAVE_LIBS="$LIBS"
-AC_CHECK_LIB(sqlite3, sqlite3_open)
-sqlite3_LIBS="$LIBS"
-AC_SUBST(sqlite3_LIBS)
-LIBS="$SAVE_LIBS"
-
+dnl Handle optional sqlite support. If enabled/disabled by the user,
+dnl do the right thing. If not specified by the user, use it if
+dnl present.
+AC_ARG_ENABLE([sqlite],
+ AS_HELP_STRING([--enable-sqlite], [build with sqlite support]),
+ [], dnl ACTION-IF-GIVEN
+ [enable_sqlite=check]) dnl ACTION-IF-NOT-GIVEN
+sqlite3_LIBS=
+AS_IF([test "x$enable_sqlite" != xno],
+ [AC_CHECK_LIB([sqlite3], [sqlite3_open],
+ [AC_SUBST([sqlite3_LIBS], [-lsqlite3])],
+ [if test "x$enable_sqlite" != xcheck; then
+ AC_MSG_FAILURE([--enable-sqlite was given, but test for sqlite failed])
+ fi])])
AC_ARG_ENABLE([ssp],
[AC_HELP_STRING([--enable-ssp], [enable gcc stack-protector])])
@@ -122,6 +133,7 @@ if test $build_elfutils = no; then
AC_MSG_ERROR([missing elfutils development headers/libraries (dw 0.123+)])])
AC_CHECK_LIB(ebl, ebl_openbackend,,[
AC_MSG_ERROR([missing elfutils development headers/libraries (ebl 0.123+)])])
+
stap_LIBS="$LIBS"
LIBS="$SAVE_LIBS"
else
diff --git a/elaborate.cxx b/elaborate.cxx
index 0ac0f4da..39dae294 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -33,60 +33,49 @@ using namespace std;
// ------------------------------------------------------------------------
+// Used in probe_point condition construction. Either argument may be
+// NULL; if both, return NULL too. Resulting expression is a deep
+// copy for symbol resolution purposes.
+expression* add_condition (expression* a, expression* b)
+{
+ if (!a && !b) return 0;
+ if (! a) return deep_copy_visitor::deep_copy(b);
+ if (! b) return deep_copy_visitor::deep_copy(a);
+ logical_and_expr la;
+ la.op = "&&";
+ la.left = a;
+ la.right = b;
+ la.tok = a->tok; // or could be b->tok
+ return deep_copy_visitor::deep_copy(& la);
+}
+
+// ------------------------------------------------------------------------
+
+
derived_probe::derived_probe (probe *p):
base (p)
{
- if (p)
- {
- this->locations = p->locations;
- this->condition = deep_copy_visitor::deep_copy(p->condition);
- this->tok = p->tok;
- this->privileged = p->privileged;
- this->body = deep_copy_visitor::deep_copy(p->body);
- }
+ assert (p);
+ this->locations = p->locations;
+ this->tok = p->tok;
+ this->privileged = p->privileged;
+ this->body = deep_copy_visitor::deep_copy(p->body);
}
derived_probe::derived_probe (probe *p, probe_point *l):
base (p)
{
- if (p)
- {
- if (p->condition)
- this->condition = deep_copy_visitor::deep_copy(p->condition);
- this->tok = p->tok;
- this->privileged = p->privileged;
- this->body = deep_copy_visitor::deep_copy(p->body);
- }
+ assert (p);
+ this->tok = p->tok;
+ this->privileged = p->privileged;
+ this->body = deep_copy_visitor::deep_copy(p->body);
- if (l)
- {
- probe_point *pp = new probe_point (l->components, l->tok);
- this->locations.push_back (pp);
- this->add_condition (l->condition);
- this->insert_condition_statement ();
- }
+ assert (l);
+ this->locations.push_back (l);
}
-void
-derived_probe::insert_condition_statement (void)
-{
- if (this->condition)
- {
- if_statement *ifs = new if_statement ();
- ifs->tok = this->tok;
- ifs->thenblock = new next_statement ();
- ifs->thenblock->tok = this->tok;
- ifs->elseblock = NULL;
- unary_expression *notex = new unary_expression ();
- notex->op = "!";
- notex->tok = this->tok;
- notex->operand = this->condition;
- ifs->condition = notex;
- body->statements.insert (body->statements.begin(), ifs);
- }
-}
void
derived_probe::printsig (ostream& o) const
@@ -196,14 +185,14 @@ derived_probe_builder::has_null_param (std::map<std::string, literal*> const & p
match_key::match_key(string const & n)
: name(n),
have_parameter(false),
- parameter_type(tok_junk)
+ parameter_type(pe_unknown)
{
}
match_key::match_key(probe_point::component const & c)
: name(c.functor),
have_parameter(c.arg != NULL),
- parameter_type(c.arg ? c.arg->tok->type : tok_junk)
+ parameter_type(c.arg ? c.arg->type : pe_unknown)
{
}
@@ -211,7 +200,7 @@ match_key &
match_key::with_number()
{
have_parameter = true;
- parameter_type = tok_number;
+ parameter_type = pe_long;
return *this;
}
@@ -219,7 +208,7 @@ match_key &
match_key::with_string()
{
have_parameter = true;
- parameter_type = tok_string;
+ parameter_type = pe_string;
return *this;
}
@@ -229,8 +218,8 @@ match_key::str() const
if (have_parameter)
switch (parameter_type)
{
- case tok_string: return name + "(string)";
- case tok_number: return name + "(number)";
+ case pe_string: return name + "(string)";
+ case pe_long: return name + "(number)";
default: return name + "(...)";
}
return name;
@@ -371,6 +360,10 @@ match_node::find_and_build (systemtap_session& s,
non_wildcard_component->functor = subkey.name;
non_wildcard_pp->components[pos] = non_wildcard_component;
+ // NB: probe conditions are not attached at the wildcard
+ // (component/functor) level, but at the overall
+ // probe_point level.
+
// recurse (with the non-wildcard probe point)
try
{
@@ -439,7 +432,7 @@ match_node::build_no_more (systemtap_session& s)
struct alias_derived_probe: public derived_probe
{
- alias_derived_probe (probe* base): derived_probe (base) {}
+ alias_derived_probe (probe* base, probe_point *l): derived_probe (base, l) {}
void upchuck () { throw semantic_error ("inappropriate", this->tok); }
@@ -471,17 +464,18 @@ alias_expansion_builder
// alias_expansion_probe so that the expansion loop recognizes it as
// such and re-expands its expansion.
- probe * n = new alias_derived_probe (use);
+ alias_derived_probe * n = new alias_derived_probe (use, location /* soon overwritten */);
n->body = new block();
- // The new probe gets the location list of the alias,
+ // The new probe gets the location list of the alias (with incoming condition joined)
n->locations = alias->locations;
-
+ for (unsigned i=0; i<n->locations.size(); i++)
+ n->locations[i]->condition = add_condition (n->locations[i]->condition,
+ location->condition);
+
// the token location of the alias,
n->tok = location->tok;
n->body->tok = location->tok;
- // The new probe takes over condition.
- n->add_condition (location->condition);
// and statements representing the concatenation of the alias'
// body with the use's.
@@ -813,40 +807,6 @@ struct no_var_mutation_during_iteration_check
};
-static int
-semantic_pass_vars (systemtap_session & sess)
-{
-
- map<functiondecl *, set<vardecl *> *> fmv;
- no_var_mutation_during_iteration_check chk(sess, fmv);
-
- for (unsigned i = 0; i < sess.functions.size(); ++i)
- {
- functiondecl * fn = sess.functions[i];
- if (fn->body)
- {
- set<vardecl *> * m = new set<vardecl *>();
- mutated_var_collector mc (m);
- fn->body->visit (&mc);
- fmv[fn] = m;
- }
- }
-
- for (unsigned i = 0; i < sess.functions.size(); ++i)
- {
- if (sess.functions[i]->body)
- sess.functions[i]->body->visit (&chk);
- }
-
- for (unsigned i = 0; i < sess.probes.size(); ++i)
- {
- if (sess.probes[i]->body)
- sess.probes[i]->body->visit (&chk);
- }
-
- return sess.num_errors();
-}
-
// ------------------------------------------------------------------------
struct stat_decl_collector
@@ -950,6 +910,106 @@ semantic_pass_stats (systemtap_session & sess)
// ------------------------------------------------------------------------
+// Enforce variable-related invariants: no modification of
+// a foreach()-iterated array.
+static int
+semantic_pass_vars (systemtap_session & sess)
+{
+
+ map<functiondecl *, set<vardecl *> *> fmv;
+ no_var_mutation_during_iteration_check chk(sess, fmv);
+
+ for (unsigned i = 0; i < sess.functions.size(); ++i)
+ {
+ functiondecl * fn = sess.functions[i];
+ if (fn->body)
+ {
+ set<vardecl *> * m = new set<vardecl *>();
+ mutated_var_collector mc (m);
+ fn->body->visit (&mc);
+ fmv[fn] = m;
+ }
+ }
+
+ for (unsigned i = 0; i < sess.functions.size(); ++i)
+ {
+ if (sess.functions[i]->body)
+ sess.functions[i]->body->visit (&chk);
+ }
+
+ for (unsigned i = 0; i < sess.probes.size(); ++i)
+ {
+ if (sess.probes[i]->body)
+ sess.probes[i]->body->visit (&chk);
+ }
+
+ return sess.num_errors();
+}
+
+
+// ------------------------------------------------------------------------
+
+// Rewrite probe condition expressions into probe bodies. Tricky and
+// exciting business, this. This:
+//
+// probe foo if (g1 || g2) { ... }
+// probe bar { ... g1 ++ ... }
+//
+// becomes:
+//
+// probe begin(MAX) { if (! (g1 || g2)) %{ disable_probe_foo %} }
+// probe foo { if (! (g1 || g2)) next; ... }
+// probe bar { ... g1 ++ ...;
+// if (g1 || g2) %{ enable_probe_foo %} else %{ disable_probe_foo %}
+// }
+//
+// XXX: As a first cut, do only the "inline probe condition" part of the
+// transform.
+
+static int
+semantic_pass_conditions (systemtap_session & sess)
+{
+ for (unsigned i = 0; i < sess.probes.size(); ++i)
+ {
+ derived_probe* p = sess.probes[i];
+ expression* e = p->sole_location()->condition;
+ if (e)
+ {
+ varuse_collecting_visitor vut;
+ e->visit (& vut);
+
+ if (! vut.written.empty())
+ {
+ string err = ("probe condition must not modify any variables");
+ sess.print_error (semantic_error (err, e->tok));
+ }
+ else if (vut.embedded_seen)
+ {
+ sess.print_error (semantic_error ("probe condition must not include impure embedded-C", e->tok));
+ }
+
+ // Add the condition expression to the front of the
+ // derived_probe body.
+ if_statement *ifs = new if_statement ();
+ ifs->tok = e->tok;
+ ifs->thenblock = new next_statement ();
+ ifs->thenblock->tok = e->tok;
+ ifs->elseblock = NULL;
+ unary_expression *notex = new unary_expression ();
+ notex->op = "!";
+ notex->tok = e->tok;
+ notex->operand = e;
+ ifs->condition = notex;
+ p->body->statements.insert (p->body->statements.begin(), ifs);
+ }
+ }
+
+ return sess.num_errors();
+}
+
+
+// ------------------------------------------------------------------------
+
static int semantic_pass_symbols (systemtap_session&);
static int semantic_pass_optimize1 (systemtap_session&);
@@ -957,7 +1017,7 @@ static int semantic_pass_optimize2 (systemtap_session&);
static int semantic_pass_types (systemtap_session&);
static int semantic_pass_vars (systemtap_session&);
static int semantic_pass_stats (systemtap_session&);
-
+static int semantic_pass_conditions (systemtap_session&);
// Link up symbols to their declarations. Set the session's
@@ -1030,6 +1090,12 @@ semantic_pass_symbols (systemtap_session& s)
sym.current_function = 0;
sym.current_probe = dp;
dp->body->visit (& sym);
+
+ // Process the probe-point condition expression.
+ sym.current_function = 0;
+ sym.current_probe = 0;
+ if (dp->sole_location()->condition)
+ dp->sole_location()->condition->visit (& sym);
}
catch (const semantic_error& e)
{
@@ -1058,7 +1124,8 @@ semantic_pass (systemtap_session& s)
s.register_library_aliases();
register_standard_tapsets(s);
- rc = semantic_pass_symbols (s);
+ if (rc == 0) rc = semantic_pass_symbols (s);
+ if (rc == 0) rc = semantic_pass_conditions (s);
if (rc == 0 && ! s.unoptimized) rc = semantic_pass_optimize1 (s);
if (rc == 0) rc = semantic_pass_types (s);
if (rc == 0 && ! s.unoptimized) rc = semantic_pass_optimize2 (s);
@@ -1248,8 +1315,8 @@ symresolution_info::visit_symbol (symbol* e)
else if (current_probe)
current_probe->locals.push_back (v);
else
- // must not happen
- throw semantic_error ("no current probe/function", e->tok);
+ // must be probe-condition expression
+ throw semantic_error ("probe condition must not reference undeclared global", e->tok);
e->referent = v;
}
}
@@ -1301,6 +1368,14 @@ symresolution_info::visit_arrayindex (arrayindex* e)
void
symresolution_info::visit_functioncall (functioncall* e)
{
+ // XXX: we could relax this, if we're going to examine the
+ // vartracking data recursively. See testsuite/semko/fortytwo.stp.
+ if (! (current_function || current_probe))
+ {
+ // must be probe-condition expression
+ throw semantic_error ("probe condition must not reference function", e->tok);
+ }
+
for (unsigned i=0; i<e->args.size(); i++)
e->args[i]->visit (this);
@@ -1323,20 +1398,22 @@ symresolution_info::visit_functioncall (functioncall* e)
vardecl*
symresolution_info::find_var (const string& name, int arity)
{
-
- // search locals
- vector<vardecl*>& locals = (current_function ?
- current_function->locals :
- current_probe->locals);
-
-
- for (unsigned i=0; i<locals.size(); i++)
- if (locals[i]->name == name
- && locals[i]->compatible_arity(arity))
- {
- locals[i]->set_arity (arity);
- return locals[i];
- }
+ if (current_function || current_probe)
+ {
+ // search locals
+ vector<vardecl*>& locals = (current_function ?
+ current_function->locals :
+ current_probe->locals);
+
+
+ for (unsigned i=0; i<locals.size(); i++)
+ if (locals[i]->name == name
+ && locals[i]->compatible_arity(arity))
+ {
+ locals[i]->set_arity (arity);
+ return locals[i];
+ }
+ }
// search function formal parameters (for scalars)
if (arity == 0 && current_function)
@@ -1430,7 +1507,11 @@ void semantic_pass_opt1 (systemtap_session& s, bool& relaxed_p)
{
functioncall_traversing_visitor ftv;
for (unsigned i=0; i<s.probes.size(); i++)
- s.probes[i]->body->visit (& ftv);
+ {
+ s.probes[i]->body->visit (& ftv);
+ if (s.probes[i]->sole_location()->condition)
+ s.probes[i]->sole_location()->condition->visit (& ftv);
+ }
for (unsigned i=0; i<s.functions.size(); /* see below */)
{
if (ftv.traversed.find(s.functions[i]) == ftv.traversed.end())
@@ -1463,7 +1544,13 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
varuse_collecting_visitor vut;
for (unsigned i=0; i<s.probes.size(); i++)
- s.probes[i]->body->visit (& vut);
+ {
+ s.probes[i]->body->visit (& vut);
+
+ if (s.probes[i]->sole_location()->condition)
+ s.probes[i]->sole_location()->condition->visit (& vut);
+ }
+
// NB: Since varuse_collecting_visitor also traverses down
// actually called functions, we don't need to explicitly
// iterate over them. Uncalled ones should have been pruned
@@ -1985,6 +2072,15 @@ semantic_pass_types (systemtap_session& s)
ti.current_probe = pn;
ti.t = pe_unknown;
pn->body->visit (& ti);
+
+ probe_point* pp = pn->sole_location();
+ if (pp->condition)
+ {
+ ti.current_function = 0;
+ ti.current_probe = 0;
+ ti.t = pe_long; // NB: expected type
+ pp->condition->visit (& ti);
+ }
}
for (unsigned j=0; j<s.globals.size(); j++)
@@ -2853,7 +2949,7 @@ typeresolution_info::unresolved (const token* tok)
stringstream msg;
string nm = (current_function ? current_function->name :
current_probe ? current_probe->name :
- "?");
+ "probe condition");
msg << nm + " with unresolved type";
session.print_error (semantic_error (msg.str(), tok));
}
@@ -2870,7 +2966,7 @@ typeresolution_info::invalid (const token* tok, exp_type pe)
stringstream msg;
string nm = (current_function ? current_function->name :
current_probe ? current_probe->name :
- "?");
+ "probe condition");
if (tok && tok->type == tok_operator)
msg << nm + " uses invalid operator";
else
@@ -2890,7 +2986,7 @@ typeresolution_info::mismatch (const token* tok, exp_type t1, exp_type t2)
stringstream msg;
string nm = (current_function ? current_function->name :
current_probe ? current_probe->name :
- "?");
+ "probe condition");
msg << nm + " with type mismatch (" << t1 << " vs. " << t2 << ")";
session.print_error (semantic_error (msg.str(), tok));
}
diff --git a/elaborate.h b/elaborate.h
index 13246b86..5f396526 100644
--- a/elaborate.h
+++ b/elaborate.h
@@ -118,7 +118,6 @@ struct derived_probe: public probe
virtual probe_point* sole_location () const;
virtual void printsig (std::ostream &o) const;
void printsig_nested (std::ostream &o) const;
- void insert_condition_statement (void);
virtual void collect_derivation_chain (std::vector<derived_probe*> &probes_list);
virtual void emit_probe_context_vars (translator_output*) {}
@@ -197,7 +196,7 @@ match_key
{
std::string name;
bool have_parameter;
- token_type parameter_type;
+ exp_type parameter_type;
match_key(std::string const & n);
match_key(probe_point::component const & c);
diff --git a/runtime/autoconf-nameidata.c b/runtime/autoconf-nameidata.c
new file mode 100644
index 00000000..c1d02400
--- /dev/null
+++ b/runtime/autoconf-nameidata.c
@@ -0,0 +1,4 @@
+#include <linux/namei.h>
+
+struct nameidata nd __attribute__ ((unused)) = {.path={(void *)0}};
+
diff --git a/runtime/autoconf-x86-uniregs.c b/runtime/autoconf-x86-uniregs.c
new file mode 100644
index 00000000..25729c22
--- /dev/null
+++ b/runtime/autoconf-x86-uniregs.c
@@ -0,0 +1,6 @@
+#include <asm/ptrace.h>
+
+#if defined (__i386__) || defined (__x86_64__)
+struct pt_regs regs = {.ax = 0x0};
+#endif
+
diff --git a/runtime/loc2c-runtime.h b/runtime/loc2c-runtime.h
index 8dbff764..4674e399 100644
--- a/runtime/loc2c-runtime.h
+++ b/runtime/loc2c-runtime.h
@@ -75,7 +75,37 @@
})
-#if defined __i386__
+#if defined (STAPCONF_X86_UNIREGS) && defined (__i386__)
+
+#define dwarf_register_0(regs) regs->ax
+#define dwarf_register_1(regs) regs->cx
+#define dwarf_register_2(regs) regs->dx
+#define dwarf_register_3(regs) regs->bx
+#define dwarf_register_4(regs) ((long) &regs->sp)
+#define dwarf_register_5(regs) regs->bp
+#define dwarf_register_6(regs) regs->si
+#define dwarf_register_7(regs) regs->di
+
+#elif defined (STAPCONF_X86_UNIREGS) && defined (__x86_64__)
+
+#define dwarf_register_0(regs) regs->ax
+#define dwarf_register_1(regs) regs->dx
+#define dwarf_register_2(regs) regs->cx
+#define dwarf_register_3(regs) regs->bx
+#define dwarf_register_4(regs) regs->si
+#define dwarf_register_5(regs) regs->di
+#define dwarf_register_6(regs) regs->bp
+#define dwarf_register_7(regs) regs->sp
+#define dwarf_register_8(regs) regs->r8
+#define dwarf_register_9(regs) regs->r9
+#define dwarf_register_10(regs) regs->r10
+#define dwarf_register_11(regs) regs->r11
+#define dwarf_register_12(regs) regs->r12
+#define dwarf_register_13(regs) regs->r13
+#define dwarf_register_14(regs) regs->r14
+#define dwarf_register_15(regs) regs->r15
+
+#elif defined __i386__
/* The stack pointer is unlike other registers. When a trap happens in
kernel mode, it is not saved in the trap frame (struct pt_regs).
diff --git a/runtime/procfs.c b/runtime/procfs.c
index eb0f845c..1b1d5447 100644
--- a/runtime/procfs.c
+++ b/runtime/procfs.c
@@ -87,8 +87,14 @@ int _stp_mkdir_proc_module(void)
goto done;
}
} else {
+ #ifdef STAPCONF_NAMEIDATA_CLEANUP
+ _stp_proc_stap = PDE(nd.path.dentry->d_inode);
+ path_put (&nd.path);
+
+ #else
_stp_proc_stap = PDE(nd.dentry->d_inode);
path_release (&nd);
+ #endif
}
_stp_proc_root = proc_mkdir(THIS_MODULE->name, _stp_proc_stap);
diff --git a/runtime/regs.c b/runtime/regs.c
index bc717695..5e08e376 100644
--- a/runtime/regs.c
+++ b/runtime/regs.c
@@ -33,7 +33,13 @@
unsigned long _stp_ret_addr (struct pt_regs *regs)
{
-#ifdef __x86_64__
+#if defined (STAPCONF_X86_UNIREGS) && (defined (__x86_64__) || defined (__i386__))
+ unsigned long *ra = (unsigned long *)regs->sp;
+ if (ra)
+ return *ra;
+ else
+ return 0;
+#elif defined (__x86_64__)
unsigned long *ra = (unsigned long *)regs->rsp;
if (ra)
return *ra;
@@ -77,7 +83,76 @@ unsigned long _stp_ret_addr (struct pt_regs *regs)
*/
#define _stp_probe_addr_r(ri) (ri->rp->kp.addr)
-#ifdef __x86_64__
+#if defined (STAPCONF_X86_UNIREGS) && defined (__x86_64__)
+
+void _stp_print_regs(struct pt_regs * regs)
+{
+ unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
+ unsigned int fsindex,gsindex;
+ unsigned int ds,cs,es;
+
+ _stp_printf("RIP: %016lx\nRSP: %016lx EFLAGS: %08lx\n", regs->ip, regs->sp, regs->flags);
+ _stp_printf("RAX: %016lx RBX: %016lx RCX: %016lx\n",
+ regs->ax, regs->bx, regs->cx);
+ _stp_printf("RDX: %016lx RSI: %016lx RDI: %016lx\n",
+ regs->dx, regs->si, regs->di);
+ _stp_printf("RBP: %016lx R08: %016lx R09: %016lx\n",
+ regs->bp, regs->r8, regs->r9);
+ _stp_printf("R10: %016lx R11: %016lx R12: %016lx\n",
+ regs->r10, regs->r11, regs->r12);
+ _stp_printf("R13: %016lx R14: %016lx R15: %016lx\n",
+ regs->r13, regs->r14, regs->r15);
+
+ asm("movl %%ds,%0" : "=r" (ds));
+ asm("movl %%cs,%0" : "=r" (cs));
+ asm("movl %%es,%0" : "=r" (es));
+ asm("movl %%fs,%0" : "=r" (fsindex));
+ asm("movl %%gs,%0" : "=r" (gsindex));
+
+ rdmsrl(MSR_FS_BASE, fs);
+ rdmsrl(MSR_GS_BASE, gs);
+ rdmsrl(MSR_KERNEL_GS_BASE, shadowgs);
+
+ asm("movq %%cr0, %0": "=r" (cr0));
+ asm("movq %%cr2, %0": "=r" (cr2));
+ asm("movq %%cr3, %0": "=r" (cr3));
+ asm("movq %%cr4, %0": "=r" (cr4));
+
+ _stp_printf("FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
+ fs,fsindex,gs,gsindex,shadowgs);
+ _stp_printf("CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0);
+ _stp_printf("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4);
+}
+
+ #elif defined (STAPCONF_X86_UNIREGS) && defined (__i386__)
+
+void _stp_print_regs(struct pt_regs * regs)
+{
+ unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
+
+ _stp_printf ("EIP: %08lx\n",regs->ip);
+ _stp_printf ("ESP: %08lx\n",regs->sp);
+ _stp_printf ("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
+ regs->ax,regs->bx,regs->cx,regs->dx);
+ _stp_printf ("ESI: %08lx EDI: %08lx EBP: %08lx",
+ regs->si, regs->di, regs->bp);
+ _stp_printf (" DS: %04x ES: %04x\n",
+ 0xffff & regs->ds,0xffff & regs->es);
+
+ __asm__("movl %%cr0, %0": "=r" (cr0));
+ __asm__("movl %%cr2, %0": "=r" (cr2));
+ __asm__("movl %%cr3, %0": "=r" (cr3));
+ /* This could fault if %cr4 does not exist */
+ __asm__("1: movl %%cr4, %0 \n"
+ "2: \n"
+ ".section __ex_table,\"a\" \n"
+ ".long 1b,2b \n"
+ ".previous \n"
+ : "=r" (cr4): "0" (0));
+ _stp_printf ("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
+}
+
+#elif defined (__x86_64__)
void _stp_print_regs(struct pt_regs * regs)
{
unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
diff --git a/runtime/regs.h b/runtime/regs.h
index 0887d628..c1e2344b 100644
--- a/runtime/regs.h
+++ b/runtime/regs.h
@@ -11,8 +11,11 @@
#ifndef _REGS_H_ /* -*- linux-c -*- */
#define _REGS_H_
+#if defined (STAPCONF_X86_UNIREGS) && (defined (__x86_64__) || defined (__i386__))
+#define REG_IP(regs) regs->ip
+#define REG_SP(regs) regs->sp
-#ifdef __x86_64__
+#elif defined (__x86_64__)
#define REG_IP(regs) regs->rip
#define REG_SP(regs) regs->rsp
diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c
index 3675fc97..d73f4c84 100644
--- a/runtime/stack-i386.c
+++ b/runtime/stack-i386.c
@@ -21,7 +21,11 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels)
#ifdef CONFIG_FRAME_POINTER
{
+ #ifdef STAPCONF_X86_UNIREGS
+ unsigned long ebp = regs->bp;
+ #elif
unsigned long ebp = regs->ebp;
+ #endif
while (_stp_valid_stack_ptr(context, (unsigned long)ebp)) {
addr = *(unsigned long *)(ebp + 4);
diff --git a/runtime/staprun/ChangeLog b/runtime/staprun/ChangeLog
index 3f373863..53545db2 100644
--- a/runtime/staprun/ChangeLog
+++ b/runtime/staprun/ChangeLog
@@ -1,3 +1,8 @@
+2008-01-21 Martin Hunt <hunt@redhat.com>
+
+ * symbols.c (send_module): Simplify and use new send_data() function to keep
+ longword alignment.
+
2008-01-14 Martin Hunt <hunt@redhat.com>
PR4037 and fixes to better synchronize staprun and stapio.
diff --git a/runtime/staprun/staprun_funcs.c b/runtime/staprun/staprun_funcs.c
index ebf05b34..d1bba3f8 100644
--- a/runtime/staprun/staprun_funcs.c
+++ b/runtime/staprun/staprun_funcs.c
@@ -16,8 +16,6 @@
#include <grp.h>
#include <pwd.h>
-void cleanup(int rc);
-
void setup_staprun_signals(void)
{
struct sigaction a;
diff --git a/runtime/staprun/symbols.c b/runtime/staprun/symbols.c
index 5a4855b3..e33ee624 100644
--- a/runtime/staprun/symbols.c
+++ b/runtime/staprun/symbols.c
@@ -12,9 +12,8 @@
#include "staprun.h"
/* send symbol data */
-static int send_data(void *data, int len)
+static int send_data(int32_t type, void *data, int len)
{
- int32_t type = STP_SYMBOLS;
if (write(control_channel, &type, 4) <= 0)
return -1;
return write(control_channel, data, len);
@@ -158,11 +157,9 @@ static int send_module (char *mname)
{
char data[65536];
int len;
- *(int32_t *)data = STP_MODULE;
- len = get_sections(mname, data + sizeof(int32_t),
- sizeof(data) - sizeof(int32_t));
+ len = get_sections(mname, data, sizeof(data));
if (len > 0) {
- if (write(control_channel, data, len + sizeof(int32_t)) <= 0) {
+ if (send_data(STP_MODULE, data, len) < 0) {
_err("Loading of module %s failed. Exiting...\n", mname);
return -1;
}
@@ -296,11 +293,11 @@ int do_kernel_symbols(void)
goto err;
/* send syms */
- if (send_data(syms, num_syms*struct_symbol_size) < 0)
+ if (send_data(STP_SYMBOLS, syms, num_syms*struct_symbol_size) < 0)
goto err;
/* send data */
- if (send_data(data_base, dataptr-data_base) < 0)
+ if (send_data(STP_SYMBOLS, data_base, dataptr-data_base) < 0)
goto err;
free(data_base);
diff --git a/runtime/uprobes/uprobes.c b/runtime/uprobes/uprobes.c
index 50930709..501c4298 100644
--- a/runtime/uprobes/uprobes.c
+++ b/runtime/uprobes/uprobes.c
@@ -42,8 +42,14 @@
#define MAX_SSOL_SLOTS 1024
+#ifdef NO_ACCESS_PROCESS_VM_EXPORT
+static int __access_process_vm(struct task_struct *tsk, unsigned long addr,
+ void *buf, int len, int write);
+#define access_process_vm __access_process_vm
+#else
extern int access_process_vm(struct task_struct *tsk, unsigned long addr,
void *buf, int len, int write);
+#endif
static int utask_fake_quiesce(struct uprobe_task *utask);
static void uprobe_release_ssol_vma(struct uprobe_process *uproc);
@@ -1601,7 +1607,7 @@ static u32 uprobe_report_signal(struct utrace_attached_engine *engine,
int hit_uretprobe_trampoline = 0;
int registrations_deferred = 0;
- utask = rcu_dereference((struct uprobe_task *)engine->data);
+ utask = (struct uprobe_task *)rcu_dereference(engine->data);
BUG_ON(!utask);
if (info->si_signo != BREAKPOINT_SIGNAL &&
@@ -1785,7 +1791,7 @@ static u32 uprobe_report_quiesce(struct utrace_attached_engine *engine,
struct uprobe_task *utask;
struct uprobe_process *uproc;
- utask = rcu_dereference((struct uprobe_task *)engine->data);
+ utask = (struct uprobe_task *)rcu_dereference(engine->data);
BUG_ON(!utask);
uproc = utask->uproc;
if (current == utask->quiesce_master) {
@@ -1886,7 +1892,7 @@ static u32 uprobe_report_exit(struct utrace_attached_engine *engine,
struct uprobe_probept *ppt;
int utask_quiescing;
- utask = rcu_dereference((struct uprobe_task *)engine->data);
+ utask = (struct uprobe_task *)rcu_dereference(engine->data);
uproc = utask->uproc;
uprobe_get_process(uproc);
@@ -1965,7 +1971,7 @@ static u32 uprobe_report_clone(struct utrace_attached_engine *engine,
struct uprobe_process *uproc;
struct uprobe_task *ptask, *ctask;
- ptask = rcu_dereference((struct uprobe_task *)engine->data);
+ ptask = (struct uprobe_task *)rcu_dereference(engine->data);
uproc = ptask->uproc;
/*
@@ -2054,7 +2060,7 @@ static u32 uprobe_report_exec(struct utrace_attached_engine *engine,
struct uprobe_task *utask;
int uproc_freed;
- utask = rcu_dereference((struct uprobe_task *)engine->data);
+ utask = (struct uprobe_task *)rcu_dereference(engine->data);
uproc = utask->uproc;
uprobe_get_process(uproc);
@@ -2267,5 +2273,61 @@ static void zap_uretprobe_instances(struct uprobe *u,
}
#endif /* CONFIG_URETPROBES */
+#ifdef NO_ACCESS_PROCESS_VM_EXPORT
+/*
+ * Some kernel versions export everything that uprobes.ko needs except
+ * access_process_vm, so we copied and pasted it here. Fortunately,
+ * everything it calls is exported.
+ */
+#include <linux/pagemap.h>
+#include <asm/cacheflush.h>
+static int __access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
+{
+ struct mm_struct *mm;
+ struct vm_area_struct *vma;
+ struct page *page;
+ void *old_buf = buf;
+
+ mm = get_task_mm(tsk);
+ if (!mm)
+ return 0;
+
+ down_read(&mm->mmap_sem);
+ /* ignore errors, just check how much was sucessfully transfered */
+ while (len) {
+ int bytes, ret, offset;
+ void *maddr;
+
+ ret = get_user_pages(tsk, mm, addr, 1,
+ write, 1, &page, &vma);
+ if (ret <= 0)
+ break;
+
+ bytes = len;
+ offset = addr & (PAGE_SIZE-1);
+ if (bytes > PAGE_SIZE-offset)
+ bytes = PAGE_SIZE-offset;
+
+ maddr = kmap(page);
+ if (write) {
+ copy_to_user_page(vma, page, addr,
+ maddr + offset, buf, bytes);
+ set_page_dirty_lock(page);
+ } else {
+ copy_from_user_page(vma, page, addr,
+ buf, maddr + offset, bytes);
+ }
+ kunmap(page);
+ page_cache_release(page);
+ len -= bytes;
+ buf += bytes;
+ addr += bytes;
+ }
+ up_read(&mm->mmap_sem);
+ mmput(mm);
+
+ return buf - old_buf;
+}
+#endif
#include "uprobes_arch.c"
MODULE_LICENSE("GPL");
diff --git a/stap.1.in b/stap.1.in
index 16a799cf..05eecda2 100644
--- a/stap.1.in
+++ b/stap.1.in
@@ -932,7 +932,14 @@ The location of kernel module building infrastructure.
@prefix@/lib/debug/lib/modules/VERSION
The location of kernel debugging information when packaged into the
.IR kernel\-debuginfo
-RPM.
+RPM, unless overridden by the
+.I SYSTEMTAP_DEBUGINFO_PATH
+environment variable. The default value for this variable is
+.IR \-:.debug:/usr/lib/debug .
+This path is interpreted by elfutils as a list of base directories of
+which various subdirectories will be searched. The \- at the front
+means to skip CRC matching for separated debug objects and is a small
+performance win if no possible corruption is suspected.
.TP
@prefix@/bin/staprun
The auxiliary program supervising module loading, interaction, and
diff --git a/staptree.cxx b/staptree.cxx
index 8cd9ca83..173314ee 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -18,6 +18,7 @@
#include <cstring>
#include <vector>
#include <algorithm>
+#include <cstring>
using namespace std;
@@ -89,7 +90,7 @@ probe_point::probe_point ():
unsigned probe::last_probeidx = 0;
probe::probe ():
- body (0), tok (0), condition (0)
+ body (0), tok (0)
{
this->name = string ("probe_") + lex_cast<string>(last_probeidx ++);
}
@@ -899,26 +900,6 @@ probe::collect_derivation_chain (std::vector<derived_probe*> &probes_list)
probes_list.push_back((derived_probe*)this);
}
-void
-probe::add_condition (expression* e)
-{
- if (e)
- {
- if (this->condition)
- {
- logical_and_expr *la = new logical_and_expr ();
- la->op = "&&";
- la->left = this->condition;
- la->right = e;
- la->tok = e->tok;
- this->condition = la;
- }
- else
- {
- this->condition = e;
- }
- }
-}
void probe_point::print (ostream& o) const
{
@@ -2390,3 +2371,30 @@ deep_copy_visitor::deep_copy (expression* s)
require <expression*> (&v, &n, s);
return n;
}
+
+template <> void
+require <indexable *> (deep_copy_visitor* v, indexable** dst, indexable* src)
+{
+ if (src != NULL)
+ {
+ symbol *array_src=NULL, *array_dst=NULL;
+ hist_op *hist_src=NULL, *hist_dst=NULL;
+
+ classify_indexable(src, array_src, hist_src);
+
+ *dst = NULL;
+
+ if (array_src)
+ {
+ require <symbol*> (v, &array_dst, array_src);
+ *dst = array_dst;
+ }
+ else
+ {
+ require <hist_op*> (v, &hist_dst, hist_src);
+ *dst = hist_dst;
+ }
+ assert (*dst);
+ }
+}
+
diff --git a/staptree.h b/staptree.h
index a1a5ebd2..5b4b56cd 100644
--- a/staptree.h
+++ b/staptree.h
@@ -591,10 +591,8 @@ struct probe
const token* tok;
std::vector<vardecl*> locals;
std::vector<vardecl*> unused_locals;
- expression* condition;
probe ();
void print (std::ostream& o) const;
- void add_condition (expression* e);
virtual void printsig (std::ostream &o) const;
virtual void collect_derivation_chain (std::vector<derived_probe*> &probes_list);
virtual probe* basest () { return this; }
@@ -848,31 +846,8 @@ require (deep_copy_visitor* v, T* dst, T src)
}
}
-template <> static void
-require <indexable *> (deep_copy_visitor* v, indexable** dst, indexable* src)
-{
- if (src != NULL)
- {
- symbol *array_src=NULL, *array_dst=NULL;
- hist_op *hist_src=NULL, *hist_dst=NULL;
-
- classify_indexable(src, array_src, hist_src);
-
- *dst = NULL;
-
- if (array_src)
- {
- require <symbol*> (v, &array_dst, array_src);
- *dst = array_dst;
- }
- else
- {
- require <hist_op*> (v, &hist_dst, hist_src);
- *dst = hist_dst;
- }
- assert (*dst);
- }
-}
+template <> void
+require <indexable *> (deep_copy_visitor* v, indexable** dst, indexable* src);
template <typename T> void
provide (deep_copy_visitor* v, T src)
diff --git a/systemtap.spec.in b/systemtap.spec.in
index 21acffc0..e2f93056 100644
--- a/systemtap.spec.in
+++ b/systemtap.spec.in
@@ -1,5 +1,5 @@
# Release number for rpm build. Stays at 1 for new PACKAGE_VERSION increases.
-%define release 2
+%define release 1
# Version number of oldest elfutils release that works with systemtap.
%define elfutils_version 0.127
@@ -51,6 +51,9 @@ BuildRequires: libcap-devel
BuildRequires: sqlite-devel
Requires: sqlite
%endif
+%if "%rhel" >= "5"
+BuildRequires: crash-devel
+%endif
# Requires: kernel-devel
# or is that kernel-smp-devel? kernel-hugemem-devel?
Requires: gcc make
@@ -124,9 +127,11 @@ cd ..
%define elfutils_mflags LD_LIBRARY_PATH=`pwd`/lib-elfutils
%endif
+# Enable/disable the sqlite coverage testing support
%if %{sqlite}
-# Include the coverage testing support
-%define sqlite_config --enable-sqlitedb
+%define sqlite_config --enable-sqlite
+%else
+%define sqlite_config --disable-sqlite
%endif
%configure %{?elfutils_config} %{?sqlite_config}
@@ -197,6 +202,10 @@ exit 0
%changelog
+* Fri Jan 18 2008 Frank Ch. Eigler <fche@redhat.com> - 0.6.1-1
+- Add crash-devel buildreq to build staplog.so crash(8) module.
+- Many robustness & functionality improvements:
+
* Wed Dec 5 2007 Will Cohen <wcohen@redhat.com> - 0.6-2
- Correct Source to point to location contain code.
diff --git a/tapset/ChangeLog b/tapset/ChangeLog
index a7f8fdf8..f617b331 100644
--- a/tapset/ChangeLog
+++ b/tapset/ChangeLog
@@ -1,3 +1,10 @@
+2008-01-23 Masami Hiramatsu <mhiramat@redhat.com>
+
+ PR5554
+ * syscalls.stp (__is_user_regs): Add new function to check whether
+ pt_regs is user mode registers.
+ (syscall.fork): Use __is_user_regs() to decide syscall name.
+
2008-01-16 Eugene Teo <eteo@redhat.com>
* signal.stp (get_sa_flags, get_sa_handler): New functions to
diff --git a/tapset/syscalls.stp b/tapset/syscalls.stp
index 500aff1a..3a239245 100644
--- a/tapset/syscalls.stp
+++ b/tapset/syscalls.stp
@@ -848,6 +848,37 @@ probe syscall.flock.return = kernel.function("sys_flock").return {
retstr = returnstr(1)
}
+function __is_user_regs:long (regs:long) %{ /* pure */
+ struct pt_regs * regs = (void *)((unsigned long)THIS->regs);
+/* copied from asm/ptrace.h */
+#if defined(__i386__)
+#ifdef STAPCONF_X86_UNIREGS
+ int cs = kread(&regs->cs);
+#else
+ int cs = kread(&regs->xcs);
+#endif
+ THIS->__retvalue = ((cs & SEGMENT_RPL_MASK) == USER_RPL);
+#elif defined(__x86_64__)
+ unsigned long cs = kread(&regs->cs);
+ THIS->__retvalue = (!!((cs & 3)));
+#elif defined(__ia64__)
+ unsigned long psr = kread(&regs->cr_ipsr);
+ THIS->__retvalue = (((struct ia64_psr *) &psr)->cpl != 0);
+#elif defined(__powerpc64__)
+ unsigned long msr = kread(&regs->msr);
+ THIS->__retvalue = ((msr >> MSR_PR_LG) & 0x1);
+#elif defined(__arm__)
+ long cpsr = kread(&regs->ARM_cpsr);
+ THIS->__retvalue = ((cpsr & 0xf) == 0);
+#elif defined(__s390__) || defined(__s390x__)
+ unsigned long mask = kread(&regs->psw.mask);
+ THIS->__retvalue = ((mask & PSW_MASK_PSTATE) != 0);
+#else
+#error "Unimplemented architecture"
+#endif
+CATCH_DEREF_FAULT();
+%}
+
# fork _______________________________________________________
# long do_fork(unsigned long clone_flags,
# unsigned long stack_start,
@@ -863,7 +894,7 @@ probe syscall.fork = kernel.function("do_fork") {
parent_tid_uaddr = $parent_tidptr
child_tid_uaddr = $child_tidptr
- if (stack_start == 0) {
+ if (!__is_user_regs(regs)) {
name = "fork_kernel_thread"
argstr = __fork_flags(clone_flags)
} else if (clone_flags == 17)
diff --git a/tapsets.cxx b/tapsets.cxx
index 84187960..06aa73aa 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -716,7 +716,10 @@ struct dwflpp
{
// XXX: this is where the session -R parameter could come in
static char debuginfo_path_arr[] = "-:.debug:/usr/lib/debug";
- static char *debuginfo_path = debuginfo_path_arr;
+ static char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH");
+
+ static char *debuginfo_path = (debuginfo_env_arr ?
+ debuginfo_env_arr : debuginfo_path_arr);
static const Dwfl_Callbacks proc_callbacks =
{
@@ -3632,7 +3635,7 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
Dwarf_Addr addr,
dwarf_query& q,
Dwarf_Die* scope_die /* may be null */)
- : derived_probe (q.base_probe, 0 /* location-less */),
+ : derived_probe (q.base_probe, q.base_loc /* NB: base_loc.components will be overwritten */ ),
module (module), section (section), addr (addr),
has_return (q.has_return),
has_maxactive (q.has_maxactive),
@@ -3644,14 +3647,8 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
if (section != "" && dwfl_addr == addr) // addr should be an offset
throw semantic_error ("inconsistent relocation address", q.base_loc->tok);
-
this->tok = q.base_probe->tok;
- // add condition from base location
- if (q.base_loc->condition)
- add_condition (q.base_loc->condition);
- insert_condition_statement ();
-
// Make a target-variable-expanded copy of the probe body
if (scope_die)
{
@@ -3674,7 +3671,7 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
}
// else - null scope_die - $target variables will produce an error during translate phase
- // Set the sole element of the "locations" vector as a
+ // Reset the sole element of the "locations" vector as a
// "reverse-engineered" form of the incoming (q.base_loc) probe
// point. This allows a user to see what function / file / line
// number any particular match of the wildcards.
@@ -3727,7 +3724,8 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
comps.push_back (new probe_point::component
(TOK_MAXACTIVE, new literal_number(maxactive_val)));
- locations.push_back(new probe_point(comps, q.base_loc->tok));
+ // Overwrite it.
+ this->sole_location()->components = comps;
}
@@ -4578,6 +4576,8 @@ procfs_derived_probe_group::enroll (procfs_derived_probe* p)
throw semantic_error("only one write procfs probe can exist for procfs path \"" + p->path + "\"");
else if (! p->write && pset->read_probe != NULL)
throw semantic_error("only one read procfs probe can exist for procfs path \"" + p->path + "\"");
+
+ // XXX: multiple writes should be acceptable
}
if (p->write)
@@ -4970,7 +4970,7 @@ struct mark_derived_probe: public derived_probe
{
mark_derived_probe (systemtap_session &s,
const string& probe_name, const string& probe_sig,
- probe* base_probe, expression* cond);
+ probe* base_probe, probe_point* location);
systemtap_session& sess;
string probe_name, probe_sig;
@@ -5121,24 +5121,15 @@ mark_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e)
mark_derived_probe::mark_derived_probe (systemtap_session &s,
const string& p_n,
const string& p_s,
- probe* base, expression* cond):
- derived_probe (base, 0), sess (s), probe_name (p_n), probe_sig (p_s),
+ probe* base, probe_point* loc):
+ derived_probe (base, loc), sess (s), probe_name (p_n), probe_sig (p_s),
target_symbol_seen (false)
{
- // create synthetic probe point
- probe_point* pp = new probe_point;
-
- probe_point::component* c;
- c = new probe_point::component ("kernel");
- pp->components.push_back (c);
- c = new probe_point::component ("mark",
- new literal_string (probe_name));
- pp->components.push_back (c);
- this->locations.push_back (pp);
-
- if (cond)
- add_condition (cond);
- insert_condition_statement ();
+ // create synthetic probe point name; preserve condition
+ vector<probe_point::component*> comps;
+ comps.push_back (new probe_point::component ("kernel"));
+ comps.push_back (new probe_point::component ("mark", new literal_string (probe_name)));
+ this->sole_location()->components = comps;
// expand the signature string
parse_probe_sig();
@@ -5543,7 +5534,7 @@ mark_builder::build(systemtap_session & sess,
derived_probe *dp
= new mark_derived_probe (sess,
it->first, it->second,
- base, loc->condition);
+ base, loc);
finished_results.push_back (dp);
}
}
diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog
index 6dd0d8de..f30b9891 100644
--- a/testsuite/ChangeLog
+++ b/testsuite/ChangeLog
@@ -1,3 +1,29 @@
+2008-01-24 Frank Ch. Eigler <fche@elastic.org>
+
+ crash(8) tests, based on Masami Hiramatsu <mhiramat@redhat.com>:
+ * Makefile.am (CRASH_LIBDIR): Pass in $(RUNTEST).
+ * lib/systemtap.exp (as_root): Trace command string, output, and
+ result.
+ * sysetmtap.samples/crash.*, testlog.stp: New test case.
+ * Makefile.in: Regenerated.
+
+2008-01-23 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 2521.
+ * systemtap.base/debugpath.exp: New test.
+
+2008-01-18 Frank Ch. Eigler <fche@elastic.org>
+
+ * configure.ac: Bump version to 0.6.1.
+ * configure: Regenerated.
+
+2008-01-17 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 4935.
+ * semko/forty.stp, fortyone.stp, fortytwo.stp: New tests.
+ * semok/twentynine.stp: Weaken test since condition expressions have
+ become more tightly constrained.
+
2008-01-17 David Smith <dsmith@redhat.com>
* semko/procfs11.stp: Added test for invalid use of procfs probe
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 689ec371..6b14bd60 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -27,6 +27,7 @@ EXTRA_DIST = config lib systemtap \
SYSTEMTAP_RUNTIME=$(DESTDIR)$(pkgdatadir)/runtime
SYSTEMTAP_TAPSET=$(DESTDIR)$(pkgdatadir)/tapset
LD_LIBRARY_PATH=$(DESTDIR)$(libdir)/systemtap
+CRASH_LIBDIR=$(DESTDIR)$(libdir)/systemtap
SYSTEMTAP_PATH=$(DESTDIR)$(bindir)
-RUNTEST="env SYSTEMTAP_RUNTIME=$(SYSTEMTAP_RUNTIME) SYSTEMTAP_TAPSET=$(SYSTEMTAP_TAPSET) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) PATH=$(SYSTEMTAP_PATH):$$PATH runtest"
+RUNTEST="env SYSTEMTAP_RUNTIME=$(SYSTEMTAP_RUNTIME) SYSTEMTAP_TAPSET=$(SYSTEMTAP_TAPSET) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) CRASH_LIBDIR=$(CRASH_LIBDIR) PATH=$(SYSTEMTAP_PATH):$$PATH runtest"
diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in
index 3f2db011..8907c519 100644
--- a/testsuite/Makefile.in
+++ b/testsuite/Makefile.in
@@ -36,7 +36,8 @@ DIST_COMMON = $(am__configure_deps) $(srcdir)/../install-sh \
$(srcdir)/../missing $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(top_srcdir)/configure ../AUTHORS \
../COPYING ../ChangeLog ../INSTALL ../NEWS ../README \
- ../compile ../depcomp ../install-sh ../missing ChangeLog
+ ../compile ../config.guess ../depcomp ../install-sh ../missing \
+ ChangeLog
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -146,8 +147,9 @@ EXTRA_DIST = config lib systemtap \
SYSTEMTAP_RUNTIME = $(DESTDIR)$(pkgdatadir)/runtime
SYSTEMTAP_TAPSET = $(DESTDIR)$(pkgdatadir)/tapset
LD_LIBRARY_PATH = $(DESTDIR)$(libdir)/systemtap
+CRASH_LIBDIR = $(DESTDIR)$(libdir)/systemtap
SYSTEMTAP_PATH = $(DESTDIR)$(bindir)
-RUNTEST = "env SYSTEMTAP_RUNTIME=$(SYSTEMTAP_RUNTIME) SYSTEMTAP_TAPSET=$(SYSTEMTAP_TAPSET) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) PATH=$(SYSTEMTAP_PATH):$$PATH runtest"
+RUNTEST = "env SYSTEMTAP_RUNTIME=$(SYSTEMTAP_RUNTIME) SYSTEMTAP_TAPSET=$(SYSTEMTAP_TAPSET) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) CRASH_LIBDIR=$(CRASH_LIBDIR) PATH=$(SYSTEMTAP_PATH):$$PATH runtest"
all: all-am
.SUFFIXES:
diff --git a/testsuite/configure b/testsuite/configure
index e50dc588..2e29a3d7 100755
--- a/testsuite/configure
+++ b/testsuite/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for systemtap 0.6.
+# Generated by GNU Autoconf 2.61 for systemtap 0.6.1.
#
# Report bugs to <systemtap@sources.redhat.com>.
#
@@ -574,8 +574,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='systemtap'
PACKAGE_TARNAME='systemtap'
-PACKAGE_VERSION='0.6'
-PACKAGE_STRING='systemtap 0.6'
+PACKAGE_VERSION='0.6.1'
+PACKAGE_STRING='systemtap 0.6.1'
PACKAGE_BUGREPORT='systemtap@sources.redhat.com'
ac_subst_vars='SHELL
@@ -1148,7 +1148,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures systemtap 0.6 to adapt to many kinds of systems.
+\`configure' configures systemtap 0.6.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1214,7 +1214,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of systemtap 0.6:";;
+ short | recursive ) echo "Configuration of systemtap 0.6.1:";;
esac
cat <<\_ACEOF
@@ -1285,7 +1285,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-systemtap configure 0.6
+systemtap configure 0.6.1
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1299,7 +1299,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by systemtap $as_me 0.6, which was
+It was created by systemtap $as_me 0.6.1, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
@@ -1991,7 +1991,7 @@ fi
# Define the identity of the package.
PACKAGE='systemtap'
- VERSION='0.6'
+ VERSION='0.6.1'
cat >>confdefs.h <<_ACEOF
@@ -2595,7 +2595,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by systemtap $as_me 0.6, which was
+This file was extended by systemtap $as_me 0.6.1, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -2638,7 +2638,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-systemtap config.status 0.6
+systemtap config.status 0.6.1
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
diff --git a/testsuite/configure.ac b/testsuite/configure.ac
index 18e85559..5eb9b151 100644
--- a/testsuite/configure.ac
+++ b/testsuite/configure.ac
@@ -1,7 +1,7 @@
dnl configure.ac --- autoconf input file for systemtap testsuite
dnl Process this file with autoconf to produce a configure script.
-AC_INIT([systemtap], 0.6, systemtap@sources.redhat.com, systemtap)
+AC_INIT([systemtap], 0.6.1, systemtap@sources.redhat.com, systemtap)
AC_PREREQ(2.59)
AC_CONFIG_AUX_DIR(..)
diff --git a/testsuite/lib/systemtap.exp b/testsuite/lib/systemtap.exp
index f677da41..baed0e41 100644
--- a/testsuite/lib/systemtap.exp
+++ b/testsuite/lib/systemtap.exp
@@ -121,6 +121,9 @@ proc as_root { command } {
if {$effective_pid != 0} {
set command "sudo $command"
}
+ verbose -log "as_root $command"
set res [catch {eval exec $command} value]
+ verbose -log "OUT $value"
+ verbose -log "RC $res"
return $res
}
diff --git a/testsuite/semko/forty.stp b/testsuite/semko/forty.stp
new file mode 100755
index 00000000..f7721a47
--- /dev/null
+++ b/testsuite/semko/forty.stp
@@ -0,0 +1,4 @@
+#! stap -p2
+
+global x
+probe kernel.function("sys_open") if (x = 1) { } # bad side-effect
diff --git a/testsuite/semko/fortyone.stp b/testsuite/semko/fortyone.stp
new file mode 100755
index 00000000..e9b986df
--- /dev/null
+++ b/testsuite/semko/fortyone.stp
@@ -0,0 +1,3 @@
+#! stap -p2
+
+probe kernel.function("sys_open") if (x > 1) { } # not a global
diff --git a/testsuite/semko/fortytwo.stp b/testsuite/semko/fortytwo.stp
new file mode 100755
index 00000000..17dacb1c
--- /dev/null
+++ b/testsuite/semko/fortytwo.stp
@@ -0,0 +1,10 @@
+#! stap -p2
+
+probe kernel.function("sys_open") if (foo(2)) { } # must not call functions
+
+function foo(x) { return x }
+
+# NB: If this condition is relaxed, then this will have to be blocked:
+# global y function foo () { return y++ } # since global y is written-to
+# but this one would be fine:
+# function foo () { return y++ } # since y is written-to
diff --git a/testsuite/semok/twentynine.stp b/testsuite/semok/twentynine.stp
index 6fe308f2..05e591ce 100644
--- a/testsuite/semok/twentynine.stp
+++ b/testsuite/semok/twentynine.stp
@@ -4,10 +4,10 @@ function dummy:long () {return p;}
# alias with a condition
probe alias0 = begin if (3) {p=1}
-# alias with a kernel-variable condition
-probe alias1 = kernel.function("sys_read").return if ($return) {p=0}
+# alias with a kernel-variable condition -- not valid
+probe alias1 = kernel.function("sys_read").return if (0) { if ($return) {p=0} }
# alias with a function-call condition
-probe blias0 = timer.s(1) if (dummy()) {p=10}
+probe blias0 = timer.s(1) if (1 /* dummy() */) {p=10}
# multiple probe point with conditions
probe alias2 = alias0 if (1), alias1 if (-1) {p=2}
diff --git a/testsuite/systemtap.base/debugpath.exp b/testsuite/systemtap.base/debugpath.exp
new file mode 100644
index 00000000..67b9eb70
--- /dev/null
+++ b/testsuite/systemtap.base/debugpath.exp
@@ -0,0 +1,18 @@
+
+set test "debugpath-bad"
+spawn env SYSTEMTAP_DEBUGINFO_PATH=/dev/null stap -e "probe kernel.function(\"sys_open\") {}" -p4
+expect {
+ -re {^semantic error:.*missing.*debuginfo} { pass $test }
+ timeout { fail "$test (timeout1)" }
+ eof { fail "$test (eof)" }
+}
+catch { close; wait }
+
+set test "debugpath-good"
+spawn env SYSTEMTAP_DEBUGINFO_PATH=:/usr/lib/debug stap -e "probe kernel.function(\"sys_open\") {}" -p2
+expect {
+ -re {kernel.function.*pc=} { pass $test }
+ timeout { fail "$test (timeout2)" }
+ eof { fail "$test (eof)" }
+}
+catch { close ; wait }
diff --git a/testsuite/systemtap.samples/crash.exp b/testsuite/systemtap.samples/crash.exp
new file mode 100644
index 00000000..629cff54
--- /dev/null
+++ b/testsuite/systemtap.samples/crash.exp
@@ -0,0 +1,45 @@
+# Simple test for staplog.so crash(8) extension
+set test "crash"
+
+if {![installtest_p]} { untested $test; return }
+if {![file exists $env(CRASH_LIBDIR)/staplog.so]} { untested "$test - no staplog.so"; return }
+
+# Load a test script
+spawn stap $srcdir/$subdir/testlog.stp -m testlog
+expect {
+ -timeout 120
+ "HelloWorld\r\n" {
+ pass "$test - testlog.stp"
+ # Need to run crash(8) while this script is still running.
+ # Since crash(8) needs /dev/mem access, need it run as_root too.
+ # This [ eval ... \{ \} ] business is necessary because as_root
+ # evals the given list/variables in its own scope.
+ eval as_root \{ $srcdir/$subdir/crash.sh $env(CRASH_LIBDIR) \}
+ }
+ timeout { fail "$test - testlog.stp timeout" }
+ timeout { fail "$test - testlog.stp eof" }
+}
+catch { send "\003"; close ; wait }
+
+# The crash(8) script creates testlog/global or testlog/cpu<n>
+as_root { chmod -R a+rX testlog }
+
+set ok 0
+foreach f [glob -nocomplain testlog/*] {
+ pass "$test - crash(8) generated $f"
+ set fp [open $f]
+ set chars [read $fp]
+ close $fp
+ if [string match "HelloWorld*" $chars] {
+ incr ok
+ pass "$test - crash(8) data"
+ } else {
+ fail "$test - crash(8) data $chars"
+ }
+}
+if {$ok == 0} {
+ fail "$test - crash(8) data"
+}
+
+as_root { rm -rf testlog testlog.ko }
+
diff --git a/testsuite/systemtap.samples/crash.sh b/testsuite/systemtap.samples/crash.sh
new file mode 100755
index 00000000..06aa414e
--- /dev/null
+++ b/testsuite/systemtap.samples/crash.sh
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+crash --readnow << END
+mod -s testlog testlog.ko
+extend $1/staplog.so
+staplog testlog
+exit
+END
diff --git a/testsuite/systemtap.samples/testlog.stp b/testsuite/systemtap.samples/testlog.stp
new file mode 100644
index 00000000..5b702aa9
--- /dev/null
+++ b/testsuite/systemtap.samples/testlog.stp
@@ -0,0 +1,6 @@
+probe begin
+{
+ printf("Hello");
+ printf("World");
+ printf("\n");
+}
diff --git a/translate.cxx b/translate.cxx
index 7f42ceec..0beaf1f8 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -400,6 +400,20 @@ public:
}
}
+ string fini () const
+ {
+ switch (type())
+ {
+ case pe_string:
+ case pe_long:
+ return ""; // no action required
+ case pe_stats:
+ return "_stp_stat_del (" + value () + ");";
+ default:
+ throw semantic_error("unsupported deallocator for " + value());
+ }
+ }
+
void declare(c_unparser &c) const
{
c.c_declare(ty, name);
@@ -887,8 +901,12 @@ c_unparser::emit_common_header ()
// NB: see c_unparser::emit_probe() for original copy of duplicate-hashing logic.
ostringstream oss;
oss << "c->statp = & time_" << dp->basest()->name << ";" << endl; // -t anti-dupe
- dp->body->print(oss);
oss << "# needs_global_locks: " << dp->needs_global_locks () << endl;
+ dp->body->print(oss);
+ // NB: dependent probe conditions *could* be listed here, but don't need to be.
+ // That's because they're only dependent on the probe body, which is already
+ // "hashed" in above.
+
if (tmp_probe_contents.count(oss.str()) == 0) // unique
{
@@ -911,9 +929,13 @@ c_unparser::emit_common_header ()
throw e2;
}
}
+
+ // NB: This part is finicky. The logic here must
+ // match up with
c_tmpcounter ct (this);
- dp->body->visit (& ct);
dp->emit_probe_context_vars (o);
+ dp->body->visit (& ct);
+
o->newline(-1) << "} " << dp->name << ";";
}
}
@@ -1193,6 +1215,8 @@ c_unparser::emit_module_init ()
vardecl* v = session->globals[i];
if (v->index_types.size() > 0)
o->newline() << getmap (v).fini();
+ else
+ o->newline() << getvar (v).fini();
}
o->newline() << "return rc;";
@@ -1254,6 +1278,8 @@ c_unparser::emit_module_exit ()
vardecl* v = session->globals[i];
if (v->index_types.size() > 0)
o->newline() << getmap (v).fini();
+ else
+ o->newline() << getvar (v).fini();
}
o->newline() << "free_percpu (contexts);";
@@ -1404,8 +1430,11 @@ c_unparser::emit_probe (derived_probe* v)
//
// which would make comparisons impossible.
//
- // NB: see also c_unparser:emit_common_header(), which duplicates
- // this calculation.
+ // --------------------------------------------------------------------------
+ // NB: see also c_unparser:emit_common_header(), which deliberately but sadly
+ // duplicates this calculation.
+ // --------------------------------------------------------------------------
+ //
ostringstream oss;
// NB: statp is just for avoiding designation as duplicate. It need not be C.
@@ -1503,13 +1532,12 @@ c_unparser::emit_probe (derived_probe* v)
}
v->initialize_probe_context_vars (o);
-
+
v->body->visit (this);
o->newline(-1) << "out:";
- // NB: no need to uninitialize locals, except if arrays can
- // somedays be local
-
+ // NB: no need to uninitialize locals, except if arrays/stats can
+ // someday be local
// XXX: do this flush only if the body included a
// print/printf/etc. routine!