summaryrefslogtreecommitdiffstats
path: root/testsuite/systemtap.samples
diff options
context:
space:
mode:
authorfche <fche>2006-08-12 05:13:09 +0000
committerfche <fche>2006-08-12 05:13:09 +0000
commit814bc89d4635f101b2c0077598f31aad95ed15b7 (patch)
tree407a49dbaf446af4751f5068607a7fb8dad0611d /testsuite/systemtap.samples
parent6b6d04673a1ef175821afc7d4fabdb496698e8e3 (diff)
downloadsystemtap-steved-814bc89d4635f101b2c0077598f31aad95ed15b7.tar.gz
systemtap-steved-814bc89d4635f101b2c0077598f31aad95ed15b7.tar.xz
systemtap-steved-814bc89d4635f101b2c0077598f31aad95ed15b7.zip
2006-08-12 Frank Ch. Eigler <fche@elastic.org>
* configure.ac, Makefile.am: Descend into testsuite/ directory. Remove local test logic. * configure, Makefile.in: Regenerated. * runtest.sh: Not yet removed. * HACKING: Update for new testsuite layout. 2006-08-12 Frank Ch. Eigler <fche@elastic.org> * all: Reorganized old pass-1..4 tests one dejagnu bucket. Moved over old pass-5 tests, except for disabled syscalls tests. * Makefile (installcheck): New target for running pass-1..5 tests against installed systemtap.
Diffstat (limited to 'testsuite/systemtap.samples')
-rw-r--r--testsuite/systemtap.samples/args.exp72
-rw-r--r--testsuite/systemtap.samples/args.stp9
-rw-r--r--testsuite/systemtap.samples/arith.exp14
-rw-r--r--testsuite/systemtap.samples/arith.stp79
-rw-r--r--testsuite/systemtap.samples/arith_limits.exp13
-rw-r--r--testsuite/systemtap.samples/arith_limits.stp81
-rw-r--r--testsuite/systemtap.samples/control_limits.exp42
-rw-r--r--testsuite/systemtap.samples/control_limits.stp24
-rw-r--r--testsuite/systemtap.samples/ioblocktest.exp12
-rw-r--r--testsuite/systemtap.samples/ioblocktest.stp14
-rw-r--r--testsuite/systemtap.samples/iotask.stp45
-rw-r--r--testsuite/systemtap.samples/iotask2.stp42
-rw-r--r--testsuite/systemtap.samples/kmalloc-stacks.stp35
-rwxr-xr-xtestsuite/systemtap.samples/kmalloc-top97
-rw-r--r--testsuite/systemtap.samples/pfaults.exp17
-rw-r--r--testsuite/systemtap.samples/pfaults.stp64
-rw-r--r--testsuite/systemtap.samples/poll_map.exp14
-rwxr-xr-xtestsuite/systemtap.samples/poll_map.stp33
-rw-r--r--testsuite/systemtap.samples/primes.exp21
-rw-r--r--testsuite/systemtap.samples/primes.stp21
-rw-r--r--testsuite/systemtap.samples/profile.exp14
-rw-r--r--testsuite/systemtap.samples/profile.stp38
-rw-r--r--testsuite/systemtap.samples/queue_demo.exp13
-rw-r--r--testsuite/systemtap.samples/queue_demo.stp32
-rw-r--r--testsuite/systemtap.samples/scf.stp25
-rw-r--r--testsuite/systemtap.samples/scf2.stp13
-rw-r--r--testsuite/systemtap.samples/symbols.exp14
-rw-r--r--testsuite/systemtap.samples/symbols.stp11
-rw-r--r--testsuite/systemtap.samples/syscalls.stp7
-rw-r--r--testsuite/systemtap.samples/syscalls1.exp14
-rw-r--r--testsuite/systemtap.samples/syscalls2.exp14
-rw-r--r--testsuite/systemtap.samples/sysopen.exp12
-rw-r--r--testsuite/systemtap.samples/sysopen.stp9
-rw-r--r--testsuite/systemtap.samples/tcp_connections.stp49
-rw-r--r--testsuite/systemtap.samples/tcp_connections_wa.stp55
-rw-r--r--testsuite/systemtap.samples/tcptest.exp12
-rw-r--r--testsuite/systemtap.samples/tcptest.stp73
-rw-r--r--testsuite/systemtap.samples/topsys.stp69
-rwxr-xr-xtestsuite/systemtap.samples/transport-counts38
-rw-r--r--testsuite/systemtap.samples/transport.exp73
-rw-r--r--testsuite/systemtap.samples/transport1.stp32
-rw-r--r--testsuite/systemtap.samples/transport2.stp33
42 files changed, 1399 insertions, 0 deletions
diff --git a/testsuite/systemtap.samples/args.exp b/testsuite/systemtap.samples/args.exp
new file mode 100644
index 00000000..14f19f17
--- /dev/null
+++ b/testsuite/systemtap.samples/args.exp
@@ -0,0 +1,72 @@
+set test "args"
+if {![installtest_p]} { untested $test; return }
+
+set stappath [exec which stap]
+set stpdpath [exec dirname $stappath]/../libexec/systemtap/stpd
+
+if [file exists $stpdpath] {
+ pass "$test search for stpd ($stpdpath)"
+} else {
+ fail "$test search for stpd"
+ return
+}
+
+set modname "args_[pid]"
+spawn stap -k -p4 -m $modname $srcdir/$subdir/args.stp
+set tmpdir NO_SUCH_FILE
+expect {
+ -timeout 30
+ -re {Keeping temporary directory "([/a-zA-Z0-9_]*)"} { pass "$test compile";
+ set tmpdir $expect_out(1,string) }
+ timeout { fail "$test compile (timeout)" }
+ eof { }
+}
+catch {close}; wait
+if [file exists $tmpdir] {
+ pass "$test search for tmpdir ($tmpdir)"
+} else {
+ fail "$test search for tmpdir"
+ return
+}
+
+set modpath "$tmpdir/$modname.ko"
+if [file exists $modpath] {
+ pass "$test search for probe module ($modpath)"
+} else {
+ fail "$test search for probe module"
+ return
+}
+
+spawn sudo $stpdpath -r -d [pid] $modpath foo=hello bar=999
+set ok 0
+expect {
+ -timeout 30
+ -re {foo=hello bar=999} { incr ok }
+ timeout { }
+ eof { }
+}
+catch {close}; wait
+if {$ok == 1} {
+ pass "$test run 1"
+} else {
+ fail "$test run 1"
+}
+
+spawn sudo $stpdpath -r -d [pid] $modpath foo=goodbye bar=0
+set ok 0
+expect {
+ -timeout 30
+ -re {foo=goodbye bar=0} { incr ok }
+ timeout { }
+ eof { }
+}
+catch {close}; wait
+if {$ok == 1} {
+ pass "$test run 2"
+} else {
+ fail "$test run 2"
+}
+
+
+
+exec /bin/rm -rf $tmpdir
diff --git a/testsuite/systemtap.samples/args.stp b/testsuite/systemtap.samples/args.stp
new file mode 100644
index 00000000..85e731ac
--- /dev/null
+++ b/testsuite/systemtap.samples/args.stp
@@ -0,0 +1,9 @@
+#! stap
+
+global foo, bar
+
+probe begin {
+ log ("foo=" . foo . " bar=" . sprint (bar+0 /* cast bar to integer */))
+ exit ()
+}
+
diff --git a/testsuite/systemtap.samples/arith.exp b/testsuite/systemtap.samples/arith.exp
new file mode 100644
index 00000000..cd00ab71
--- /dev/null
+++ b/testsuite/systemtap.samples/arith.exp
@@ -0,0 +1,14 @@
+set test "arith"
+if {![installtest_p]} { untested $test; return }
+
+spawn stap -DMAXNESTING=5 $srcdir/$subdir/arith.stp
+set ok 0
+expect {
+ -timeout 30
+ -re {passes: [0-9]* failures: 0} { incr ok }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+close
+wait
+if {$ok == 1} { pass "$test" } { fail "$test" }
diff --git a/testsuite/systemtap.samples/arith.stp b/testsuite/systemtap.samples/arith.stp
new file mode 100644
index 00000000..80f0c040
--- /dev/null
+++ b/testsuite/systemtap.samples/arith.stp
@@ -0,0 +1,79 @@
+global testno, passes, failures
+
+function test (v,n1,n2) {
+ if (n1 == n2) {
+ passes ++
+ result = "pass"
+ } else {
+ failures ++
+ result = "fail"
+ }
+ log ("test " . (sprint (++testno)) . " [" . v . "]\t" . result)
+}
+
+function stest (v,n1,n2) {
+ if (n1 == n2) {
+ passes ++
+ result = "pass"
+ } else {
+ failures ++
+ result = "fail"
+ }
+ log ("test " . (sprint (++testno)) . " [" . v . "]\t" . result)
+}
+
+
+probe begin {
+ test ("+", 0, 0+0)
+ test ("+", 33339999, 33330000+9999)
+ test ("-", -1, 2-3)
+ test ("==", 1, -1==-1)
+ test ("!=", 1, -1!=1)
+ test ("== s", 1, "foobar"=="foobar")
+ test ("<= s", 1, "fooban"<="foobar")
+ test ("> s", 1, "xxx">"aaa")
+ test ("<", 1, -1<0)
+ test ("<", 1, 85723838<8273823892)
+ test ("*", 100300400500, 1003004005 * 100)
+ test ("*", -1*-500, 500)
+ test ("/", 1003004005/1000, 1003004)
+ test ("%", 1003004005%1000, 5)
+ test ("/", -1/-1, 1)
+ test ("%", -1%-1, 0)
+ test ("/", 0/-100, 0)
+ test ("%", 0%-100, 0)
+ test ("/", (-2147483647-1)/-1, 2147483648)
+ test ("%", (-2147483647-1)%-1, 0)
+ # but (-9223372036854775807-1)/-1 may overflow
+ test ("%", (-9223372036854775807-1)%-1, 0)
+ test ("&", 0x555&0xaaa, 0)
+ test ("|", 0x555|0xaaa, 0xfff)
+ test ("^", 0x55f^0xaaf, 0xff0)
+ test ("&&", 0x555&&0xaaa, 1)
+ test ("||", 0x555||0xaaa, 1)
+ test ("<<", 0<<5, 0)
+ test ("<<", 1<<8, 0x100)
+ test ("<<", 120<<-2, 120)
+ test ("<<", 120<<0, 120)
+ test ("<<", -4096<<-3, -4096)
+ test (">>", -4096>>3, -512)
+ test (">>", -4096>>-3, -4096)
+ test (">>", 120>>-2, 120)
+ test (">>", 120>>0, 120)
+ i=1; test ("--i", --i, 0)
+ i=1; test ("++i", ++i, 2)
+ i=1; test ("i--", i--, 1)
+ i=1; test ("i++", i++, 1)
+ i=1; test ("+=", i+=4, 5) test ("after +=", i, 5)
+ i=5; test ("/=", i/=2, 2) test ("after /=", i, 2)
+ a="1" b="2"; stest (".=", a .= b, "12") stest ("after .=", a, "12")
+}
+
+
+probe timer.jiffies(1) { # some time after all the begin probes
+ exit ()
+}
+
+probe end {
+ log ("passes: " . sprint(passes) . " failures: " . sprint(failures))
+}
diff --git a/testsuite/systemtap.samples/arith_limits.exp b/testsuite/systemtap.samples/arith_limits.exp
new file mode 100644
index 00000000..d60308c6
--- /dev/null
+++ b/testsuite/systemtap.samples/arith_limits.exp
@@ -0,0 +1,13 @@
+set test "arith"
+if {![installtest_p]} { untested $test; return }
+
+spawn stap -DMAXNESTING=5 $srcdir/$subdir/arith_limits.stp
+set ok 0
+expect {
+ -timeout 30
+ -re {passes: [0-9]* failures: 0} { incr ok }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+wait
+if {$ok == 1} { pass "$test" } { fail "$test" }
diff --git a/testsuite/systemtap.samples/arith_limits.stp b/testsuite/systemtap.samples/arith_limits.stp
new file mode 100644
index 00000000..f38a5a68
--- /dev/null
+++ b/testsuite/systemtap.samples/arith_limits.stp
@@ -0,0 +1,81 @@
+global testno, passes, failures
+
+function test (v,n1,n2) {
+ if (n1 == n2) {
+ passes ++
+ result = "pass"
+ } else {
+ failures ++
+ result = "fail"
+ }
+ log ("test " . (sprint (testno++)) . " [" . v . "]\t\t" . result)
+}
+
+# Exactly the same as test() except it will magically work for strings.
+# Wouldn't it be nice if we didn't have to do this?
+
+function teststr (v,n1,n2) {
+ if (n1 == n2) {
+ passes ++
+ result = "pass"
+ } else {
+ failures ++
+ result = "fail"
+ }
+ log ("test " . (sprint (testno++)) . " [" . v . "]\t\t" . result)
+}
+
+
+
+probe begin {
+ # max/minimum signed 32-bit values.
+ # these could cause problems for 32-bit cpus when overflows
+ # occur into 64-but values
+ lmax = 0x7fffffff
+ lmin = -0x80000000
+
+ # max/minimum signed 64-bit values
+ llmax = 0x7fffffffffffffff
+ llmin = -0x7fffffffffffffff-1
+
+ # 32-bit limit tests
+ teststr ("string lmax", sprint(lmax), "2147483647")
+ teststr ("hex lmax", sprintf("0x%x", lmax), "0x7fffffff")
+ teststr ("string lmin", sprint(lmin), "-2147483648")
+ teststr ("hex lmin", sprintf("0x%x", lmin), "0xffffffff80000000")
+ test ("lmax/-1", lmax/-1, -2147483647);
+ test ("lmin/-1", lmin/-1, 2147483648);
+ test ("lmax +1", lmax+1, 2147483648);
+ test ("lmin -1", lmin-1, -2147483649);
+
+ # 64-bit limits
+ teststr ("string llmax", sprint(llmax), "9223372036854775807")
+ teststr ("hex llmax", sprintf("0x%x", llmax), "0x7fffffffffffffff")
+ teststr ("string llmin", sprint(llmin), "-9223372036854775808")
+ teststr ("hex llmin", sprintf("0x%x", llmin), "0x8000000000000000")
+ test ("llmax/-1", llmax/-1, -llmax)
+ test ("llmax*-1", llmax*-1, -llmax)
+
+ # the next three overflow and produce predictable, although
+ # wrong results
+ test ("llmin/-1", llmin/-1, llmin)
+ test ("llmin*-1", llmin*-1, llmin)
+ test ("llmax +1", llmax+1, llmin)
+ test ("llmin -1", llmin-1, llmax)
+
+ # modulo tests
+ test ("llmax%1", llmax%1, 0)
+ test ("llmin%1", llmin%1, 0)
+ test ("0%1 ", 0%1, 0)
+ test ("0%lmax", 0%lmax, 0)
+ test ("1%lmax", 1%lmax, 1)
+ test ("0%lmin", 0%lmin, 0)
+ test ("1%lmin", 1%lmin, 1)
+
+ exit()
+}
+
+probe end {
+ print ("passes: " . sprint(passes))
+ print (" failures: " . sprint(failures). "\n")
+}
diff --git a/testsuite/systemtap.samples/control_limits.exp b/testsuite/systemtap.samples/control_limits.exp
new file mode 100644
index 00000000..d0ad7d2d
--- /dev/null
+++ b/testsuite/systemtap.samples/control_limits.exp
@@ -0,0 +1,42 @@
+set test "control_limits MAXNESTING"
+if {![installtest_p]} { untested $test; return }
+
+spawn stap -u -DMAXNESTING=5 $srcdir/$subdir/control_limits.stp
+set ok 0
+expect {
+ -timeout 60 -re {ERROR.*MAXNESTING} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+if {$ok == 1} { pass "$test ($ok)" } { fail "$test ($ok)" }
+
+set test "control_limits MAXACTION"
+spawn stap -u -DMAXACTION=500 $srcdir/$subdir/control_limits.stp
+set ok 0
+expect {
+ -timeout 60 -re {ERROR.*MAXACTION} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+if {$ok == 1} { pass "$test ($ok)" } { fail "$test ($ok)" }
+
+set test "control_limits MAXSTRINGLEN small"
+spawn stap -u -DMAXSTRINGLEN=50 $srcdir/$subdir/control_limits.stp
+set ok 0
+expect {
+ -timeout 60 -re {ERROR.*MAXSTRINGLEN reduced} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+if {$ok == 1} { pass "$test ($ok)" } { fail "$test ($ok)" }
+
+set test "control_limits MAXSTRINGLEN large"
+spawn stap -u -DMAXSTRINGLEN=500 $srcdir/$subdir/control_limits.stp
+set ok 0
+expect {
+ -timeout 60 -re {ERROR.*MAXSTRINGLEN enlarged} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+if {$ok == 1} { pass "$test ($ok)" } { fail "$test ($ok)" }
+
diff --git a/testsuite/systemtap.samples/control_limits.stp b/testsuite/systemtap.samples/control_limits.stp
new file mode 100644
index 00000000..89b0bae4
--- /dev/null
+++ b/testsuite/systemtap.samples/control_limits.stp
@@ -0,0 +1,24 @@
+
+# for MAXNESTING testing
+function recurse (n) {
+ if (n > 0) recurse (n-1)
+}
+probe begin {
+ recurse (7)
+}
+
+# for MAXACTION testing
+probe begin {
+ for (i=0; i<498; i++) {}
+}
+
+# for MAXSTRINGLEN testing
+probe begin {
+ s = "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678" # last 8 will be \0'd
+ if (strlen(s) < 127) error ("MAXSTRINGLEN reduced")
+ if (strlen(s) > 127) error ("MAXSTRINGLEN enlarged")
+}
+
+
+probe begin { exit () }
+
diff --git a/testsuite/systemtap.samples/ioblocktest.exp b/testsuite/systemtap.samples/ioblocktest.exp
new file mode 100644
index 00000000..43c44f5e
--- /dev/null
+++ b/testsuite/systemtap.samples/ioblocktest.exp
@@ -0,0 +1,12 @@
+# Test the functionality of the various ioblock probes.
+
+load_lib "stap_run.exp"
+set test "ioblocktest"
+
+proc sleep_ten_secs {} {
+ after 10000;
+ return 0;
+}
+
+set output_string "\\mioblock*"
+stap_run $srcdir/$subdir/$test.stp sleep_ten_secs $output_string
diff --git a/testsuite/systemtap.samples/ioblocktest.stp b/testsuite/systemtap.samples/ioblocktest.stp
new file mode 100644
index 00000000..1386903c
--- /dev/null
+++ b/testsuite/systemtap.samples/ioblocktest.stp
@@ -0,0 +1,14 @@
+#! stap
+global teststr
+probe begin { log("systemtap starting probe") }
+
+probe ioblock.request {
+ teststr = sprintf("ioblock: %s\t%d\t%s\t%d\n", devname, sector, bio_rw_str(rw), rw)
+}
+probe ioblock.end {
+ teststr = sprintf("ioblock: %s\t%d\t%s\t%d\n", devname, sector, bio_rw_str(rw), rw)
+}
+probe end {
+ log("systemtap ending probe")
+ printf("%s\n", teststr)
+}
diff --git a/testsuite/systemtap.samples/iotask.stp b/testsuite/systemtap.samples/iotask.stp
new file mode 100644
index 00000000..13d273a3
--- /dev/null
+++ b/testsuite/systemtap.samples/iotask.stp
@@ -0,0 +1,45 @@
+# iotask.stp
+# A reimplementation of user script: iotask.stp given at OLS 2005
+# in the current language.
+#
+# Will Cohen
+# 9/22/2005
+
+global names, opens
+global reads, read_bytes
+global writes, write_bytes
+
+probe kernel.function("sys_open") {
+ ++names[execname()]; ++opens[execname()];
+}
+
+probe kernel.function("sys_read") {
+ ++names[execname()]; ++reads[execname()];
+ read_bytes[execname()] += $count;
+}
+
+probe kernel.function("sys_write") {
+ ++names[execname()]; ++writes[execname()];
+ write_bytes[execname()] += $count;
+}
+
+probe begin { log( "starting probe" ); }
+
+probe end {
+ foreach( name in names){
+ log ("process: " . name);
+ if (opens[name])
+ log( "opens n=" . sprint(opens[name]));
+ if ( reads[name]){
+ count = reads[name]; total=read_bytes[name];
+ log("reads n, sum, avg=". sprint(count)
+ . "," . sprint(total) . "," . sprint(total/count));
+ }
+ if (writes[name]){
+ count = writes[name]; total=write_bytes[name];
+ log("writes n, sum, avg=". sprint(count)
+ . "," . sprint(total) . "," . sprint(total/count));
+ }
+ log("");
+ }
+}
diff --git a/testsuite/systemtap.samples/iotask2.stp b/testsuite/systemtap.samples/iotask2.stp
new file mode 100644
index 00000000..1f3248e3
--- /dev/null
+++ b/testsuite/systemtap.samples/iotask2.stp
@@ -0,0 +1,42 @@
+global names, opens, reads, writes
+
+probe begin { log("starting probe") }
+
+probe timer.ms(10000) {
+ log("stopping probe after 10 seconds")
+ exit()
+}
+
+probe kernel.function("sys_open") {
+ e=execname(); names[e]=1
+ opens[e] ++ # simple integer array
+}
+
+probe kernel.function("sys_read") {
+ e=execname(); names[e]=1
+ reads[e] <<< $count # statistics array
+}
+
+probe kernel.function("sys_write") {
+ e=execname(); names[e]=1
+ writes[e] <<< $count # statistics array
+}
+
+
+probe end {
+ foreach (name+ in names) { # sort by name
+ printf("process: %s\n", name)
+ if (opens[name])
+ printf("opens n=%d\n", opens[name])
+ if (@count(reads[name]))
+ printf("reads n=%d, sum=%d, avg=%d\n",
+ @count(reads[name]), # extracting stat results
+ @sum(reads[name]),
+ @avg(reads[name]))
+ if (@count(writes[name]))
+ printf("writes n=%d, sum=%d, avg=%d\n",
+ @count(writes[name]), # extracting stat results
+ @sum(writes[name]),
+ @avg(writes[name]))
+ }
+}
diff --git a/testsuite/systemtap.samples/kmalloc-stacks.stp b/testsuite/systemtap.samples/kmalloc-stacks.stp
new file mode 100644
index 00000000..25a23f2d
--- /dev/null
+++ b/testsuite/systemtap.samples/kmalloc-stacks.stp
@@ -0,0 +1,35 @@
+global kmalloc_stack
+
+function reset_maxaction () %{
+ if (CONTEXT && CONTEXT->actioncount)
+ CONTEXT->actioncount=0;
+%}
+
+function write_output()
+{
+ foreach (stack in kmalloc_stack) {
+ log("<hashkey>");
+ print_stack(stack);
+ log("</hashkey>");
+ print("<hashval>");
+ print(sprint(kmalloc_stack[stack]));
+ log("</hashval>");
+ reset_maxaction();
+ }
+}
+
+probe timer.jiffies(5000)
+{
+ write_output();
+ delete kmalloc_stack;
+}
+
+probe kernel.function("__kmalloc")
+{
+ kmalloc_stack[backtrace()]++;
+}
+
+probe end
+{
+ write_output();
+}
diff --git a/testsuite/systemtap.samples/kmalloc-top b/testsuite/systemtap.samples/kmalloc-top
new file mode 100755
index 00000000..42a6d152
--- /dev/null
+++ b/testsuite/systemtap.samples/kmalloc-top
@@ -0,0 +1,97 @@
+#!/usr/bin/perl
+#
+# This script accumulates the execution paths of all calls to kmalloc
+# in the kernel. On Ctrl-C, it sorts, filters and displays them on
+# stdout.
+#
+# The -e (exclude) option can be used to specify a comma-separated list
+# - any stack with contents matching any of the items in the list will
+# be excluded from the output.
+#
+# The -m (min) option can be used to specify the minimum number of
+# occurrences a stack needs to be included in the output.
+#
+# Usage: ./kmalloc-top [-m min] [-i exclude list]
+# Ctrl-c
+
+use Getopt::Std;
+
+my $kmalloc_stacks;
+my $total_kmallocs;
+my $sorted_stacks;
+my $min_count = 1;
+my $exclude;
+
+$SIG{INT} = \&sigint_handler;
+
+getopts('e:m:');
+
+if ($opt_e) {
+ $exclude = join('|', split(/,/, $opt_e));
+ print "Will exclude stacks containing: $exclude\n";
+}
+
+if ($opt_m) {
+ $min_count = $opt_n;
+}
+print "Will print stacks with counts >= $min_count.\n";
+print STDERR "Press Ctrl-C to stop.\n";
+
+open STREAM, "stap -g kmalloc-stacks.stp |" or die "Couldn't get output stream $!";
+
+while (<STREAM>) {
+ if (/<hashval>(.*?)<\/hashval>/) {
+ update_hash($key, $1);
+ $key = "";
+ } elsif ($_ !~ (/<hashkey>|<\/hashkey>/)) {
+ $key .= $_;
+ }
+}
+
+$num_keys_before_filtering = scalar keys %kmalloc_stacks;
+filter_stacks();
+$num_keys_after_filtering = scalar keys %kmalloc_stacks;
+sort_stacks();
+summarize();
+exit();
+
+sub update_hash
+{
+ my($key, $val) = @_;
+ $kmalloc_stacks{$key} += $val;
+ $total_kmallocs += $val;
+}
+
+sub filter_stacks
+{
+ while (($stack, $count) = each %kmalloc_stacks) {
+ if ($count < $min_count) {
+ delete $kmalloc_stacks{$stack};
+ } elsif ($exclude && $stack =~ /$exclude/) {
+ delete $kmalloc_stacks{$stack};
+ }
+ }
+}
+
+sub sort_stacks
+{
+ @sorted_stacks = sort { $kmalloc_stacks{$b} <=> $kmalloc_stacks{$a} } keys %kmalloc_stacks;
+}
+
+sub summarize {
+ print "\n";
+ foreach $stack(@sorted_stacks) {
+ print "This path seen $kmalloc_stacks{$stack} times:\n$stack\n";
+ }
+
+ print "Total kmallocs (before filtering): $total_kmallocs\n";
+ print "Num stacks before filtering: $num_keys_before_filtering\n";
+ print "Num stacks after filtering: $num_keys_after_filtering\n";
+
+ close(STREAM);
+}
+
+sub sigint_handler
+{
+ system("pkill kmalloc-stacks");
+}
diff --git a/testsuite/systemtap.samples/pfaults.exp b/testsuite/systemtap.samples/pfaults.exp
new file mode 100644
index 00000000..b230cc6a
--- /dev/null
+++ b/testsuite/systemtap.samples/pfaults.exp
@@ -0,0 +1,17 @@
+set test "pfaults"
+if {![installtest_p]} { untested $test; return }
+
+spawn stap -g $srcdir/$subdir/pfaults.stp
+set pid $spawn_id
+set ok 0
+expect {
+ -timeout 30
+ -re "Page fault tracking, start time" { incr ok; exp_continue }
+ -timeout 30
+ -re "Page fault tracking, end time" { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+#FIXME does not handle case of hanging pfaults.stp correctly
+wait
+if {$ok == 2} { pass "$test ($ok)" } { fail "$test ($ok)" }
diff --git a/testsuite/systemtap.samples/pfaults.stp b/testsuite/systemtap.samples/pfaults.stp
new file mode 100644
index 00000000..753409ba
--- /dev/null
+++ b/testsuite/systemtap.samples/pfaults.stp
@@ -0,0 +1,64 @@
+#! stap
+
+global pidnames, faults, fault_types
+
+probe kernel.function(%( kernel_v > "2.6.9" %? "__handle_mm_fault"
+ %: "handle_mm_fault" %)) {
+
+ # Maintain a pid-to-execname mapping. This logic should get transplanted
+ # into a tapset script that is automatically included upon reference to
+ # its exported global variable.
+ pidnames[pid()] = execname()
+
+ faults [pid(), $write_access ? 1 : 0] ++
+}
+
+# (needed only until bug 1132 supports $retvalue)
+function get_retvalue:long () %{ THIS->__retvalue = fetch_register(0); %}
+
+probe kernel.function(%( kernel_v > "2.6.9" %? "__handle_mm_fault"
+ %: "handle_mm_fault" %)).return {
+ fault_types [pid(), get_retvalue()] ++
+}
+
+
+# Some constants, to come from a future "VM tapset"
+
+global VM_FAULT_OOM, VM_FAULT_SIGBUS, VM_FAULT_MINOR, VM_FAULT_MAJOR
+probe begin {
+ VM_FAULT_OOM=-1
+ VM_FAULT_SIGBUS=0
+ VM_FAULT_MINOR=1
+ VM_FAULT_MAJOR=2
+}
+
+
+# Shut down the probing session after a while
+probe timer.ms(1000) { report() }
+probe timer.ms(10000) { exit() }
+
+function _(n) { return sprint(n) } # let's abbreviate
+
+function report () {
+ print ("time=" . _(gettimeofday_s()) . "\n")
+ foreach ([pid] in pidnames) {
+ if (faults[pid,0]+faults[pid,1] == 0) continue
+ print (pidnames[pid] . "[" . _(pid) . "]" .
+ " reads=" . _(faults[pid,0]) .
+ " writes=" . _(faults[pid,1]) .
+ " oom=" . _(fault_types[pid,VM_FAULT_OOM]) .
+ " sigbus=" . _(fault_types[pid,VM_FAULT_SIGBUS]) .
+ " minor=" . _(fault_types[pid,VM_FAULT_MINOR]) .
+ " major=" . _(fault_types[pid,VM_FAULT_MAJOR]) .
+ "\n")
+ }
+ delete faults
+ delete fault_types
+}
+
+probe begin {
+ print ("Page fault tracking, start time=" . _(gettimeofday_s()) . "\n")
+}
+probe end {
+ print ("Page fault tracking, end time=" . _(gettimeofday_s()) . "\n")
+}
diff --git a/testsuite/systemtap.samples/poll_map.exp b/testsuite/systemtap.samples/poll_map.exp
new file mode 100644
index 00000000..6e26380a
--- /dev/null
+++ b/testsuite/systemtap.samples/poll_map.exp
@@ -0,0 +1,14 @@
+set test "poll_map"
+if {![installtest_p]} { untested $test; return }
+
+spawn stap -g $srcdir/$subdir/poll_map.stp
+set ok 0
+expect {
+ -timeout 90
+ -ex "SUCCESS" { incr ok }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+close
+wait
+if {$ok == 1} { pass "$test ($ok)" } { fail "$test ($ok)" }
diff --git a/testsuite/systemtap.samples/poll_map.stp b/testsuite/systemtap.samples/poll_map.stp
new file mode 100755
index 00000000..ba494ddb
--- /dev/null
+++ b/testsuite/systemtap.samples/poll_map.stp
@@ -0,0 +1,33 @@
+#! stap
+
+# test that polling loops do not exit when conflicts happen
+# see PR 1379
+
+global called, num_polls
+
+probe kernel.function( "sys_*" ) {
+ called[execname(),name]++
+}
+
+probe timer.ms(1000)
+{
+ print("\n\n")
+ num_to_do = 10
+ foreach ([n,f] in called-) {
+ printf("%s called %s\t%d times\n", n, f, called[n,f])
+ num_to_do--
+ if (num_to_do <= 0)
+ break
+ }
+ delete called
+ num_polls++
+ if (num_polls > 30)
+ exit()
+}
+
+probe end {
+ if (num_polls <= 30)
+ print ("FAIL\n")
+ else
+ print ("SUCCESS\n")
+}
diff --git a/testsuite/systemtap.samples/primes.exp b/testsuite/systemtap.samples/primes.exp
new file mode 100644
index 00000000..5381494d
--- /dev/null
+++ b/testsuite/systemtap.samples/primes.exp
@@ -0,0 +1,21 @@
+set test "primes"
+if {![installtest_p]} { untested $test; return }
+
+spawn stap $srcdir/$subdir/primes.stp
+set ok 0
+expect {
+ -timeout 30
+ -ex {odds[0] = 1} { incr ok; exp_continue }
+ -ex {odds[1] = 3} { incr ok; exp_continue }
+ -ex {odds[3] = 7} { incr ok; exp_continue }
+ -ex {odds[4] = 9} { incr ok; exp_continue }
+ -ex {evens[2] = 6} { incr ok; exp_continue }
+ -ex {evens[1] = 4} { incr ok; exp_continue }
+ -ex {evens[0] = 2} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+#FIXME does not handle case of hanging primes.stp correctly
+wait
+
+if {$ok == 7} { pass "$test" } { fail "$test" }
diff --git a/testsuite/systemtap.samples/primes.stp b/testsuite/systemtap.samples/primes.stp
new file mode 100644
index 00000000..7e7aeb37
--- /dev/null
+++ b/testsuite/systemtap.samples/primes.stp
@@ -0,0 +1,21 @@
+#! stap
+global odds, evens
+probe begin {
+ # "no" and "ne" are local integers
+ for (i=1; 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[" . sprint(x) . "] = " . sprint(odds[x]))
+ }
+ foreach (x in evens-) {
+ log("evens[" . sprint(x) . "] = " . sprint(evens[x]))
+ }
+}
diff --git a/testsuite/systemtap.samples/profile.exp b/testsuite/systemtap.samples/profile.exp
new file mode 100644
index 00000000..39b4587f
--- /dev/null
+++ b/testsuite/systemtap.samples/profile.exp
@@ -0,0 +1,14 @@
+set test "profile"
+if {![installtest_p]} { untested $test; return }
+
+spawn stap $srcdir/$subdir/profile.stp
+set ok 0
+expect {
+ -timeout 30 -re {kernel.function[^\r]*ttime=[0-9]*\r} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+#FIXME does not handle case of hanging primes.stp correctly
+wait
+
+if {$ok > 0} { pass "$test ($ok)" } { fail "$test" }
diff --git a/testsuite/systemtap.samples/profile.stp b/testsuite/systemtap.samples/profile.stp
new file mode 100644
index 00000000..1a93153d
--- /dev/null
+++ b/testsuite/systemtap.samples/profile.stp
@@ -0,0 +1,38 @@
+#! stap
+
+global command, syscall_count, syscall_times, this_syscall_time, this_syscall
+
+function accumulate () {
+ pid = pid()
+ if (! ([pid] in command)) command[pid] = execname()
+ syscall=pp() # just the substring ideally
+ syscall_count[pid,syscall] ++
+ this_syscall[pid] = syscall
+ this_syscall_time[pid] = gettimeofday_us()
+}
+function decumulate () {
+ pid = pid()
+ syscall = this_syscall[pid]
+ syscall_times[pid,syscall] +=
+ gettimeofday_us() - this_syscall_time[pid]
+ # free up memory
+ this_syscall[pid] = ""
+ this_syscall_time[pid] = 0
+}
+probe kernel.function("sys_*") {
+ accumulate ()
+}
+probe kernel.function("sys_*").return {
+ decumulate ()
+}
+probe timer.ms(5000) {
+ exit ()
+}
+probe end {
+ foreach ([pid,syscall] in syscall_count-) {
+ log (command[pid] . "(" . sprint(pid) . ") " . syscall .
+ " count=" . sprint(syscall_count[pid,syscall]) .
+ " ttime=" . sprint(syscall_times[pid,syscall]))
+ if (count++ > 30) next
+ }
+}
diff --git a/testsuite/systemtap.samples/queue_demo.exp b/testsuite/systemtap.samples/queue_demo.exp
new file mode 100644
index 00000000..71feddd6
--- /dev/null
+++ b/testsuite/systemtap.samples/queue_demo.exp
@@ -0,0 +1,13 @@
+set test "queue_demo"
+if {![installtest_p]} { untested $test; return }
+
+spawn stap $srcdir/$subdir/queue_demo.stp
+set ok 0
+expect {
+ -timeout 30
+ -re {block-[^\r]*} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+
+if {$ok > 4 && $ok < 10} { pass "$test" } { fail "$test" }
diff --git a/testsuite/systemtap.samples/queue_demo.stp b/testsuite/systemtap.samples/queue_demo.stp
new file mode 100644
index 00000000..61a3b6d1
--- /dev/null
+++ b/testsuite/systemtap.samples/queue_demo.stp
@@ -0,0 +1,32 @@
+
+probe begin {
+ qsq_start ("block-read")
+ qsq_start ("block-write")
+}
+
+probe timer.ms(3500), end {
+ qsq_print ("block-read")
+ qsq_start ("block-read")
+ qsq_print ("block-write")
+ qsq_start ("block-write")
+}
+
+probe timer.ms(10000) { exit () }
+
+
+# synthesize queue work/service using three randomized "threads" for each queue.
+
+global tc
+function qs_doit (thread, name) {
+ n = tc[thread] = (tc[thread]+1) % 3 # per-thread state counter
+ if (n==1) qs_wait (name)
+ else if (n==2) qs_run (name)
+ else if (n==0) qs_done (name)
+}
+
+probe timer.ms(100).randomize(100) { qs_doit (0, "block-read") }
+probe timer.ms(100).randomize(100) { qs_doit (1, "block-read") }
+probe timer.ms(100).randomize(100) { qs_doit (2, "block-read") }
+probe timer.ms(100).randomize(100) { qs_doit (3, "block-write") }
+probe timer.ms(100).randomize(100) { qs_doit (4, "block-write") }
+probe timer.ms(100).randomize(100) { qs_doit (5, "block-write") }
diff --git a/testsuite/systemtap.samples/scf.stp b/testsuite/systemtap.samples/scf.stp
new file mode 100644
index 00000000..1108fdea
--- /dev/null
+++ b/testsuite/systemtap.samples/scf.stp
@@ -0,0 +1,25 @@
+# scf.stp
+# A reimplementation of user script:smp_call_function example given at OLS 2005
+# in the current language.
+#
+# Will Cohen
+# 9/22/2005
+
+global traces
+
+probe kernel.function("smp_call_function")
+{
+ traces[pid(), pexecname(), backtrace()] += 1;
+}
+
+probe begin { print( "starting probe\n" ); }
+
+probe end {
+ print("end of data collection\n");
+ foreach( [pid, name, stack] in traces){
+ print( "traces[" . sprint(pid) . "," . name . ",\n" );
+ print_stack(stack)
+ print( "] = " . sprint(traces[pid, name, stack]) );
+ print( "\n" );
+ }
+}
diff --git a/testsuite/systemtap.samples/scf2.stp b/testsuite/systemtap.samples/scf2.stp
new file mode 100644
index 00000000..5ad46350
--- /dev/null
+++ b/testsuite/systemtap.samples/scf2.stp
@@ -0,0 +1,13 @@
+global traces
+
+probe kernel.function("smp_call_function") {
+ traces[pid(), pexecname(), backtrace()] ++
+}
+probe timer.ms(1000) { exit () }
+probe end {
+ foreach ([pid+, name, stack] in traces) { # sort by pid
+ printf ("traces[%d,%s,\n", pid, name)
+ print_stack (stack)
+ printf ("] = %d\n", traces[pid, name, stack]);
+ }
+}
diff --git a/testsuite/systemtap.samples/symbols.exp b/testsuite/systemtap.samples/symbols.exp
new file mode 100644
index 00000000..52e90e93
--- /dev/null
+++ b/testsuite/systemtap.samples/symbols.exp
@@ -0,0 +1,14 @@
+set test "symbols"
+if {![installtest_p]} { untested $test; return }
+
+spawn stap -g $srcdir/$subdir/symbols.stp
+set ok 0
+expect {
+ -timeout 30
+ -re { 0x[a-f0-9]+[^\r]*\r} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+#FIXME does not handle case of hanging symbols.stp correctly
+wait
+if {$ok == 11} { pass "$test ($ok)" } { fail "$test ($ok)" }
diff --git a/testsuite/systemtap.samples/symbols.stp b/testsuite/systemtap.samples/symbols.stp
new file mode 100644
index 00000000..040c3444
--- /dev/null
+++ b/testsuite/systemtap.samples/symbols.stp
@@ -0,0 +1,11 @@
+#! stap
+
+probe begin {
+ # a spectrum of figures for 32-bit x86
+ print_stack ("0x0 0x80000000 0xc0000000 0xe0000000 0xf0000000 0xffffffff")
+ # for x86_64
+ print_stack ("0xffffffff00000000 0xffffffff80000000 0xffffffff80120000")
+ print_stack ("0xffffffff88000000 0xffffffffffffffff")
+ # ... for a total of 11 lines, which symbols.exp counts
+ exit ()
+}
diff --git a/testsuite/systemtap.samples/syscalls.stp b/testsuite/systemtap.samples/syscalls.stp
new file mode 100644
index 00000000..670b239d
--- /dev/null
+++ b/testsuite/systemtap.samples/syscalls.stp
@@ -0,0 +1,7 @@
+#! stap
+
+global count
+probe kernel.function("sys_*") {
+ print (sprint(pid()) . " " . pp() . "\n")
+ if (++count > 100) exit()
+}
diff --git a/testsuite/systemtap.samples/syscalls1.exp b/testsuite/systemtap.samples/syscalls1.exp
new file mode 100644
index 00000000..edfddf6f
--- /dev/null
+++ b/testsuite/systemtap.samples/syscalls1.exp
@@ -0,0 +1,14 @@
+set test "syscalls-count"
+if {![installtest_p]} { untested $test; return }
+
+spawn stap -p2 $srcdir/$subdir/syscalls.stp
+set ok 0
+expect {
+ -timeout 30
+ -re {kernel.function[^\r]*sys_[^\r]*\r} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+#FIXME does not handle case of hanging psyscalls.stp correctly
+wait
+if {$ok > 200 && $ok < 350} { pass "$test ($ok)" } { fail "$test ($ok)" }
diff --git a/testsuite/systemtap.samples/syscalls2.exp b/testsuite/systemtap.samples/syscalls2.exp
new file mode 100644
index 00000000..c817f23f
--- /dev/null
+++ b/testsuite/systemtap.samples/syscalls2.exp
@@ -0,0 +1,14 @@
+set test "syscalls-run"
+if {![installtest_p]} { untested $test; return }
+spawn stap $srcdir/$subdir/syscalls.stp
+set ok 0
+expect {
+ -timeout 60 -re {[0-9]* kernel.function[^\r]*\r} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+#FIXME does not handle case of hanging psyscalls.stp correctly
+wait
+# 150 is conservative - it's larger than 100 to allow a bit of slop
+# between the exit() call and the actual shutdown
+if {$ok >= 100 && $ok < 150} { pass "$test ($ok)" } { fail "$test ($ok)" }
diff --git a/testsuite/systemtap.samples/sysopen.exp b/testsuite/systemtap.samples/sysopen.exp
new file mode 100644
index 00000000..7f98ff3f
--- /dev/null
+++ b/testsuite/systemtap.samples/sysopen.exp
@@ -0,0 +1,12 @@
+set test "sysopen"
+if {![installtest_p]} { untested $test; return }
+spawn stap $srcdir/$subdir/sysopen.stp
+set ok 0
+expect {
+ -timeout 60 -re {.* opened .*\r} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+#FIXME does not handle case of hanging sysopen.stp correctly
+wait
+if {$ok > 1} { pass "$test ($ok)" } { fail "$test ($ok)" }
diff --git a/testsuite/systemtap.samples/sysopen.stp b/testsuite/systemtap.samples/sysopen.stp
new file mode 100644
index 00000000..58a27b71
--- /dev/null
+++ b/testsuite/systemtap.samples/sysopen.stp
@@ -0,0 +1,9 @@
+#! stap
+
+# pulling out some params has been a problem; see PR 1295
+probe kernel.function("sys_open") {
+ log (execname() . " opened " . user_string($filename))
+}
+probe timer.ms(10000) {
+ exit ()
+}
diff --git a/testsuite/systemtap.samples/tcp_connections.stp b/testsuite/systemtap.samples/tcp_connections.stp
new file mode 100644
index 00000000..a4449b60
--- /dev/null
+++ b/testsuite/systemtap.samples/tcp_connections.stp
@@ -0,0 +1,49 @@
+#! stap
+
+%{
+#include <linux/version.h>
+#include <net/sock.h>
+#include <net/tcp.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+#define LPORT (inet->inet.num)
+#define DADDR (&inet->inet.daddr)
+#else
+#define LPORT (inet->num)
+#define DADDR (&inet->daddr)
+#endif
+%}
+
+function get_local_port:long(sock)
+%{
+ unsigned long ptr = (unsigned long) THIS->sock;
+
+ struct inet_sock *inet = (struct inet_sock *) ptr;
+ THIS->__retvalue = (long long) LPORT;
+%}
+
+function get_ip_source:string(sock)
+%{
+ unsigned long ptr = (unsigned long) THIS->sock;
+ struct inet_sock *inet = (struct inet_sock *) ptr;
+ unsigned char addr[4];
+ memcpy(addr, DADDR, sizeof(addr));
+ sprintf(THIS->__retvalue, "%d.%d.%d.%d",
+ addr[0], addr[1], addr[2], addr[3]);
+
+%}
+
+
+probe begin {
+ log ("UID\tCMD\t\tPID\t\tPORT\tIP_SOURCE")
+}
+
+probe kernel.function("tcp_accept").return {
+ sock = $return
+ if (sock != 0)
+ log(sprint(uid())."\t".
+ execname()."\t\t".
+ sprint(pid())."\t\t ".
+ sprint(get_local_port(sock))."\t".
+ get_ip_source(sock))
+}
diff --git a/testsuite/systemtap.samples/tcp_connections_wa.stp b/testsuite/systemtap.samples/tcp_connections_wa.stp
new file mode 100644
index 00000000..4c5e2399
--- /dev/null
+++ b/testsuite/systemtap.samples/tcp_connections_wa.stp
@@ -0,0 +1,55 @@
+%{
+#include <linux/version.h>
+#include <net/sock.h>
+#include <net/tcp.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+#define LPORT (inet->inet.num)
+#define DADDR (&inet->inet.daddr)
+#else
+#define LPORT (inet->num)
+#define DADDR (&inet->daddr)
+#endif
+%}
+
+
+function get_eax:long () %{
+ if (CONTEXT && CONTEXT->regs)
+ THIS->__retvalue = CONTEXT->regs->eax;
+ else
+ THIS->__retvalue = 0;
+%}
+
+function get_local_port:long(sock)
+%{
+ unsigned long ptr = (unsigned long) THIS->sock;
+
+ struct inet_sock *inet = (struct inet_sock *) ptr;
+ THIS->__retvalue = (long long) LPORT;
+%}
+
+function get_ip_source:string(sock)
+%{
+ unsigned long ptr = (unsigned long) THIS->sock;
+ struct inet_sock *inet = (struct inet_sock *) ptr;
+ unsigned char addr[4];
+ memcpy(addr, DADDR, sizeof(addr));
+ sprintf(THIS->__retvalue, "%d.%d.%d.%d",
+ addr[0], addr[1], addr[2], addr[3]);
+
+%}
+
+probe begin {
+ log ("UID\tCMD\t\tPID\t\tPORT\tIP_SOURCE")
+}
+probe kernel.function("tcp_accept").return {
+ sock = get_eax()
+ if (sock != 0)
+ log(sprint(uid())."\t".
+ execname()."\t\t".
+ sprint(pid())."\t\t ".
+ sprint(get_local_port(sock))."\t".
+ get_ip_source(sock))
+}
+
+
diff --git a/testsuite/systemtap.samples/tcptest.exp b/testsuite/systemtap.samples/tcptest.exp
new file mode 100644
index 00000000..d34cc5f4
--- /dev/null
+++ b/testsuite/systemtap.samples/tcptest.exp
@@ -0,0 +1,12 @@
+# Test the functionality of the tcp probes
+
+load_lib "stap_run.exp"
+set test "tcptest"
+
+proc sleep_ten_secs {} {
+ after 10000;
+ return 0;
+}
+
+set output_string "\\mTCP totalbytes: \\d+\\M"
+stap_run $srcdir/$subdir/$test.stp sleep_ten_secs $output_string
diff --git a/testsuite/systemtap.samples/tcptest.stp b/testsuite/systemtap.samples/tcptest.stp
new file mode 100644
index 00000000..2c88e2c7
--- /dev/null
+++ b/testsuite/systemtap.samples/tcptest.stp
@@ -0,0 +1,73 @@
+#! stap
+global uids, pidnames, send_bytes, recv_bytes, pid_ports, pid_src_ips, pid_rtos
+global pid_state, pid_mss, pid_ssthresh, pid_cwnd, totalbytes
+
+probe begin { log("systemtap starting probe") }
+
+probe end {
+ log("systemtap ending probe")
+ printf("TCP totalbytes: %d\n", totalbytes)
+}
+
+function print_report()
+{
+ lines = 0;
+ log ("UID\tPID\tSIZE\tNAME\t\t\tPORT\tSOURCE\t\tRTO\tRCVMSS\tSSTHRES\tCWND\tSTATE")
+ for (lines = 0; lines <= 21; lines ++) {
+ if (!lines) {
+ foreach (_pid_ in pidnames) {
+ printf("%d\t%d\t%d\t%s\t\t\t%d\t%s\t%d\t%d\t%d\t%d\t%d\n",
+ uids[_pid_],_pid_,send_bytes[_pid_] + recv_bytes[_pid_],
+ pidnames[_pid_],pid_ports[_pid_],
+ pid_src_ips[_pid_],pid_rtos[_pid_], pid_mss[_pid_],
+ pid_ssthresh[_pid_],pid_cwnd[_pid_],pid_state[_pid_]);
+ lines++
+ }
+ } else {
+ print("\n")
+ }
+ }
+}
+
+probe tcp.sendmsg {
+ pid_ports[pid()] = inet_get_local_port(sock)
+ pid_src_ips[pid()] = inet_get_ip_source(sock)
+ pid_rtos[pid()] = tcp_get_info_rto(sock)
+}
+
+probe tcp.recvmsg {
+ pid_cwnd[pid()] = tcp_get_info_snd_cwnd(sock)
+ pid_mss[pid()] = tcp_ts_get_info_rcv_mss(sock)
+ pid_ssthresh[pid()] = tcp_ts_get_info_snd_ssthresh(sock)
+ pid_state[pid()] = tcp_ts_get_info_state(sock)
+}
+
+probe tcp.sendmsg.return {
+ if (size > 0) {
+ send_bytes[pid()] += size
+ totalbytes += size
+ pidnames[pid()] = execname()
+ uids[pid()] = uid()
+ }
+}
+
+probe tcp.recvmsg.return {
+ if (size > 0) {
+ recv_bytes[pid()] += size
+ totalbytes += size
+ pidnames[pid()] = execname()
+ uids[pid()] = uid()
+ }
+}
+
+probe tcp.disconnect {
+ delete pidnames[pid()]
+}
+
+probe timer.ms(2000) {
+ print_report()
+ foreach (_pid_ in pidnames) {
+ send_bytes[_pid_] = 0
+ recv_bytes[_pid_] = 0
+ }
+}
diff --git a/testsuite/systemtap.samples/topsys.stp b/testsuite/systemtap.samples/topsys.stp
new file mode 100644
index 00000000..e6e6bb2a
--- /dev/null
+++ b/testsuite/systemtap.samples/topsys.stp
@@ -0,0 +1,69 @@
+#! stap -g
+#
+# This script continuously lists the top 20 systemcalls in the interval
+# of 2000 jiffies.
+#
+
+global syscalls_count, syscalls
+
+function syscall_name:string () %{
+ char *str, buff[80];
+ char *tok;
+ str = buff;
+ strlcpy(str, CONTEXT->probe_point, sizeof(buff));
+ tok = strsep(&str, "\"");
+ tok = strsep(&str, "@");
+ sprintf(str, "%-25s", tok);
+ strlcpy(THIS->__retvalue, str, MAXSTRINGLEN);
+%}
+
+function reset_maxaction () %{
+ if (CONTEXT && CONTEXT->actioncount)
+ CONTEXT->actioncount=0;
+%}
+
+function accumulate () {
+ syscall=syscall_name()
+ syscalls_count[syscall]++
+ # I use this array to refer to syscalls_count array in
+ # the reset_syscalls_count. Initalize with a non-zero.
+ syscalls[syscall]=1
+}
+
+
+function print_top () {
+ lcnt=0
+ reset_maxaction ()
+ foreach ([syscall] in syscalls_count-) {
+ sys_cnt = syscalls_count[syscall]
+ log (syscall . "\t\t\t\t" . sprint(sys_cnt))
+ if (lcnt++ == 20)
+ break;
+ }
+ syscalls_count[lsyscall]=0
+}
+
+function reset_syscalls_count () {
+ # For some reason, I have to do this to get pass the elaboration
+ # phase on RHEL4 (seg fault). Under FC4, it works fine with out
+ # the 'dummy_init'
+ syscalls["dummy_init"]=0
+ foreach ([sys] in syscalls)
+ syscalls_count[sys]=0
+}
+
+function print_systop () {
+ log ("SYSCALL \t\t\t\tCOUNT")
+ print_top()
+ reset_syscalls_count ()
+}
+
+probe kernel.function("sys_*") {
+ accumulate ()
+}
+
+probe timer.jiffies(2000) {
+ print_systop ()
+ log("--------------------------------------------------------------")
+}
+
diff --git a/testsuite/systemtap.samples/transport-counts b/testsuite/systemtap.samples/transport-counts
new file mode 100755
index 00000000..87335cb9
--- /dev/null
+++ b/testsuite/systemtap.samples/transport-counts
@@ -0,0 +1,38 @@
+#!/usr/bin/perl
+
+# tracks gaps (missing records) and repeats in the transport-testing
+# output. If there aren't any missing records or repeats, it prints
+# "test passed", otherwise "test failed"
+#
+# Usage: transport-counts <output file>
+
+$prev = 0;
+$total_missing = 0;
+$repeats = 0;
+
+open TRACEFILE, $ARGV[0]
+ or die "Couldn't open trace file $ARGV[0]";
+
+while (<TRACEFILE>) {
+ chomp;
+ if (/\[(\d*)/) {
+ if ($prev + 1 != $1) {
+ $start_missing = $prev + 1;
+ $end_missing = $1 - 1;
+ if ($start_missing > $end_missing) {
+ $repeats++;
+ } else {
+ $total_missing += $end_missing - $start_missing;
+ }
+ }
+ $prev = $1;
+ }
+}
+print "total missing: $total_missing\n";
+print "repeats: $repeats\n";
+print "last event logged: $prev\n";
+if ($total_missing == 0 && $repeats == 0) {
+ print "test passed\n";
+} else {
+ print "test failed\n";
+}
diff --git a/testsuite/systemtap.samples/transport.exp b/testsuite/systemtap.samples/transport.exp
new file mode 100644
index 00000000..b7d6d77b
--- /dev/null
+++ b/testsuite/systemtap.samples/transport.exp
@@ -0,0 +1,73 @@
+set test "transport normal - procfs"
+if {![installtest_p]} { untested $test; return }
+
+spawn stap -o probe.out -DMAXACTION=1000000 $srcdir/$subdir/transport1.stp
+set ok 0
+expect {
+ -timeout 60
+ timeout { fail "$test (timeout)" }
+ eof { spawn $srcdir/$subdir/transport-counts probe.out
+ expect {
+ -ex {test passed} { incr ok; exp_continue }
+ eof { spawn rm probe.out }
+ }
+ }
+}
+close
+wait
+
+if {$ok >= 1} { pass "$test ($ok)" } { fail "$test ($ok)" }
+
+set test "transport normal - relayfs"
+spawn stap -b -o probe.out -DMAXACTION=1000000 $srcdir/$subdir/transport1.stp
+set ok 0
+expect {
+ -timeout 60
+ timeout { fail "$test (timeout)" }
+ eof { spawn $srcdir/$subdir/transport-counts probe.out
+ expect {
+ -ex {test passed} { incr ok; exp_continue }
+ eof { spawn rm probe.out }
+ }
+ }
+}
+close
+wait
+
+if {$ok >= 1} { pass "$test ($ok)" } { fail "$test ($ok)" }
+
+set test "transport fill staging buffer - procfs"
+spawn stap -o probe.out -DMAXACTION=1000000 $srcdir/$subdir/transport2.stp
+set ok 0
+expect {
+ -timeout 60
+ timeout { fail "$test (timeout)" }
+ eof { spawn $srcdir/$subdir/transport-counts probe.out
+ expect {
+ -ex {test passed} { incr ok; exp_continue }
+ eof { spawn rm probe.out }
+ }
+ }
+}
+close
+wait
+
+if {$ok >= 1} { pass "$test ($ok)" } { fail "$test ($ok)" }
+
+set test "transport fill staging buffer - relayfs"
+spawn stap -b -o probe.out -DMAXACTION=1000000 $srcdir/$subdir/transport2.stp
+set ok 0
+expect {
+ -timeout 60
+ timeout { fail "$test (timeout)" }
+ eof { spawn $srcdir/$subdir/transport-counts probe.out
+ expect {
+ -ex {test passed} { incr ok; exp_continue }
+ eof { spawn rm probe.out }
+ }
+ }
+}
+close
+wait
+
+if {$ok >= 1} { pass "$test ($ok)" } { fail "$test ($ok)" }
diff --git a/testsuite/systemtap.samples/transport1.stp b/testsuite/systemtap.samples/transport1.stp
new file mode 100644
index 00000000..5e9cfcd0
--- /dev/null
+++ b/testsuite/systemtap.samples/transport1.stp
@@ -0,0 +1,32 @@
+# This script tests normal logging - it logs a fair amount of data
+# in each probe hit, but not enough to fill up the staging buffers.
+
+global maxcount
+global count
+global n
+
+function write_output()
+{
+ for (i = 0; i < n; i++)
+ log("[".sprint(count++)."] testing 123, testing, testing. testing 123, testing, testing")
+}
+
+probe timer.jiffies(5)
+{
+ write_output();
+ if (count >= maxcount)
+ exit()
+}
+
+probe begin
+{
+ count = 1
+ n = 50
+ maxcount = 1000
+}
+
+probe end
+{
+ log("total records written: ".sprint(count - 1))
+ log("records per iteration: ".sprint(n))
+}
diff --git a/testsuite/systemtap.samples/transport2.stp b/testsuite/systemtap.samples/transport2.stp
new file mode 100644
index 00000000..1de90768
--- /dev/null
+++ b/testsuite/systemtap.samples/transport2.stp
@@ -0,0 +1,33 @@
+# This script tests normal logging - it logs a larger amount of data
+# in each probe hit, enough to fill up the staging buffers, so it
+# should detect anomalies in flushing the staging buffers.
+
+global maxcount
+global count
+global n
+
+function write_output()
+{
+ for (i = 0; i < n; i++)
+ log("[".sprint(count++)."] testing 123, testing, testing. testing 123, testing, testing")
+}
+
+probe timer.jiffies(5)
+{
+ write_output();
+ if (count >= maxcount)
+ exit()
+}
+
+probe begin
+{
+ count = 1
+ n = 500
+ maxcount = 10000
+}
+
+probe end
+{
+ log("total records written: ".sprint(count - 1))
+ log("records per iteration: ".sprint(n))
+}