summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfche <fche>2005-08-30 01:54:44 +0000
committerfche <fche>2005-08-30 01:54:44 +0000
commitba4a90fd18a9c94624a38d660c6e7ca6230c271f (patch)
tree82a060bc5f9db3001c0e09db8372caf8bfdfc2dc
parent55a030a179fdfd1e887d95d5c0050004bee27fcf (diff)
downloadsystemtap-steved-ba4a90fd18a9c94624a38d660c6e7ca6230c271f.tar.gz
systemtap-steved-ba4a90fd18a9c94624a38d660c6e7ca6230c271f.tar.xz
systemtap-steved-ba4a90fd18a9c94624a38d660c6e7ca6230c271f.zip
2005-08-29 Frank Ch. Eigler <fche@redhat.com>
* stapprobes.5.in, stapfuncs.5.in, stapex.5.in: New man pages. * stap.1.in: Moved some content out. * Makefile.am (man_MANS): Add new man pages. * configure.ac (AC_CONFIG_FILES): Add them. * systemtap.spec.in: Package them. * Makefile.in, configure: Regenerated. * buildrun.cxx (run_pass): Pass "-r" to stpd. * translate.cxx (emit_common_header): Wrap try/catch around variable decls, to improve exception particularity. (visit_literal_number): Emit as unsigned literal, which is actually a subtle correctness issue.
-rw-r--r--ChangeLog14
-rw-r--r--Makefile.am2
-rw-r--r--Makefile.in85
-rw-r--r--buildrun.cxx1
-rwxr-xr-xconfigure5
-rw-r--r--configure.ac2
-rw-r--r--stap.1.in222
-rw-r--r--stapex.5.in118
-rw-r--r--stapfuncs.5.in92
-rw-r--r--stapprobes.5.in181
-rw-r--r--systemtap.spec.in1
-rw-r--r--translate.cxx38
12 files changed, 590 insertions, 171 deletions
diff --git a/ChangeLog b/ChangeLog
index 69122cd5..d6e0ece4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2005-08-29 Frank Ch. Eigler <fche@redhat.com>
+
+ * stapprobes.5.in, stapfuncs.5.in, stapex.5.in: New man pages.
+ * stap.1.in: Moved some content out.
+ * Makefile.am (man_MANS): Add new man pages.
+ * configure.ac (AC_CONFIG_FILES): Add them.
+ * systemtap.spec.in: Package them.
+ * Makefile.in, configure: Regenerated.
+ * buildrun.cxx (run_pass): Pass "-r" to stpd.
+ * translate.cxx (emit_common_header): Wrap try/catch around
+ variable decls, to improve exception particularity.
+ (visit_literal_number): Emit as unsigned literal, which is
+ actually a subtle correctness issue.
+
2005-08-28 Frank Ch. Eigler <fche@redhat.com>
* tapsets.cxx (visit_target): Make target variable exceptions
diff --git a/Makefile.am b/Makefile.am
index ea26e4d6..660aae40 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -8,7 +8,7 @@ AM_CFLAGS = -std=gnu99 -D_GNU_SOURCE \
-Wall -Werror -Wshadow -Wunused -Wformat=2 -W
AM_CXXFLAGS = -Wall
-dist_man_MANS = stap.1
+dist_man_MANS = stap.1 stapprobes.5 stapfuncs.5 stapex.5
bin_PROGRAMS = stap
stap_SOURCES = main.cxx \
parse.cxx staptree.cxx elaborate.cxx translate.cxx \
diff --git a/Makefile.in b/Makefile.in
index 74741bbe..cab17cba 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -43,9 +43,11 @@ noinst_PROGRAMS = stpd$(EXEEXT) loc2c-test$(EXEEXT)
subdir = .
DIST_COMMON = README $(am__configure_deps) $(dist_man_MANS) \
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
- $(srcdir)/config.in $(srcdir)/stap.1.in $(srcdir)/stp_check.in \
- $(srcdir)/systemtap.spec.in $(top_srcdir)/configure AUTHORS \
- COPYING ChangeLog INSTALL NEWS TODO depcomp install-sh missing
+ $(srcdir)/config.in $(srcdir)/stap.1.in $(srcdir)/stapex.5.in \
+ $(srcdir)/stapfuncs.5.in $(srcdir)/stapprobes.5.in \
+ $(srcdir)/stp_check.in $(srcdir)/systemtap.spec.in \
+ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
+ TODO depcomp install-sh missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -54,8 +56,10 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno configure.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
-CONFIG_CLEAN_FILES = systemtap.spec stp_check stap.1
-am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"
+CONFIG_CLEAN_FILES = systemtap.spec stp_check stap.1 stapprobes.5 \
+ stapfuncs.5 stapex.5
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \
+ "$(DESTDIR)$(man5dir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
am_loc2c_test_OBJECTS = loc2c-test.$(OBJEXT) loc2c.$(OBJEXT)
@@ -85,6 +89,7 @@ CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
SOURCES = $(loc2c_test_SOURCES) $(stap_SOURCES) $(stpd_SOURCES)
DIST_SOURCES = $(loc2c_test_SOURCES) $(stap_SOURCES) $(stpd_SOURCES)
man1dir = $(mandir)/man1
+man5dir = $(mandir)/man5
NROFF = nroff
MANS = $(dist_man_MANS)
ETAGS = etags
@@ -193,7 +198,7 @@ AM_CFLAGS = -std=gnu99 -D_GNU_SOURCE \
-Wall -Werror -Wshadow -Wunused -Wformat=2 -W
AM_CXXFLAGS = -Wall
-dist_man_MANS = stap.1
+dist_man_MANS = stap.1 stapprobes.5 stapfuncs.5 stapex.5
stap_SOURCES = main.cxx \
parse.cxx staptree.cxx elaborate.cxx translate.cxx \
tapsets.cxx buildrun.cxx loc2c.c
@@ -287,6 +292,12 @@ stp_check: $(top_builddir)/config.status $(srcdir)/stp_check.in
cd $(top_builddir) && $(SHELL) ./config.status $@
stap.1: $(top_builddir)/config.status $(srcdir)/stap.1.in
cd $(top_builddir) && $(SHELL) ./config.status $@
+stapprobes.5: $(top_builddir)/config.status $(srcdir)/stapprobes.5.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+stapfuncs.5: $(top_builddir)/config.status $(srcdir)/stapfuncs.5.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+stapex.5: $(top_builddir)/config.status $(srcdir)/stapex.5.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
@@ -540,6 +551,51 @@ uninstall-man1:
echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \
rm -f "$(DESTDIR)$(man1dir)/$$inst"; \
done
+install-man5: $(man5_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man5dir)" || $(mkdir_p) "$(DESTDIR)$(man5dir)"
+ @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 5*) ;; \
+ *) ext='5' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst"; \
+ done
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 5*) ;; \
+ *) ext='5' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man5dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man5dir)/$$inst"; \
+ done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
@@ -797,7 +853,7 @@ check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS) $(MANS) config.h
installdirs:
- for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
@@ -852,7 +908,7 @@ install-exec-am: install-binPROGRAMS install-exec-local
install-info: install-info-am
-install-man: install-man1
+install-man: install-man1 install-man5
installcheck-am:
@@ -878,7 +934,7 @@ ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-info-am uninstall-local \
uninstall-man
-uninstall-man: uninstall-man1
+uninstall-man: uninstall-man1 uninstall-man5
.PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \
clean clean-binPROGRAMS clean-generic clean-local \
@@ -890,11 +946,12 @@ uninstall-man: uninstall-man1
install-binPROGRAMS install-data install-data-am \
install-data-local install-exec install-exec-am \
install-exec-local install-info install-info-am install-man \
- install-man1 install-strip installcheck installcheck-am \
- installdirs maintainer-clean maintainer-clean-generic \
- mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
- ps ps-am tags uninstall uninstall-am uninstall-binPROGRAMS \
- uninstall-info-am uninstall-local uninstall-man uninstall-man1
+ install-man1 install-man5 install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-binPROGRAMS uninstall-info-am \
+ uninstall-local uninstall-man uninstall-man1 uninstall-man5
dist-hook:
find $(distdir) -name CVS -o -name '*~' -o -name '.#*' | xargs rm -rf
diff --git a/buildrun.cxx b/buildrun.cxx
index 06e2494c..867d0d0e 100644
--- a/buildrun.cxx
+++ b/buildrun.cxx
@@ -113,6 +113,7 @@ run_pass (systemtap_session& s)
// for now, just spawn stpd
string stpd_cmd = string("/usr/bin/sudo ")
+ string(PKGLIBDIR) + "/stpd "
+ + "-r " // disable relayfs
+ (s.verbose ? "" : "-q ")
+ s.tmpdir + "/" + s.module_name + ".ko";
diff --git a/configure b/configure
index a0a2dda7..169e3133 100755
--- a/configure
+++ b/configure
@@ -5170,7 +5170,7 @@ DATE="$date"
ac_config_headers="$ac_config_headers config.h:config.in"
- ac_config_files="$ac_config_files Makefile systemtap.spec stp_check stap.1"
+ ac_config_files="$ac_config_files Makefile systemtap.spec stp_check stap.1 stapprobes.5 stapfuncs.5 stapex.5"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -5746,6 +5746,9 @@ do
"systemtap.spec" ) CONFIG_FILES="$CONFIG_FILES systemtap.spec" ;;
"stp_check" ) CONFIG_FILES="$CONFIG_FILES stp_check" ;;
"stap.1" ) CONFIG_FILES="$CONFIG_FILES stap.1" ;;
+ "stapprobes.5" ) CONFIG_FILES="$CONFIG_FILES stapprobes.5" ;;
+ "stapfuncs.5" ) CONFIG_FILES="$CONFIG_FILES stapfuncs.5" ;;
+ "stapex.5" ) CONFIG_FILES="$CONFIG_FILES stapex.5" ;;
"depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
"config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.in" ;;
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
diff --git a/configure.ac b/configure.ac
index cfdbd95e..6730879c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -40,5 +40,5 @@ AC_DEFINE_UNQUOTED(DATE, "$date", [Configuration/build date])
AC_SUBST(DATE, "$date")
AC_CONFIG_HEADERS([config.h:config.in])
-AC_CONFIG_FILES(Makefile systemtap.spec stp_check stap.1)
+AC_CONFIG_FILES(Makefile systemtap.spec stp_check stap.1 stapprobes.5 stapfuncs.5 stapex.5)
AC_OUTPUT
diff --git a/stap.1.in b/stap.1.in
index cf89758f..56148f06 100644
--- a/stap.1.in
+++ b/stap.1.in
@@ -2,6 +2,20 @@
.TH STAP 1 @DATE@ "Red Hat"
.SH NAME
stap \- systemtap script translator/driver
+
+.\" macros
+.de SAMPLE
+.br
+.RS
+.nf
+.nh
+..
+.de ESAMPLE
+.hy
+.fi
+.RE
+..
+
.SH SYNOPSIS
.br
@@ -32,7 +46,11 @@ instructions (written in a simple scripting language), translates
those instructions into C code, compiles this C code, and loads the
resulting kernel module into a running Linux kernel to perform the
requested system trace/probe functions. You can supply the script in
-a named file, from standard input, or from the command line.
+a named file, from standard input, or from the command line. The
+program runs until it is interrupted by the user, or if the script
+voluntarily invokes the
+.I exit()
+function, or by any fatal error.
.PP
The language, which is described in a later section, is strictly typed,
declaration free, procedural, and inspired by
@@ -234,126 +252,43 @@ function call
.SS PROBES
The main construct in the scripting language identifies probes.
Probes associate abstract events with a statement block ("probe
-handler") that is to be executed when those events occur. The
+handler") that is to be executed when any of those events occur. The
general syntax is as follows:
-.RS
-.br
-.nh
-.nf
+.SAMPLE
.BR probe " PROBEPOINT [" , " PROBEPOINT] " { " [STMT ...] " }
-.hy
-.fi
-.RE
-.PP
-Events are specified in a special syntax called "probe points". One
-family refers to specific points in a kernel, which are identified by
-module, source file, line number, function name, C label name, or some
-combination of these. This kind of "synchronous" event is deemed to
-occur when any processor executes an instruction matched by the
-specification. Other families of probe points refer to "asynchronous"
-events such as timers/counters rolling over, where there is no fixed
-execution point that is related. Each probe point specification may
-match multiple physical locations, all of which are then probed. A
-probe declaration may also contain several comma-separated
-specifications, all of which are probed.
-.PP
-Here is a list of probe point families currently supported. The
-.B .function
-variant places a probe near the beginning of the named function, so that
-parameters are available as context variables. The
-.B .return
-variant places a probe at the moment of return from the named function, so
-the return value is available as the "$retvalue" context variable.
-The
-.B .statement
-variant places a probe at the exact spot, exposing those local variables
-that are visible there.
-.RS
-.nf
-.br
-kernel.function(PATTERN)
-.br
-kernel.function(PATTERN).return
-.br
-module(MPATTERN).function(PATTERN)
-.br
-module(MPATTERN).function(PATTERN).return
-.br
-kernel.statement(PATTERN)
-.br
-module(MPATTERN).statement(PATTERN)
-.br
-timer.jiffies(NUM)
-.br
-timer.jiffies(NUM).randomize(RAND)
-.fi
-.RE
+.ESAMPLE
.PP
-In the above list, MPATTERN stands for a string literal that aims to
-identify the loaded kernel module of interest. It may include "*" and
-"?" wildcards. PATTERN stands for a string literal that aims to
-identify a point in the program. It is made up of three parts. The
-first part is the name of a function, as would appear in the
-.I nm
-program's output. This part may use the "*" and "?" wildcarding
-operators to match multiple names. The second part is optional, and
-begins with the "@" character. It is followed by a source file name
-wildcard pattern, such as
-.IR mm/slab* .
-Finally, the third part is optional if the file name part was given,
-and identifies the line number in the source file, preceded by a ":".
-As an alternative, PATTERN may be a numeric constant, indicating an
-(module-relative or kernel-absolute) address.
-.PP
-The timer-based asynchronous probe points run the given handler every
-NUM jiffies. If given, the random value in the range [-RAND..RAND] is
-added to NUM every time the handler is run.
-.PP
-Here are some example probe points:
-.TP
-kernel.function("*init*"), kernel.function("*exit*")
-refers to all kernel functions with "init" or "exit" in the name.
-.TP
-kernel.function("*@kernel/sched.c:240")
-refers to any functions within the "kernel/sched.c" file that span
-line 240.
-.TP
-module("usb*").function("*sync*").return
-refers to the moment of return from all functions with "sync" in the
-name in any of the USB drivers.
-.TP
-kernel.statement(0xc0044852)
-refers to the first byte of the statement whose compiled instructions
-include the given address in the kernel.
-.TP
-timer.jiffies(1000).randomize(200)
-refers to a periodic interrupt, every 1000 +/- 200 jiffies.
-
+Events are specified in a special syntax called "probe points". There
+are several varieties of probe points defined by the translator, and
+tapset scripts may define further ones using aliases. These are
+listed in the
+.IR stapprobes (5)
+manual pages.
.PP
-When any matching event occurs, the probe handler is run within that
-context. For events that are defined by execution of specific parts
-of code, this context may include variables defined in the source code
+The probe handler is interpreted relative to the context of each
+event. For events associated with kernel code, this context may
+include
+.I variables
+defined in the
+.I source code
at that spot. These "target variables" are presented to the script as
-variables whose names are prefixed with "$". They may be read/written
+variables whose names are prefixed with "$". They may be accessed
only if the kernel's compiler preserved them despite optimization.
This is the same constraint that a debugger user faces when working
-with optimized code. Asynchronous probes have very little context.
+with optimized code. Some other events have very little context.
.PP
-In addition, "probe aliases" may be defined. Probe aliases look
-similar to probe definitions, but instead of activating a probe at the
-given point, it defines a new probe point name to alias an existing
-one. This is identified by the "=" assignment operator. In addition,
-the probe handler defined with an alias is implicitly added as a
-prologue to any probe that refers to the alias. For example:
-.RS
-.nf
-.nh
+New probe points may be defined using "aliases". Probe point aliases
+look similar to probe definitions, but instead of activating a probe
+at the given point, it just defines a new probe point name as an alias
+to an existing one. This is identified by the "=" assignment
+operator. In addition, the statement block that follows an alias
+definition is implicitly added as a prologue to any probe that refers
+to the alias. For example:
+.SAMPLE
probe syscall("read") = kernel.function("sys_read") {
fildes = $fd
}
-.hy
-.fi
-.RE
+.ESAMPLE
defines a new probe point
.nh
.IR syscall("read") ,
@@ -364,26 +299,22 @@ which expands to
.hy
with the given assignment as a prologue. Another probe definition
may use the alias like this:
-.RS
-.nf
+.SAMPLE
probe syscall("read") {
printk ("reading fd=" . string (fildes))
}
-.fi
-.RE
+.ESAMPLE
.SS FUNCTIONS
Systemtap scripts may define subroutines to factor out common work.
Functions take any number of scalar (integer or string) arguments, and
must return a single scalar (integer or string). An example function
declaration looks like this:
-.RS
-.nf
+.SAMPLE
function thisfn (arg1, arg2) {
return arg1 + arg2
}
-.fi
-.RE
+.ESAMPLE
Note the usual absence of type declarations, which are instead
inferred by the translator. Functions may call others or themselves
recursively, up to a fixed nesting limit. This limit is defined by
@@ -416,9 +347,7 @@ The memory locations set aside for input and output values
are made available to it using a macro
.IR THIS .
Here are some examples:
-.RS
-.br
-.nf
+.SAMPLE
function add_one (val) %{
THIS->__retvalue = THIS->val + 1;
%}
@@ -426,20 +355,21 @@ function add_one_str (val) %{
strncpy (THIS->__retvalue, THIS->val, MAXSTRINGLEN);
strncat (THIS->__retvalue, "one", MAXSTRINGLEN);
%}
-.fi
-.RE
+.ESAMPLE
The function argument and return value types have to be inferred by
the translator from the call sites in order for this to work. The
user should examine C code generated for ordinary script-language
functions in order to write compatible embedded-C ones.
.SS BUILT-INS
-A set of builtin functions and probe aliases are provided by the
-scripts installed under the
+A set of builtin functions and probe point aliases are provided
+by the scripts installed under the
.nh
.IR /usr/share/systemtap/tapset
.hy
-directory.
+directory. These are described in the
+.IR stapfuncs "(5) and " stapprobes (5)
+manual pages.
.SH PROCESSING
The translator begins pass 1 by parsing the given input script,
@@ -448,9 +378,9 @@ and all scripts (files named
found in a tapset directory. The directories listed
with
.BR -I
-are processed in sequence. For each directory, a number of subdirectories
-are also searched. These subdirectories are derived from the selected
-kernel version (the
+are processed in sequence, each processed in "guru mode". For each
+directory, a number of subdirectories are also searched. These
+subdirectories are derived from the selected kernel version (the
.BR -R
option),
in order to allow more kernel-version-specific scripts to override less
@@ -519,22 +449,10 @@ results in an error condition that prevents further probes from
running. Finally, stpd unloads the module, and cleans up.
.SH EXAMPLES
-To trace entry and exit from a function, use a pair of probes:
-.RS
-.br
-.nf
-probe kernel.function("foo") { log ("enter") }
-probe kernel.function("foo").return { log ("exit") }
-.fi
-.RE
+See the
+.IR stapex (5)
+manual page for a collection of samples.
-To list the probeable functions in the kernel, use
-.RS
-.br
-.nf
-stap -p2 -e 'probe kernel.function("*") {}'
-.fi
-.RE
.SH SAFETY AND SECURITY
Systemtap is an administrative tool. It exposes kernel internal data
@@ -556,8 +474,17 @@ privileges to untrusted users.
The translator asserts certain safety constraints. It aims to ensure
that no handler routine can run for very long, allocate memory,
perform unsafe operations, or in unintentionally interfere with the
-kernel. Use of guru mode constructs such as embedded C can violate
-these constraints, leading to kernel crash or data corruption.
+kernel. Use of script global variables is suitably locked to protect
+against manipulation by concurrent probe handlers. Use of guru mode
+constructs such as embedded C can violate these constraints, leading
+to kernel crash or data corruption.
+.PP
+In case something goes wrong with
+.IR stap " or " stpd
+after a probe has already started running, one may safely kill both
+user processes, and remove the active probe kernel module with
+.IR rmmod .
+Any pending trace messages may be lost.
.SH FILES
.\" consider autoconf-substituting these directories
@@ -590,6 +517,9 @@ The auxiliary program supervising module loading, interaction, and
unloading.
.SH SEE ALSO
+.IR stapprobes (5),
+.IR stapfuncs (5),
+.IR stapex (5),
.IR dtrace (1),
.IR dprobes (1),
.IR awk (1),
diff --git a/stapex.5.in b/stapex.5.in
new file mode 100644
index 00000000..f62eb112
--- /dev/null
+++ b/stapex.5.in
@@ -0,0 +1,118 @@
+.\" -*- nroff -*-
+.TH STAPEX 5 @DATE@ "Red Hat"
+.SH NAME
+stapex \- systemtap examples
+
+.\" macros
+.de SAMPLE
+.br
+.RS
+.nf
+.nh
+..
+.de ESAMPLE
+.hy
+.fi
+.RE
+..
+
+.SH LANGUAGE BASICS
+These examples give a feel for basic systemtap syntax and
+control structures.
+
+.SAMPLE
+global odds, evens
+
+probe begin {
+ # "no" and "ne" are local integers
+ for (i=0; i<10; i++) {
+ if (i % 2) odds [no++] = i
+ else evens [ne++] = i
+ }
+ delete odds[2]
+ delete evens[3]
+ exit ()
+}
+
+probe end {
+ foreach (x in odds) {
+ log("odds[" . string(x) . "] = " . string(odds[x]))
+ }
+ foreach (x in evens) {
+ log("evens[" . string(x) . "] = " . string(evens[x]))
+ }
+}
+.ESAMPLE
+This prints:
+.SAMPLE
+odds[1] = 1
+odds[3] = 5
+odds[4] = 7
+odds[5] = 9
+evens[2] = 2
+evens[4] = 6
+evens[5] = 8
+.ESAMPLE
+Note that the evens[1] key is missing, since its value was zero. Any
+array element with an "empty" value (zero or empty string) is
+considered not present in the array, as if it was deleted. Note that
+all variables types are inferred, and that all locals and globals are
+initialized.
+
+.PP
+This script prints the primes between 0 and 49.
+.SAMPLE
+function isprime (x) {
+ if (x < 2) return 0
+ for (i=2; i<x; i++) {
+ if (x % i == 0) return 0
+ if (i * i > x) break
+ }
+ return 1
+}
+probe begin {
+ for (i=0; i<50; i++)
+ if (isprime (i)) log (string(i))
+ exit()
+}
+.ESAMPLE
+
+.PP
+This script demonstrates recursive functions.
+.SAMPLE
+function fibonacci(i) {
+ if (i < 1) error ("bad number")
+ if (i == 1) return 1
+ if (i == 2) return 2
+ return fibonacci (i-1) + fibonacci (i-2)
+}
+probe begin {
+ log ("11th fibonacci number: " . string (fibonacci (11)))
+ exit ()
+}
+.ESAMPLE
+Any larger number may exceed the MAXACTION or MAXNESTING
+limits, and result in an error.
+
+
+.SH PROBING
+
+To trace entry and exit from a function, use a pair of probes:
+.SAMPLE
+probe kernel.function("sys_mkdir") { log ("enter") }
+probe kernel.function("sys_mkdir").return { log ("exit") }
+.ESAMPLE
+
+To list the probeable functions in the kernel, use the last-pass
+option to the translator. That output needs to be filtered because
+each inlined function instance is listed separately.
+.SAMPLE
+% stap -p2 -e 'probe kernel.function("*") {}' | sort | uniq
+.ESAMPLE
+
+
+.SH SEE ALSO
+.IR stap (1)
+.IR stapprobes (5)
+.IR stapfuncs (5)
+
diff --git a/stapfuncs.5.in b/stapfuncs.5.in
new file mode 100644
index 00000000..597dc674
--- /dev/null
+++ b/stapfuncs.5.in
@@ -0,0 +1,92 @@
+.\" -*- nroff -*-
+.TH STAPFUNCS 5 @DATE@ "Red Hat"
+.SH NAME
+stapfuncs \- systemtap functions
+
+.SH DESCRIPTION
+The following sections enumerate the public functions provided by
+standard tapsets installed under /usr/share/systemtap/tapset. Each
+function is described with a signature, and its behavior/restrictions.
+The signature line includes the name of the function, the type of
+its return value (if any), and the names and types of all parameters.
+The syntax is the same as printed with the
+.IR stap " option " -p2 .
+Examples:
+
+.TP
+example1:long (v:string, k:long)
+Function "example1" does something with the given string and integer.
+It returns some integer.
+
+.TP
+example2:unknown ()
+Function "example2" does something. There is no explicit return value
+and it takes no parameters.
+
+.SS LOGGING
+
+.TP
+printk:unknown (msg:string)
+Log the given string to the kernel's printk buffer, at KERN_INFO severity.
+Append an implicit end-of-line.
+
+.TP
+log:unknown (msg:string)
+Log the given string to the common trace buffer. Append an implicit
+end-of-line.
+
+.TP
+warn:unknown (msg:string)
+Log the given string to the warning stream. Append an implicit end-of-line.
+.I stpd
+prepends the string "WARNING:".
+
+.TP
+error:unknown (msg:string)
+A fatal error has occurred. Log the given string to the error stream.
+Append an implicit end-of-line.
+.I stpd
+prepends the string "ERROR:".
+Block any further execution of statements in this probe, block
+any new probe handlers, and end the systemtap session as soon
+as possible.
+
+.TP
+exit:unknown ()
+Enqueue a request to shut down the systemtap session. This does
+.B not
+unwind the current probe handler, nor block new probe handlers.
+.I stpd
+will shortly respond to the request and initiate an orderly shutdown.
+
+.SS CONVERSIONS
+
+.TP
+hexstring:string (num:long)
+Return a hexadecimal string representation of the given integer, including
+the leading "0x".
+
+.TP
+string:string (num:long)
+Return a decimal string representation of the given integer.
+
+.SS TIMESTAMP
+
+.TP
+gettimeofday_ms:long ()
+Return the number of milliseconds since the UNIX epoch.
+
+.TP
+gettimeofday_s:long ()
+Return the number of seconds since the UNIX epoch.
+
+.\" .SS CONTEXTINFO
+
+
+.SH FILES
+.nh
+.IR /usr/share/systemtap/tapset
+.hy
+
+.SH SEE ALSO
+.IR stap (1)
diff --git a/stapprobes.5.in b/stapprobes.5.in
new file mode 100644
index 00000000..f1a4451b
--- /dev/null
+++ b/stapprobes.5.in
@@ -0,0 +1,181 @@
+.\" -*- nroff -*-
+.TH STAPPROBES 5 @DATE@ "Red Hat"
+.SH NAME
+stapprobes \- systemtap probe points
+
+.\" macros
+.de SAMPLE
+.br
+.RS
+.nf
+.nh
+..
+.de ESAMPLE
+.hy
+.fi
+.RE
+..
+
+.SH DESCRIPTION
+The following sections enumerate the variety of probe points supported
+by the systemtap translator, and additional aliases defined by
+standard tapset scripts.
+.PP
+The general probe point syntax is a "dotted-functor" sequence. This
+allows a breakdown of the event namespace into parts, somewhat like
+the Domain Name System does on the Internet. Each component
+identifier may be parametrized by a string or number literal. These
+are all syntactically valid probe points:
+.SAMPLE
+kernel.function("foo").return
+syscall(22)
+user.inode("/bin/vi").statement(0x2222)
+end
+.ESAMPLE
+
+.SS BEGIN/END
+
+The probe points
+.IR begin " and " end
+are defined by the translator to refer to the time of session startup
+and shutdown. All "begin" probe handlers are run, in some sequence,
+during the startup of the session. All global variables will have
+been initialized prior to this point. All "end" probes are run, in
+some sequence, during the
+.I normal
+shutdown of a session, such as in the aftermath of an
+.I exit ()
+function call, or an interruption from the user. In the case of an
+error-triggered shutdown, "end" probes are not run. There are no
+target variables available in either context.
+
+.SS TIMERS
+
+Intervals defined by the standard kernel "jiffies" timer may be used
+to trigger probe handlers asynchronously. Two probe point variants
+are supported by the translator:
+.SAMPLE
+timer.jiffies(N)
+timer.jiffies(N).randomize(M)
+.ESAMPLE
+The probe handler is run every N jiffies (a kernel-defined unit of
+time, typically between 1 and 60 ms). If the "randomize" component is
+given, a linearly distributed random value in the range [-M..+M] is
+added to N every time the handler is run. N is restricted to a
+reasonable range (1 to around a million), and M is restricted to be
+smaller than N. There are no target variables provided in either
+context. It is possible for such probes to be run concurrently on
+a multi-processor computer.
+
+.SS DWARF
+
+This family of probe points uses symbolic debugging information for
+the target kernel/module/program, as may be found in unstripped
+executables, or the separate
+.I debuginfo
+packages. They allow placement of probes logically into the execution
+path of the target program, by specifying a set of points in the
+source or object code. When a matching statement executes on any
+processor, the probe handler is run in that context.
+.PP
+Points in a kernel, which are identified by
+module, source file, line number, function name, C label name, or some
+combination of these. This kind of "synchronous" event is deemed to
+occur when any processor executes an instruction matched by the
+specification. Other families of probe points refer to "asynchronous"
+events such as timers/counters rolling over, where there is no fixed
+execution point that is related. Each probe point specification may
+match multiple physical locations, all of which are then probed. A
+probe declaration may also contain several comma-separated
+specifications, all of which are probed.
+.PP
+Here is a list of probe point families currently supported. The
+.B .function
+variant places a probe near the beginning of the named function, so that
+parameters are available as context variables. The
+.B .return
+variant places a probe at the moment of return from the named function, so
+the return value is available as the "$retvalue" context variable.
+The
+.B .statement
+variant places a probe at the exact spot, exposing those local variables
+that are visible there.
+.SAMPLE
+kernel.function(PATTERN)
+.br
+kernel.function(PATTERN).return
+.br
+module(MPATTERN).function(PATTERN)
+.br
+module(MPATTERN).function(PATTERN).return
+.br
+kernel.statement(PATTERN)
+.br
+module(MPATTERN).statement(PATTERN)
+.ESAMPLE
+In the above list, MPATTERN stands for a string literal that aims to
+identify the loaded kernel module of interest. It may include "*" and
+"?" wildcards. PATTERN stands for a string literal that aims to
+identify a point in the program. It is made up of three parts. The
+first part is the name of a function, as would appear in the
+.I nm
+program's output. This part may use the "*" and "?" wildcarding
+operators to match multiple names. The second part is optional, and
+begins with the "@" character. It is followed by a source file name
+wildcard pattern, such as
+.IR mm/slab* .
+Finally, the third part is optional if the file name part was given,
+and identifies the line number in the source file, preceded by a ":".
+As an alternative, PATTERN may be a numeric constant, indicating an
+(module-relative or kernel-absolute) address.
+.PP
+Some of the source-level variables, such as function parameters,
+locals, globals visible in the compilation unit, may be visible to
+probe handlers. They may refer to these variables by prefixing their
+name with "$" within the scripts. In addition, a special syntax
+allows limited traversal of structures, pointers, and arrays.
+.TP
+$var
+refers to an in-scope variable "var". If it's an integer-like type,
+it will be cast to a 64-bit int for systemtap script use. If it's
+a string-like type (char *), it will be copied into a systemtap
+string.
+.TP
+$var->field
+traversal to a structure's field. The indirection operator
+may be repeated to follow more levels of pointers.
+.TP
+$var[N]
+indexes into an array. The index is given with a
+literal number.
+
+.SH EXAMPLES
+.PP
+Here are some example probe points, defining the associated events.
+.TP
+begin, end, end
+refers to the startup and normal shutdown of the session. In this
+case, the handler would run once during startup and twice during
+shutdown.
+.TP
+timer.jiffies(1000).randomize(200)
+refers to a periodic interrupt, every 1000 +/- 200 jiffies.
+.TP
+kernel.function("*init*"), kernel.function("*exit*")
+refers to all kernel functions with "init" or "exit" in the name.
+.TP
+kernel.function("*@kernel/sched.c:240")
+refers to any functions within the "kernel/sched.c" file that span
+line 240.
+.TP
+module("usb*").function("*sync*").return
+refers to the moment of return from all functions with "sync" in the
+name in any of the USB drivers.
+.TP
+kernel.statement(0xc0044852)
+refers to the first byte of the statement whose compiled instructions
+include the given address in the kernel.
+
+
+.SH SEE ALSO
+.IR stap (1)
diff --git a/systemtap.spec.in b/systemtap.spec.in
index 22dc7ba0..6711b35a 100644
--- a/systemtap.spec.in
+++ b/systemtap.spec.in
@@ -112,6 +112,7 @@ rm -rf ${RPM_BUILD_ROOT}
%{_bindir}/stap
%{_mandir}/man1/*
+%{_mandir}/man5/*
%{_libexecdir}/systemtap/*
%dir %{_datadir}/systemtap
diff --git a/translate.cxx b/translate.cxx
index 71241d00..a8d768ae 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -564,8 +564,15 @@ c_unparser::emit_common_header ()
for (unsigned j=0; j<dp->locals.size(); j++)
{
vardecl* v = dp->locals[j];
- o->newline() << c_typename (v->type) << " "
- << c_varname (v->name) << ";";
+ try
+ {
+ o->newline() << c_typename (v->type) << " "
+ << c_varname (v->name) << ";";
+ } catch (const semantic_error& e) {
+ semantic_error e2 (e);
+ if (e2.tok1 == 0) e2.tok1 = v->tok;
+ throw e2;
+ }
}
c_tmpcounter ct (this);
dp->body->visit (& ct);
@@ -580,15 +587,29 @@ c_unparser::emit_common_header ()
o->indent(1);
for (unsigned j=0; j<fd->locals.size(); j++)
{
- vardecl* v = fd->locals[j];
- o->newline() << c_typename (v->type) << " "
- << c_varname (v->name) << ";";
+ vardecl* v = fd->locals[j];
+ try
+ {
+ o->newline() << c_typename (v->type) << " "
+ << c_varname (v->name) << ";";
+ } catch (const semantic_error& e) {
+ semantic_error e2 (e);
+ if (e2.tok1 == 0) e2.tok1 = v->tok;
+ throw e2;
+ }
}
for (unsigned j=0; j<fd->formal_args.size(); j++)
{
vardecl* v = fd->formal_args[j];
- o->newline() << c_typename (v->type) << " "
- << c_varname (v->name) << ";";
+ try
+ {
+ o->newline() << c_typename (v->type) << " "
+ << c_varname (v->name) << ";";
+ } catch (const semantic_error& e) {
+ semantic_error e2 (e);
+ if (e2.tok1 == 0) e2.tok1 = v->tok;
+ throw e2;
+ }
}
c_tmpcounter ct (this);
fd->body->visit (& ct);
@@ -1590,7 +1611,8 @@ c_unparser::visit_literal_number (literal_number* e)
{
// This looks ugly, but tries to be warning-free on 32- and 64-bit
// hosts.
- o->line() << "((uint64_t)" << e->value << "LL)";
+ // NB: this needs to be signed!
+ o->line() << "((int64_t)" << e->value << "LL)";
}