summaryrefslogtreecommitdiffstats
path: root/testsuite/systemtap.examples
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite/systemtap.examples')
-rw-r--r--testsuite/systemtap.examples/ChangeLog96
-rw-r--r--testsuite/systemtap.examples/README9
-rwxr-xr-xtestsuite/systemtap.examples/futexes.stp36
-rw-r--r--testsuite/systemtap.examples/futexes.txt18
-rwxr-xr-xtestsuite/systemtap.examples/helloworld.stp2
-rwxr-xr-xtestsuite/systemtap.examples/iostat-scsi.stp81
-rw-r--r--testsuite/systemtap.examples/iostat-scsi.txt14
-rwxr-xr-xtestsuite/systemtap.examples/iotime.stp114
-rwxr-xr-xtestsuite/systemtap.examples/nettop.stp42
-rw-r--r--testsuite/systemtap.examples/nettop.txt20
-rwxr-xr-xtestsuite/systemtap.examples/pf2.stp16
-rw-r--r--testsuite/systemtap.examples/pf2.txt21
-rwxr-xr-xtestsuite/systemtap.examples/sig_by_pid.stp42
-rw-r--r--testsuite/systemtap.examples/sig_by_pid.txt24
-rwxr-xr-xtestsuite/systemtap.examples/sig_by_proc.stp36
-rw-r--r--testsuite/systemtap.examples/sig_by_proc.txt20
-rwxr-xr-xtestsuite/systemtap.examples/sigmon.stp35
-rwxr-xr-xtestsuite/systemtap.examples/sleeptime.stp63
-rwxr-xr-xtestsuite/systemtap.examples/small_demos/ansi_colors.stp21
-rw-r--r--testsuite/systemtap.examples/small_demos/click.wavbin0 -> 1290 bytes
-rwxr-xr-xtestsuite/systemtap.examples/small_demos/close.stp14
-rw-r--r--testsuite/systemtap.examples/small_demos/demo_script.txt102
-rwxr-xr-xtestsuite/systemtap.examples/small_demos/fileopen.stp24
-rwxr-xr-xtestsuite/systemtap.examples/small_demos/key.stp22
-rwxr-xr-xtestsuite/systemtap.examples/small_demos/keyhack.stp15
-rwxr-xr-xtestsuite/systemtap.examples/small_demos/kmalloc.stp22
-rwxr-xr-xtestsuite/systemtap.examples/small_demos/kmalloc2.stp26
-rwxr-xr-xtestsuite/systemtap.examples/small_demos/proc_snoop.stp55
-rwxr-xr-xtestsuite/systemtap.examples/small_demos/prof.stp35
-rw-r--r--testsuite/systemtap.examples/small_demos/return.wavbin0 -> 6584 bytes
-rwxr-xr-xtestsuite/systemtap.examples/small_demos/rwtiming.stp74
-rwxr-xr-xtestsuite/systemtap.examples/small_demos/sched_snoop.stp35
-rwxr-xr-xtestsuite/systemtap.examples/small_demos/sys.stp17
-rwxr-xr-xtestsuite/systemtap.examples/small_demos/top.stp24
-rwxr-xr-xtestsuite/systemtap.examples/socket-trace.stp8
-rwxr-xr-xtestsuite/systemtap.examples/socktop318
-rw-r--r--testsuite/systemtap.examples/socktop.txt66
-rwxr-xr-xtestsuite/systemtap.examples/syscalls_by_pid.stp28
-rw-r--r--testsuite/systemtap.examples/syscalls_by_pid.txt35
-rwxr-xr-xtestsuite/systemtap.examples/syscalls_by_proc.stp28
-rw-r--r--testsuite/systemtap.examples/syscalls_by_proc.txt58
-rwxr-xr-xtestsuite/systemtap.examples/syscalltimes248
-rw-r--r--testsuite/systemtap.examples/syscalltimes.txt155
-rwxr-xr-xtestsuite/systemtap.examples/wait4time.stp60
44 files changed, 2179 insertions, 0 deletions
diff --git a/testsuite/systemtap.examples/ChangeLog b/testsuite/systemtap.examples/ChangeLog
new file mode 100644
index 00000000..78083901
--- /dev/null
+++ b/testsuite/systemtap.examples/ChangeLog
@@ -0,0 +1,96 @@
+
+2008-03-09 Wenji Huang <wenji.huang@oracle.com>
+
+ * wait4time.stp: Change reference of $pid to local variable pid.
+
+2008-03-05 David Smith <dsmith@redhat.com>
+
+ PR5422
+ * iostat-scsi.stp: Updated to handle kernel versions > 2.6.24.
+ * iostat-scsi.txt: Updated.
+
+2008-01-29 Frank Ch. Eigler <fche@elastic.org>
+
+ * nettop.stp: Reorganize array usage to minimize contention.
+
+2007-11-19 Frank Ch. Eigler <fche@elastic.org>
+
+ * iostat-scsi.stp: Adopt "!" probe point flag.
+
+2007-11-09 Martin Hunt <hunt@redhat.com>
+
+ * README: New.
+
+ * *.stp. Fix path. See PR 4718.
+
+2007-10-10 Mike Mason
+
+ * syscalltimes, syscalltime.txt: New combination shell/SystemTap script
+ to measure system call times.
+
+2007-10-05 Frank Ch. Eigler <fche@elastic.org>
+
+ * futexes.stp, sig_by_proc.stp, small_demos/rwtiming.stp: Fix elision
+ warnings.
+
+2007-09-15 Wenji Huang <wenji.huang@oracle.com>
+
+ * iostat-scsi.stp: Make module probe optional,clarify reference to flags.
+ * small_demos/sched_snoop.stp(scheduler.migrage,scheduler.balance): Make optional.
+
+2007-09-05 Frank Ch. Eigler <fche@elastic.org>
+
+ * pf2.stp: Exploit sortable aggregates.
+
+2007-08-09 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 4718, from Eugeniy Meshcheryakov <eugen@debian.org>:
+ * *.stp: Make all shell scripts lead with #! /usr/bin/stap
+
+2007-05-29 Mike Mason <mmlnx@us.ibm.com>
+
+ * sig_count_by_pid.stp, sig_count_by_pid.txt,
+ sig_count_by_proc.stp, sig_count_by_proc.txt: Print signal activity
+
+2007-04-02 Frank Ch. Eigler <fche@elastic.org>
+
+ * socket-trace.stp, small_demos/prof.stp, top.stp: Adapt to
+ .inline -> .function change.
+
+2007-01-30 Frank Ch. Eigler <fche@elastic.org>
+
+ * socket-trace.stp: Added from the tutorial.
+
+2007-01-29 Mike Mason <mmlnx@us.ibm.com>
+
+ * socktop, socktop.txt: New example that uses a shell script to process
+ command line options for a systemtap script.
+
+2007-01-11 Will Cohen <wcohen@redhat.com>
+
+ * iotime.stp:
+ * sleeptime.stp:
+ * wait4time.stp: New examples.
+
+2007-01-10 Martin Hunt <hunt@redhat.com>
+
+ * small_demos/top.stp: Use "limit" option in foreach.
+
+2007-01-01 Frank Ch. Eigler <fche@redhat.com>
+
+ * *: Added several .stp/.txt files from the wiki.
+
+2006-04-20 Martin Hunt <hunt@redhat.com>
+
+ * small_demos/top.stp: Use printf.
+
+2006-03-30 Martin Hunt <hunt@redhat.com>
+
+ * small_demos/close.stp: Make it executable.
+
+2006-03-09 Martin Hunt <hunt@redhat.com>
+
+ * key.stp: Toy example.
+ * prof.stp: Example profiler.
+ * top.stp: Print the top 20 syscalls.
+
diff --git a/testsuite/systemtap.examples/README b/testsuite/systemtap.examples/README
new file mode 100644
index 00000000..6718a55a
--- /dev/null
+++ b/testsuite/systemtap.examples/README
@@ -0,0 +1,9 @@
+This directory contains example scripts.
+
+Each script should be checked in as executable.
+
+The first line should be
+#! /usr/bin/env stap
+
+There should be an accompanying ".txt" file describing what the
+script does and how to use it.
diff --git a/testsuite/systemtap.examples/futexes.stp b/testsuite/systemtap.examples/futexes.stp
new file mode 100755
index 00000000..16c62937
--- /dev/null
+++ b/testsuite/systemtap.examples/futexes.stp
@@ -0,0 +1,36 @@
+#! /usr/bin/env stap
+
+# This script tries to identify contended user-space locks by hooking
+# into the futex system call.
+
+global thread_thislock # short
+global thread_blocktime #
+global FUTEX_WAIT = 0 /*, FUTEX_WAKE = 1 */
+
+global lock_waits # long-lived stats on (tid,lock) blockage elapsed time
+global process_names # long-lived pid-to-execname mapping
+
+probe syscall.futex {
+ if (op != FUTEX_WAIT) next # we don't care about originators of WAKE events
+ t = tid ()
+ process_names[pid()] = execname()
+ thread_thislock[t] = $uaddr
+ thread_blocktime[t] = gettimeofday_us()
+}
+
+probe syscall.futex.return {
+ t = tid()
+ ts = thread_blocktime[t]
+ if (ts) {
+ elapsed = gettimeofday_us() - ts
+ lock_waits[pid(), thread_thislock[t]] <<< elapsed
+ delete thread_blocktime[t]
+ delete thread_thislock[t]
+ }
+}
+
+probe end {
+ foreach ([pid+, lock] in lock_waits)
+ printf ("%s[%d] lock %p contended %d times, %d avg us\n",
+ process_names[pid], pid, lock, @count(lock_waits[pid,lock]), @avg(lock_waits[pid,lock]))
+}
diff --git a/testsuite/systemtap.examples/futexes.txt b/testsuite/systemtap.examples/futexes.txt
new file mode 100644
index 00000000..51de4352
--- /dev/null
+++ b/testsuite/systemtap.examples/futexes.txt
@@ -0,0 +1,18 @@
+From: http://sourceware.org/systemtap/wiki/WSFutexContention
+
+# stap futexes.stp
+^C
+liferea-bin[3613] lock 0x0a117340 contended 1 times, 71 avg us
+java_vm[8155] lock 0x09baa45c contended 9 times, 1004013 avg us
+java_vm[8155] lock 0x09d6f9ac contended 186 times, 55964 avg us
+xmms[16738] lock 0xbfe29eec contended 777 times, 69 avg us
+xmms[16738] lock 0xbfe29ecc contended 119 times, 64 avg us
+xmms[16738] lock 0xbfe29ebc contended 111 times, 68 avg us
+xmms[16738] lock 0xbfe29ef0 contended 742 times, 91 avg us
+xmms[16738] lock 0xbfe29ed0 contended 107 times, 101 avg us
+xmms[16738] lock 0xbfe29ec0 contended 107 times, 74 avg us
+firefox-bin[21801] lock 0x096d16f4 contended 24 times, 12 avg us
+firefox-bin[21801] lock 0x096d1198 contended 2 times, 4 avg us
+firefox-bin[21801] lock 0x096d16f8 contended 150 times, 64997 avg us
+named[23869] lock 0x41ab0b84 contended 1 times, 131 avg us
+named[23869] lock 0x41ab0b50 contended 1 times, 26 avg us
diff --git a/testsuite/systemtap.examples/helloworld.stp b/testsuite/systemtap.examples/helloworld.stp
new file mode 100755
index 00000000..efe45b79
--- /dev/null
+++ b/testsuite/systemtap.examples/helloworld.stp
@@ -0,0 +1,2 @@
+#! /usr/bin/env stap
+probe begin { println("hello world") exit () }
diff --git a/testsuite/systemtap.examples/iostat-scsi.stp b/testsuite/systemtap.examples/iostat-scsi.stp
new file mode 100755
index 00000000..ef778e53
--- /dev/null
+++ b/testsuite/systemtap.examples/iostat-scsi.stp
@@ -0,0 +1,81 @@
+#! /usr/bin/env stap
+
+global devices, reads, writes
+
+/* data collection: SCSI disk */
+%(kernel_v<"2.6.24" %?
+probe module("sd_mod").function("sd_init_command") !, kernel.function("sd_init_command") {
+ device=kernel_string($SCpnt->request->rq_disk->disk_name)
+ sector_size=$SCpnt->device->sector_size
+ nr_sectors=$SCpnt->request->nr_sectors
+ devices[device] = 1
+%(kernel_v>="2.6.19" %?
+ if ($SCpnt->request->cmd_flags & 1)
+%:
+ if ($SCpnt->request->flags & 1)
+%)
+ writes[device] <<< nr_sectors * sector_size
+ else
+ reads[device] <<< nr_sectors * sector_size
+}
+%:
+%{
+#include <scsi/scsi_device.h>
+%}
+
+function get_sector_size:long (data:long) %{ /* pure */
+ struct scsi_device *sdp = (struct scsi_device *)((long)THIS->data);
+ THIS->__retvalue = kread(&(sdp->sector_size));
+ CATCH_DEREF_FAULT();
+%}
+
+probe module("sd_mod").function("sd_prep_fn") !, kernel.function("sd_prep_fn") {
+ device=kernel_string($rq->rq_disk->disk_name)
+ sector_size=get_sector_size($q->queuedata)
+ nr_sectors=$rq->nr_sectors
+ devices[device] = 1
+ if ($rq->cmd_flags & 1)
+ writes[device] <<< nr_sectors * sector_size
+ else
+ reads[device] <<< nr_sectors * sector_size
+}
+%)
+
+/* data collection: SCSI tape */
+probe module("st").function("st_do_scsi") !, kernel.function("st_do_scsi") {
+ device=kernel_string($STp->disk->disk_name)
+ devices[device] = 1
+ if ($direction)
+ writes[device] <<< $bytes
+ else
+ reads[device] <<< $bytes
+}
+
+
+/* reporting */
+global blksize=512
+global hdrcount
+probe timer.s($1) {
+ if ((hdrcount++ % 10) == 0)
+ printf("%9s %9s %9s %9s %9s %9s\n",
+ "Device:","tps","blk_read/s","blk_wrtn/s","blk_read","blk_wrtn")
+
+ foreach (dev in devices) {
+ rdcount=@count(reads[dev])
+ wrcount=@count(writes[dev])
+ tps=(rdcount+wrcount)*100/$1
+ rdblkcount=rdcount ? @sum(reads[dev])/blksize : 0
+ wrblkcount=wrcount ? @sum(writes[dev])/blksize : 0
+ rdblkrate=rdblkcount*100/$1
+ wrblkrate=wrblkcount*100/$1
+ printf("%9s %6d.%02d %6d.%02d %6d.%02d %9d %9d\n",
+ dev, tps/100,tps%100,
+ rdblkrate/100,rdblkrate%100,
+ wrblkrate/100,wrblkrate%100,
+ rdblkcount, wrblkcount)
+ }
+ printf ("\n")
+ delete devices
+ delete reads
+ delete writes
+}
diff --git a/testsuite/systemtap.examples/iostat-scsi.txt b/testsuite/systemtap.examples/iostat-scsi.txt
new file mode 100644
index 00000000..8222f659
--- /dev/null
+++ b/testsuite/systemtap.examples/iostat-scsi.txt
@@ -0,0 +1,14 @@
+From: http://sourceware.org/systemtap/wiki/WSiostatSCSI
+
+# stap -g iostat-scsi.stp 10 # seconds between reports
+ Device: tps blk_read/s blk_wrtn/s blk_read blk_wrtn
+ sda 1.30 2.40 105.60 24 1056
+
+ sda 0.30 0.00 4.00 0 40
+
+ sda 21.30 1.60 428.80 16 4288
+
+ sda 30.40 2820.80 11.60 28208 116
+
+ sda 38.10 2816.80 53.60 28168 536
+^C
diff --git a/testsuite/systemtap.examples/iotime.stp b/testsuite/systemtap.examples/iotime.stp
new file mode 100755
index 00000000..a5b36449
--- /dev/null
+++ b/testsuite/systemtap.examples/iotime.stp
@@ -0,0 +1,114 @@
+#! /usr/bin/env stap
+
+/*
+ * Copyright (C) 2006 Daniel Berrange, Red Hat Inc.
+ * Copyright (C) 2007 Will Cohen, Red Hat, Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Print out the amount of time spent in the read and write systemcall
+ * when a process closes each file is closed. Note that the systemtap
+ * script needs to be running before the open operations occur for
+ * the script to record data.
+ *
+ * This script could be used to to find out which files are slow to load
+ * on a machine. e.g.
+ *
+ * stap iotime.stp -c 'firefox'
+ *
+ * Output format is:
+ * timestamp pid (executabable) info_type path ...
+ *
+ * 200283135 2573 (cupsd) access /etc/printcap read: 0 write: 7063
+ * 200283143 2573 (cupsd) iotime /etc/printcap time: 69
+ *
+ */
+
+global start
+global entry_io
+global fd_io
+global time_io
+
+function timestamp:long() {
+ return gettimeofday_us() - start
+}
+
+function proc:string() {
+ return sprintf("%d (%s)", pid(), execname())
+}
+
+probe begin {
+ start = gettimeofday_us()
+}
+
+global filenames
+global filehandles
+global fileread
+global filewrite
+
+probe syscall.open {
+ filenames[pid()] = user_string($filename)
+}
+
+probe syscall.open.return {
+ if ($return != -1) {
+ filehandles[pid(), $return] = filenames[pid()]
+ fileread[pid(), $return] = 0
+ filewrite[pid(), $return] = 0
+ } else {
+ printf("%d %s access %s fail\n", timestamp(), proc(), filenames[pid()])
+ }
+ delete filenames[pid()]
+}
+
+probe syscall.read {
+ if ($count > 0) {
+ fileread[pid(), $fd] += $count
+ }
+ t = gettimeofday_us(); p = pid()
+ entry_io[p] = t
+ fd_io[p] = $fd
+}
+
+probe syscall.read.return {
+ t = gettimeofday_us(); p = pid()
+ fd = fd_io[p]
+ time_io[p,fd] <<< t - entry_io[p]
+}
+
+probe syscall.write {
+ if ($count > 0) {
+ filewrite[pid(), $fd] += $count
+ }
+ t = gettimeofday_us(); p = pid()
+ entry_io[p] = t
+ fd_io[p] = $fd
+}
+
+probe syscall.write.return {
+ t = gettimeofday_us(); p = pid()
+ fd = fd_io[p]
+ time_io[p,fd] <<< t - entry_io[p]
+}
+
+probe syscall.close {
+ if (filehandles[pid(), $fd] != "") {
+ printf("%d %s access %s read: %d write: %d\n", timestamp(), proc(),
+ filehandles[pid(), $fd], fileread[pid(), $fd], filewrite[pid(), $fd])
+ if (@count(time_io[pid(), $fd]))
+ printf("%d %s iotime %s time: %d\n", timestamp(), proc(),
+ filehandles[pid(), $fd], @sum(time_io[pid(), $fd]))
+ }
+ delete fileread[pid(), $fd]
+ delete filewrite[pid(), $fd]
+ delete filehandles[pid(), $fd]
+ delete fd_io[pid()]
+ delete entry_io[pid()]
+ delete time_io[pid(),$fd]
+}
diff --git a/testsuite/systemtap.examples/nettop.stp b/testsuite/systemtap.examples/nettop.stp
new file mode 100755
index 00000000..96db413a
--- /dev/null
+++ b/testsuite/systemtap.examples/nettop.stp
@@ -0,0 +1,42 @@
+#! /usr/bin/env stap
+
+global ifxmit, ifrecv
+
+probe netdev.transmit
+{
+ ifxmit[pid(), dev_name, execname(), uid()] <<< length
+}
+
+probe netdev.receive
+{
+ ifrecv[pid(), dev_name, execname(), uid()] <<< length
+}
+
+
+function print_activity()
+{
+ printf("%5s %5s %-7s %7s %7s %7s %7s %-15s\n",
+ "PID", "UID", "DEV", "XMIT_PK", "RECV_PK",
+ "XMIT_KB", "RECV_KB", "COMMAND")
+
+ foreach ([pid, dev, exec, uid] in ifrecv-) {
+ n_xmit = @count(ifxmit[pid, dev, exec, uid])
+ n_recv = @count(ifrecv[pid, dev, exec, uid])
+ printf("%5d %5d %-7s %7d %7d %7d %7d %-15s\n",
+ pid, uid, dev, n_xmit, n_recv,
+ n_xmit ? @sum(ifxmit[pid, dev, exec, uid])/1024 : 0,
+ n_recv ? @sum(ifrecv[pid, dev, exec, uid])/1024 : 0,
+ exec)
+ }
+
+ print("\n")
+
+ delete ifxmit
+ delete ifrecv
+}
+
+probe timer.ms(5000), end, error
+{
+ print_activity()
+}
+
diff --git a/testsuite/systemtap.examples/nettop.txt b/testsuite/systemtap.examples/nettop.txt
new file mode 100644
index 00000000..2bfd4967
--- /dev/null
+++ b/testsuite/systemtap.examples/nettop.txt
@@ -0,0 +1,20 @@
+From: http://sourceware.org/systemtap/wiki/WSNetTop
+
+# stap nettop.stp
+ PID UID DEV XMIT_PK RECV_PK XMIT_KB RECV_KB COMMAND
+ 0 0 eth0 66 344 18 19 swapper
+ 2469 0 eth0 214 39 167 1 Xvnc
+23470 0 eth0 24 35 5 1 firefox-bin
+ 2281 0 eth0 1 1 0 0 wcstatusd
+22446 0 eth0 1 0 1 0 sshd
+ 2538 0 eth0 0 1 0 0 metacity
+23557 0 eth0 0 1 0 0 sh
+23559 0 eth0 0 1 0 0 lspci
+23566 0 eth0 0 1 0 0 sh
+
+ PID UID DEV XMIT_PK RECV_PK XMIT_KB RECV_KB COMMAND
+ 0 0 eth0 14 80 0 3 swapper
+ 2469 0 eth0 32 2 20 0 Xvnc
+22446 0 eth0 1 0 0 0 sshd
+ 2052 38 eth0 1 0 0 0 ntpd
+
diff --git a/testsuite/systemtap.examples/pf2.stp b/testsuite/systemtap.examples/pf2.stp
new file mode 100755
index 00000000..96fdb7e7
--- /dev/null
+++ b/testsuite/systemtap.examples/pf2.stp
@@ -0,0 +1,16 @@
+#! /usr/bin/env stap
+
+global profile, pcount
+probe timer.profile {
+ pcount <<< 1
+ fn = probefunc ()
+ if (fn != "") profile[fn] <<< 1
+}
+probe timer.ms(4000) {
+ printf ("\n--- %d samples recorded:\n", @count(pcount))
+ foreach (f in profile- limit 10) {
+ printf ("%s\t%d\n", f, @count(profile[f]))
+ }
+ delete profile
+ delete pcount
+}
diff --git a/testsuite/systemtap.examples/pf2.txt b/testsuite/systemtap.examples/pf2.txt
new file mode 100644
index 00000000..0fafe17e
--- /dev/null
+++ b/testsuite/systemtap.examples/pf2.txt
@@ -0,0 +1,21 @@
+From: http://sourceware.org/systemtap/wiki/WSKernelProfile
+
+# stap pf2.stp
+
+--- 109 samples recorded:
+mwait_idle 71
+check_poison_obj 4
+_spin_unlock_irqrestore 2
+dbg_redzone1 1
+kfree 1
+kmem_cache_free 1
+_spin_unlock_irq 1
+end_buffer_write_sync 1
+lock_acquire 1
+
+--- 108 samples recorded:
+mwait_idle 91
+check_poison_obj 3
+_spin_unlock_irq 2
+delay_tsc 1
+
diff --git a/testsuite/systemtap.examples/sig_by_pid.stp b/testsuite/systemtap.examples/sig_by_pid.stp
new file mode 100755
index 00000000..9c1493f5
--- /dev/null
+++ b/testsuite/systemtap.examples/sig_by_pid.stp
@@ -0,0 +1,42 @@
+#! /usr/bin/env stap
+
+# Copyright (C) 2006 IBM Corp.
+#
+# This file is part of systemtap, and is free software. You can
+# redistribute it and/or modify it under the terms of the GNU General
+# Public License (GPL); either version 2, or (at your option) any
+# later version.
+
+#
+# Print signal counts by process IDs in descending order.
+#
+
+global sigcnt, pid2name, sig2name
+
+probe begin {
+ print("Collecting data... Type Ctrl-C to exit and display results\n")
+}
+
+probe signal.send
+{
+ snd_pid = pid()
+ rcv_pid = sig_pid
+
+ sigcnt[snd_pid, rcv_pid, sig]++
+
+ if (!(snd_pid in pid2name)) pid2name[snd_pid] = execname()
+ if (!(rcv_pid in pid2name)) pid2name[rcv_pid] = pid_name
+ if (!(sig in sig2name)) sig2name[sig] = sig_name
+}
+
+probe end
+{
+ printf("%-8s %-16s %-5s %-16s %-16s %s\n",
+ "SPID", "SENDER", "RPID", "RECEIVER", "SIGNAME", "COUNT")
+
+ foreach ([snd_pid, rcv_pid, sig_num] in sigcnt-) {
+ printf("%-8d %-16s %-5d %-16s %-16s %d\n",
+ snd_pid, pid2name[snd_pid], rcv_pid, pid2name[rcv_pid],
+ sig2name[sig_num], sigcnt[snd_pid, rcv_pid, sig_num])
+ }
+}
diff --git a/testsuite/systemtap.examples/sig_by_pid.txt b/testsuite/systemtap.examples/sig_by_pid.txt
new file mode 100644
index 00000000..927b4607
--- /dev/null
+++ b/testsuite/systemtap.examples/sig_by_pid.txt
@@ -0,0 +1,24 @@
+# stap sig_by_pid.stp
+Collecting data... Type Ctrl-C to exit and display results
+^C
+Collecting data... Type Ctrl-C to exit and display results
+SPID SENDER RPID RECEIVER SIGNAME COUNT
+0 swapper 25273 Xvnc SIGALRM 1576
+25273 Xvnc 25273 Xvnc SIGALRM 17
+29219 firefox-bin 25273 Xvnc SIGALRM 12
+0 swapper 2442 automount SIGALRM 12
+26754 xterm 26756 bash SIGWINCH 9
+0 swapper 2199 syslogd SIGALRM 6
+25345 metacity 25273 Xvnc SIGALRM 3
+2791 wclientd 2791 wclientd SIGUSR1 2
+30385 ifconfig 30384 sh SIGCHLD 1
+30384 sh 2802 wcstatusd SIGCHLD 1
+30387 mii-tool 30386 sh SIGCHLD 1
+30386 sh 2802 wcstatusd SIGCHLD 1
+30388 lspci 2802 wcstatusd SIGCHLD 1
+30389 sh 2802 wcstatusd SIGCHLD 1
+30391 ifconfig 25273 Xvnc SIGALRM 1
+30391 ifconfig 30390 sh SIGCHLD 1
+30390 sh 2802 wcstatusd SIGCHLD 1
+30393 mii-tool 30392 sh SIGCHLD 1
+30392 sh 2802 wcstatusd SIGCHLD 1
diff --git a/testsuite/systemtap.examples/sig_by_proc.stp b/testsuite/systemtap.examples/sig_by_proc.stp
new file mode 100755
index 00000000..ce845aed
--- /dev/null
+++ b/testsuite/systemtap.examples/sig_by_proc.stp
@@ -0,0 +1,36 @@
+#! /usr/bin/env stap
+
+# Copyright (C) 2006 IBM Corp.
+#
+# This file is part of systemtap, and is free software. You can
+# redistribute it and/or modify it under the terms of the GNU General
+# Public License (GPL); either version 2, or (at your option) any
+# later version.
+
+#
+# Print signal counts by process name in descending order.
+#
+
+global sigcnt, sig2name
+
+probe begin {
+ print("Collecting data... Type Ctrl-C to exit and display results\n")
+}
+
+probe signal.send
+{
+ sigcnt[execname(), pid_name, sig]++
+
+ if (!(sig in sig2name)) sig2name[sig] = sig_name
+}
+
+probe end
+{
+ printf("%-16s %-16s %-16s %s\n",
+ "SENDER", "RECEIVER", "SIGNAL", "COUNT")
+
+ foreach ([snd_name, rcv_name, sig_num] in sigcnt-)
+ printf("%-16s %-16s %-16s %d\n",
+ snd_name, rcv_name, sig2name[sig_num],
+ sigcnt[snd_name, rcv_name, sig_num])
+}
diff --git a/testsuite/systemtap.examples/sig_by_proc.txt b/testsuite/systemtap.examples/sig_by_proc.txt
new file mode 100644
index 00000000..d09da9fe
--- /dev/null
+++ b/testsuite/systemtap.examples/sig_by_proc.txt
@@ -0,0 +1,20 @@
+# stap sig_by_proc.stp
+Collecting data... Type Ctrl-C to exit and display results
+^C
+SENDER RECEIVER SIGNAL COUNT
+swapper Xvnc SIGALRM 448
+sh wcstatusd SIGCHLD 318
+ifconfig sh SIGCHLD 106
+mii-tool sh SIGCHLD 106
+lspci wcstatusd SIGCHLD 106
+automount automount SIGCHLD 14
+swapper automount SIGALRM 13
+swapper syslogd SIGALRM 7
+swapper sendmail SIGALRM 2
+sendmail sendmail SIGCHLD 2
+lspci Xvnc SIGALRM 2
+ifconfig automount SIGALRM 1
+sh Xvnc SIGALRM 1
+xterm staprun SIGINT 1
+xterm stap SIGINT 1
+
diff --git a/testsuite/systemtap.examples/sigmon.stp b/testsuite/systemtap.examples/sigmon.stp
new file mode 100755
index 00000000..31d7822e
--- /dev/null
+++ b/testsuite/systemtap.examples/sigmon.stp
@@ -0,0 +1,35 @@
+#! /usr/bin/env stap
+
+# Copyright (C) 2006 IBM Corp.
+#
+# This file is part of systemtap, and is free software. You can
+# redistribute it and/or modify it under the terms of the GNU General
+# Public License (GPL); either version 2, or (at your option) any
+# later version.
+
+#
+# Track when a specific process ID receives a specific signal. For example,
+# when process ID 31994 receives a SIGKILL signal.
+#
+# Example command line:
+#
+# stap -x 31994 sigmon.stp SIGKILL
+#
+# Example output:
+#
+# SPID SNAME RPID RNAME SIGNUM SIGNAME
+# 5609 bash 31994 find 9 SIGKILL
+#
+
+probe begin
+{
+ printf("%-8s %-16s %-5s %-16s %6s %-16s\n",
+ "SPID", "SNAME", "RPID", "RNAME", "SIGNUM", "SIGNAME")
+}
+
+probe signal.send
+{
+ if (sig_name == @1 && sig_pid == target())
+ printf("%-8d %-16s %-5d %-16s %-6d %-16s\n",
+ pid(), execname(), sig_pid, pid_name, sig, sig_name)
+}
diff --git a/testsuite/systemtap.examples/sleeptime.stp b/testsuite/systemtap.examples/sleeptime.stp
new file mode 100755
index 00000000..252e50cc
--- /dev/null
+++ b/testsuite/systemtap.examples/sleeptime.stp
@@ -0,0 +1,63 @@
+#! /usr/bin/env stap
+
+/*
+ * Copyright (C) 2006 Daniel Berrange, Red Hat Inc.
+ * Copyright (C) 2007 Will Cohen, Red Hat, Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Print out the amount of time spent in the nanosleep and compat_nanosleep
+ * systemcalls. This can help find which processes are waking based on time
+ * rather than some real event than needs to be handled.
+ *
+ * Format is:
+ * 12799538 3389 (xchat) nanosleep: 9547
+ * 12846944 2805 (NetworkManager) nanosleep: 100964
+ * 12947924 2805 (NetworkManager) nanosleep: 100946
+ * 13002925 4757 (sleep) nanosleep: 13000717
+ */
+
+global start
+global entry_nanosleep
+
+function timestamp:long() {
+ return gettimeofday_us() - start
+}
+
+function proc:string() {
+ return sprintf("%d (%s)", pid(), execname())
+}
+
+probe begin {
+ start = gettimeofday_us()
+}
+
+probe syscall.nanosleep {
+ t = gettimeofday_us(); p = pid()
+ entry_nanosleep[p] = t
+}
+
+probe syscall.nanosleep.return {
+ t = gettimeofday_us(); p = pid()
+ elapsed_time = t - entry_nanosleep[p]
+ printf("%d %s nanosleep: %d\n", timestamp(), proc(), elapsed_time)
+ delete entry_nanosleep[p]
+}
+
+probe syscall.compat_nanosleep ? {
+ t = gettimeofday_us(); p = pid()
+ entry_nanosleep[p] = t
+}
+
+probe syscall.compat_nanosleep.return ? {
+ t = gettimeofday_us(); p = pid()
+ elapsed_time = t - entry_nanosleep[p]
+ printf("%d %s compat_nanosleep: %d\n", timestamp(), proc(), elapsed_time)
+ delete entry_nanosleep[p]
+}
diff --git a/testsuite/systemtap.examples/small_demos/ansi_colors.stp b/testsuite/systemtap.examples/small_demos/ansi_colors.stp
new file mode 100755
index 00000000..0d9d7c47
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/ansi_colors.stp
@@ -0,0 +1,21 @@
+#! /usr/bin/env stap
+
+probe begin {
+ printf("a \\ b |");
+ for (c = 40; c < 48; c++)
+ printf(" %d ", c);
+ printf("\12");
+ for (l = 0; l < 71; l++)
+ printf("-");
+ printf("\12");
+
+ for (r = 30; r < 38; r++)
+ for (t = 0; t < 2; t++) {
+ printf("%d |", r);
+ for (c = 40; c < 48; c++)
+ printf("\033[%d;%d%s %s \033[0;0m",
+ r, c, !t ? "m" : ";1m", !t ? "Normal" : "Bold ");
+ printf("\12");
+ }
+ exit();
+}
diff --git a/testsuite/systemtap.examples/small_demos/click.wav b/testsuite/systemtap.examples/small_demos/click.wav
new file mode 100644
index 00000000..8214b229
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/click.wav
Binary files differ
diff --git a/testsuite/systemtap.examples/small_demos/close.stp b/testsuite/systemtap.examples/small_demos/close.stp
new file mode 100755
index 00000000..7ba2a036
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/close.stp
@@ -0,0 +1,14 @@
+#!/usr/bin/env stap
+
+probe syscall.close {
+ printf("%s: %s(%s) = ", execname(), name, argstr)
+}
+
+probe syscall.close.return {
+ printf("%s\n", returnstr(returnp))
+}
+
+probe end {
+ printf("DONE\n")
+}
+
diff --git a/testsuite/systemtap.examples/small_demos/demo_script.txt b/testsuite/systemtap.examples/small_demos/demo_script.txt
new file mode 100644
index 00000000..f3166a49
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/demo_script.txt
@@ -0,0 +1,102 @@
+> cd /root/systemtap
+
+A systemtap script can be as simple as a single line. For example,
+the following script places a probepoint on the kernel sys_read()
+function and prints all callers with the function's arguments.
+
+>stap -e 'probe syscall.open {printf("%s: %s\n", execname(), argstr)}'
+
+Most scripts are a bit longer. (show top.stp)
+This script sets a probepoint on all kernel functions beginning with "sys_".
+When the probepoint is hit, it increments an entry in the map
+(or associative array) "syscalls" with the key "probefunc()" which returns
+the name of the function that was triggered. For example, "sys_read".
+
+There is a timer that is triggered every 5000ms or 5 seconds. That timer
+calls the function print_top(). print_top() sorts the syscalls map
+and prints the top 20 entries. Then it clears the map.
+
+> ./top.stp
+
+(after stopping "top" go ahead and enter "./sys.stp". It takes a minute
+to load this script. Diplay the source in another window and talk
+while it is loading.)
+
+The "top" script looked only at the functions called. If we want more
+detail about the functions, we can use systemtap to examine their local
+arguments and variables. However that would be difficult because each
+system call has different parameters. The Syscall Tapset solves
+this problem. To use it, we set probe points using the syntax "syscall.name"
+instead of kernel.function("sys_name"). The Syscall Tapset provides three
+defined variables we can use:
+name - the name of the function
+argstr - on function entry, a formatted string containing the arguments
+retstr - on function exit, the return value and possibly error code
+
+In this example, we filter out programs named "staprun" because this is
+part of the systemtap infrastructure. (It may be filtered out
+automatically in the future.)
+
+The next example shows how you can use systemtap to focus on
+specific programs or pids. (show prof.stp)
+
+Like the "top" example, this script places probes on all kernel
+functions starting with "sys_". Only the probepoint also checks to see
+if the tid/pid matches the one returned by "target()". We'll show how
+the target pid is set later.
+
+Unlike the previous examples, this script sets a probe point on all the
+system call returns. When triggered, this probepoint computes the elapsed
+time since the function entry.
+
+To run this script, we must give it a pid to use for the target, or a
+program to run, in which case target will be its pid.
+
+> ./prof.stp -c "top -n5"
+
+--------------------------------
+
+Systemtap can also run in an unsafe mode where you can give
+it arbitrary C code to run at probepoints, or modify kernel variables
+and structures. This is very dangerous so only experts with root access will
+ever be permitted to do this.
+
+(show keyhack.stp)
+
+The next example will modify the local variable "keycode" in the "kdb_keycode"
+function in the kernel driver. We indicate it is a local variable by putting
+a dollar sign before the name.
+
+./keyhack.stp
+
+(prints error message)
+
+To tell systemtap we really want to run this script, we must use the "-g" flag.
+
+./keyhack.stp -g
+
+(type some keys. "m" should display as "b" in every window)
+
+This example is not something you would normally want to do. There are
+far better ways to remap a keyboard. What it demonstartes is that Systemtap
+can modify variables in a running kernel.
+
+(show kmalloc.stp)
+This next script shows the kind of statistics systemtap can collect.
+It collects information about kernel allocations.
+
+> ./kmalloc.stp
+
+Now we can refine this further
+(show kmalloc2.stp)
+
+Remember in some previous examples, we used maps or associative arrays. Maps can contain
+statistics too. So we have enhanced the previous script to collect statistics per
+program name. The output might be large so we'll redirect it to a file.
+
+> ./kmalloc2.stp > out
+
+(runs for 10 seconds)
+
+> more out
+
diff --git a/testsuite/systemtap.examples/small_demos/fileopen.stp b/testsuite/systemtap.examples/small_demos/fileopen.stp
new file mode 100755
index 00000000..c1298f9c
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/fileopen.stp
@@ -0,0 +1,24 @@
+#! /usr/bin/env stap
+
+#
+# fileopen.stp
+#
+# This is based on dtrace script from
+# http://www.gnome.org/~gman/blog/2006/Jan
+#
+# stap fileopen.stp -c "zenity --about"
+# or
+# ./fileopen.stp -c "program or script"
+
+global opens
+
+probe syscall.open {
+ if (target() == pid()) opens[filename] ++
+}
+
+probe end {
+ foreach([name] in opens+) {
+ printf("%-70s%5d\n", name, opens[name])
+ }
+}
+
diff --git a/testsuite/systemtap.examples/small_demos/key.stp b/testsuite/systemtap.examples/small_demos/key.stp
new file mode 100755
index 00000000..6d2d6c3f
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/key.stp
@@ -0,0 +1,22 @@
+#! /usr/bin/env stap
+
+# Useless, but amusing. Based on an idea I saw on a
+# dtrace site. (wav files are from emacs).
+
+// KEY_ENTER = 28
+probe kernel.function("kbd_event") {
+ if ($event_type == 1 && $value) {
+ if ($event_code == 28)
+ system("play return.wav &> /dev/null")
+ else
+ system("play click.wav &> /dev/null")
+ }
+}
+
+probe begin {
+ printf("TYPEWRITER ON\n")
+}
+
+probe end {
+ printf("DONE\n")
+}
diff --git a/testsuite/systemtap.examples/small_demos/keyhack.stp b/testsuite/systemtap.examples/small_demos/keyhack.stp
new file mode 100755
index 00000000..3137baad
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/keyhack.stp
@@ -0,0 +1,15 @@
+#! /usr/bin/env stap
+
+# This is not useful, but it demonstrates that
+# Systemtap can modify variables in a running kernel.
+
+# Usage: ./keyhack.stp -g
+
+probe kernel.function("kbd_event") {
+ # Changes 'm' to 'b' .
+ if ($event_code == 50) $event_code = 48
+}
+
+probe end {
+ printf("\nDONE\n")
+}
diff --git a/testsuite/systemtap.examples/small_demos/kmalloc.stp b/testsuite/systemtap.examples/small_demos/kmalloc.stp
new file mode 100755
index 00000000..9157928d
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/kmalloc.stp
@@ -0,0 +1,22 @@
+#! /usr/bin/env stap
+
+# Using statistics to examine kernel memory allocations
+
+global kmalloc
+
+probe kernel.function("__kmalloc") {
+ kmalloc <<< $size
+}
+
+# Exit after 10 seconds
+probe timer.ms(10000) { exit () }
+
+probe end {
+ printf("Count: %d allocations\n", @count(kmalloc))
+ printf("Sum: %d Kbytes\n", @sum(kmalloc)/1000)
+ printf("Average: %d bytes\n", @avg(kmalloc))
+ printf("Min: %d bytes\n", @min(kmalloc))
+ printf("Max: %d bytes\n", @max(kmalloc))
+ print("\nAllocations by size in bytes\n")
+ print(@hist_log(kmalloc))
+}
diff --git a/testsuite/systemtap.examples/small_demos/kmalloc2.stp b/testsuite/systemtap.examples/small_demos/kmalloc2.stp
new file mode 100755
index 00000000..2622dd2f
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/kmalloc2.stp
@@ -0,0 +1,26 @@
+#! /usr/bin/env stap
+
+# Using statistics and maps to examine kernel memory allocations
+
+global kmalloc
+
+probe kernel.function("__kmalloc") {
+ kmalloc[execname()] <<< $size
+}
+
+# Exit after 10 seconds
+probe timer.ms(10000) { exit () }
+
+probe end {
+ foreach ([name] in kmalloc) {
+ printf("Allocations for %s\n", name)
+ printf("Count: %d allocations\n", @count(kmalloc[name]))
+ printf("Sum: %d Kbytes\n", @sum(kmalloc[name])/1000)
+ printf("Average: %d bytes\n", @avg(kmalloc[name]))
+ printf("Min: %d bytes\n", @min(kmalloc[name]))
+ printf("Max: %d bytes\n", @max(kmalloc[name]))
+ print("\nAllocations by size in bytes\n")
+ print(@hist_log(kmalloc[name]))
+ printf("-------------------------------------------------------\n\n");
+ }
+}
diff --git a/testsuite/systemtap.examples/small_demos/proc_snoop.stp b/testsuite/systemtap.examples/small_demos/proc_snoop.stp
new file mode 100755
index 00000000..24499b4b
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/proc_snoop.stp
@@ -0,0 +1,55 @@
+#!/usr/bin/env stap
+
+global start_ts
+
+probe begin {
+ start_ts = gettimeofday_us()
+ printf("%12s %5s %5s %-16s ACTION\n",
+ "TIMESTAMP", "PID", "TID", "EXECNAME")
+}
+
+function report(action:string) {
+ printf("%12d %5d %5d %-16s %s\n", gettimeofday_us() - start_ts,
+ pid(), tid(), execname(), action)
+}
+
+function id:string(task:long) {
+ return sprintf("p:%d t:%d n:%s", task_pid(task), task_tid(task),
+ task_execname(task))
+}
+
+probe process.create {
+ report(sprintf("create %s", id(task)))
+}
+
+probe process.start {
+ report("start")
+}
+
+probe process.exec {
+ report(sprintf("exec %s", filename))
+}
+
+probe process.exec_complete {
+ if (success)
+ report("exec success")
+ else
+ report(sprintf("exec failed %d (%s)", errno, errno_str(errno)))
+}
+
+probe process.exit {
+ report(sprintf("exit %d", code))
+}
+
+probe process.release {
+ report(sprintf("remove %s", id(task)))
+}
+
+probe signal.send {
+ report(sprintf("sigsend %d (%s) to %s%s", sig, sig_name, id(task),
+ shared? " [SHARED]" : ""))
+}
+
+probe signal.handle {
+ report(sprintf("sighandle %d (%s)", sig, sig_name))
+}
diff --git a/testsuite/systemtap.examples/small_demos/prof.stp b/testsuite/systemtap.examples/small_demos/prof.stp
new file mode 100755
index 00000000..389f743a
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/prof.stp
@@ -0,0 +1,35 @@
+#!/usr/bin/env stap
+
+# This is an example of profiling a specific command or pid.
+# It works by recording the time when a system call is entered
+# exited.
+
+# Usage: prof.stp -c "top -n5"
+# Will start up "top" and after 5 iterations, will exit.
+#
+# Usage: prof.stp -x 3323
+# Will profile pid 3323 until it ^c is hit.
+#
+
+probe kernel.function("sys_*").call {
+ if (target() == tid())
+ calltime[tid()] = gettimeofday_us()
+}
+
+probe kernel.function("sys_*").return {
+ if (target() != tid()) next
+ now = gettimeofday_us()
+ c = calltime[tid()]
+ if (!c) next
+ ttime[probefunc()] <<< now - c
+ delete calltime[tid()]
+}
+
+probe end {
+ printf("\n")
+ foreach (x in ttime)
+ printf("%-20s\tcalls:%6d\tavg time (us):%5d\ttotal(us):%7d\n",
+ x, @count(ttime[x]), @avg(ttime[x]), @sum(ttime[x]))
+}
+
+global calltime, ttime
diff --git a/testsuite/systemtap.examples/small_demos/return.wav b/testsuite/systemtap.examples/small_demos/return.wav
new file mode 100644
index 00000000..20f978cc
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/return.wav
Binary files differ
diff --git a/testsuite/systemtap.examples/small_demos/rwtiming.stp b/testsuite/systemtap.examples/small_demos/rwtiming.stp
new file mode 100755
index 00000000..d570c581
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/rwtiming.stp
@@ -0,0 +1,74 @@
+#! /usr/bin/env stap
+# rwtiming.stp
+#
+# This is a simple example to track the amount of time
+# spent doing reads and writes for the various programs running on the
+# system.
+
+probe begin { log("starting probe") }
+
+global names, opens, reads, writes
+global entry_opens, entry_reads, entry_writes
+global time_opens, time_reads, time_writes
+
+probe kernel.function("sys_open") {
+ t=gettimeofday_us(); p=pid(); e=execname();
+ names[e]=1
+ opens[e] ++ # plain integer
+ entry_opens[p] = t;
+}
+
+probe kernel.function("sys_open").return {
+ t=gettimeofday_us(); p=pid(); e=execname();
+ time_opens[e] <<< t - entry_opens[p];
+}
+
+probe kernel.function("sys_read") {
+ t= gettimeofday_us(); p =pid(); e=execname();
+ names[e]=1
+ reads[e] <<< $count # statistics
+ entry_reads[p] = t;
+}
+
+probe kernel.function("sys_read").return {
+ t=gettimeofday_us(); p=pid(); e=execname();
+ time_reads[e] <<< t - entry_reads[p];
+}
+
+probe kernel.function("sys_write") {
+ t=gettimeofday_us(); p=pid(); e=execname();
+ names[e]=1
+ writes[e] <<< $count # statistics
+ entry_writes[p] = t;
+}
+
+probe kernel.function("sys_write").return {
+ t = gettimeofday_us(); p = pid(); e=execname();
+ time_writes[e] <<< t - entry_writes[p];
+}
+
+probe end {
+ foreach(name+ in names) { # sort by names
+ printf ("process: %s\n", name)
+ if (opens[name]) {
+ printf ("opens n=%d\n", opens[name])
+ print (@hist_log(time_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]))
+ print ("read timing distribution\n")
+ print (@hist_log(time_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]))
+ print ("write timing distribution\n")
+ print (@hist_log(time_writes[name]))
+ }
+ }
+}
diff --git a/testsuite/systemtap.examples/small_demos/sched_snoop.stp b/testsuite/systemtap.examples/small_demos/sched_snoop.stp
new file mode 100755
index 00000000..623643dd
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/sched_snoop.stp
@@ -0,0 +1,35 @@
+#!/usr/bin/env stap
+
+global start_ts
+
+probe begin {
+ start_ts = gettimeofday_us()
+ printf("%12s %3s %5s %5s %-16s ACTION\n",
+ "TIMESTAMP", "CPU", "PID", "TID", "EXECNAME")
+}
+
+function report(action:string) {
+ printf("%3d %12d %5d %5d %-16s %s\n",
+ gettimeofday_us() - start_ts, cpu(),
+ pid(), tid(), execname(), action)
+}
+
+probe scheduler.cpu_off {
+ report(sprintf("cpu_off%s", idle? " [idle]" : ""))
+}
+
+probe scheduler.cpu_on {
+ report(sprintf("cpu_on%s", idle? " [idle]" : ""))
+}
+
+probe scheduler.tick {
+ report(sprintf("tick%s", idle? " [idle]" : ""))
+}
+
+probe scheduler.migrate ? {
+ report("migrate")
+}
+
+probe scheduler.balance ? {
+ report("balance")
+}
diff --git a/testsuite/systemtap.examples/small_demos/sys.stp b/testsuite/systemtap.examples/small_demos/sys.stp
new file mode 100755
index 00000000..2df20bc3
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/sys.stp
@@ -0,0 +1,17 @@
+#!/usr/bin/env stap
+
+# print all system calls on the system
+
+probe syscall.* {
+ if (execname() != "staprun")
+ printf("%s: %s (%s) = ", execname(), name, argstr)
+}
+
+probe syscall.*.return {
+ if (execname() != "staprun")
+ printf("%s\n", retstr)
+}
+
+probe end {
+ printf("\n")
+}
diff --git a/testsuite/systemtap.examples/small_demos/top.stp b/testsuite/systemtap.examples/small_demos/top.stp
new file mode 100755
index 00000000..b46b9940
--- /dev/null
+++ b/testsuite/systemtap.examples/small_demos/top.stp
@@ -0,0 +1,24 @@
+#!/usr/bin/env stap
+#
+# This script continuously lists the top 20 systemcalls on the system
+#
+
+global syscalls
+
+function print_top () {
+ printf ("SYSCALL\t\t\t\tCOUNT\n")
+ foreach ([name] in syscalls- limit 20)
+ printf("%-20s\t\t%5d\n",name, syscalls[name])
+ printf("--------------------------------------\n")
+ delete syscalls
+}
+
+probe syscall.* {
+ syscalls[probefunc()]++
+}
+
+# print top syscalls every 5 seconds
+probe timer.ms(5000) {
+ print_top ()
+}
+
diff --git a/testsuite/systemtap.examples/socket-trace.stp b/testsuite/systemtap.examples/socket-trace.stp
new file mode 100755
index 00000000..13ab8e06
--- /dev/null
+++ b/testsuite/systemtap.examples/socket-trace.stp
@@ -0,0 +1,8 @@
+#! /usr/bin/env stap
+
+probe kernel.function("*@net/socket.c").call {
+ printf ("%s -> %s\n", thread_indent(1), probefunc())
+}
+probe kernel.function("*@net/socket.c").return {
+ printf ("%s <- %s\n", thread_indent(-1), probefunc())
+}
diff --git a/testsuite/systemtap.examples/socktop b/testsuite/systemtap.examples/socktop
new file mode 100755
index 00000000..123e37e9
--- /dev/null
+++ b/testsuite/systemtap.examples/socktop
@@ -0,0 +1,318 @@
+#!/bin/bash
+
+# Socktop systemtap script
+# Copyright (C) 2006 IBM Corp.
+#
+# This file is part of systemtap, and is free software. You can
+# redistribute it and/or modify it under the terms of the GNU General
+# Public License (GPL); either version 2, or (at your option) any
+# later version.
+
+###
+### socktop - Combination shell/systemtap script to track reads and writes
+### on sockets by process. Can be filtered by process IDs and
+### names, protocols, protocol families, users and socket type.
+###
+
+# Filter options
+F_PROTSTR=""; F_PROT=0 # Filter by protocol
+F_FAMSTR=""; F_FAM=0 # Filter by protocol family
+F_TYPESTR=""; F_TYPE=0 # Filter by socket type
+F_PIDSTR=""; F_PID=0 # Filter by process ID
+F_NAMESTR=""; F_NAME=0 # Filter by process name
+F_UIDSTR=""; F_UID=0 # Filter by user
+FILTER=0 # Any filters specified?
+
+# Print options
+P_INTERVAL=5 # default interval between output
+P_DEVICES=0 # default is don't display network device traffic
+P_NUMTOP=10 # default number of processes and network devices to print
+
+DELIM=","
+
+function usage {
+ echo "USAGE: socktop [-d] [-i interval] [-N num] [-P protocol]... [-f family]..."
+ echo " [-t stype]... [-n pname]... [-p pid]... [-u username]... [-h]"
+ echo " -d # print network device traffic (default: off)"
+ echo " -i interval # interval in seconds between printing (default: $P_INTERVAL)"
+ echo " -N num # number of top processes and devices to print (default: $P_NUMTOP)"
+ echo " -f family # this protocol family only (default: all)"
+ echo " -P protocol # this protocol only (default: all)"
+ echo " -t stype # this socket type only (default: all)"
+ echo " -n pname # this process name only (default: all)"
+ echo " -p pid # this process ID only (default: all)"
+ echo " -u username # this user only (default: all)"
+ echo " -h # print this help text"
+ echo ""
+ echo "Protocol Families:"
+ echo " LOCAL, INET, INET6, IPX, NETLINK, X25, AX25, ATMPVC, APPLETALK, PACKET"
+ echo ""
+ echo "Protocols:"
+ echo " TCP, UDP, SCTP, IP, FC, ... (see /etc/protocols for complete list)"
+ echo ""
+ echo "Socket Types:"
+ echo " STREAM, DGRAM, RAW, RDM, SEQPACKET, DCCP, PACKET"
+}
+
+# Process options
+while getopts df:i:n:N:P:p:t:u:h option; do
+ case $option in
+ d) P_DEVICES=1 ;;
+ i) P_INTERVAL=$OPTARG ;;
+ N) P_NUMTOP=$OPTARG ;;
+ f) let "F_FAM++"
+ F_FAMSTR=$OPTARG$DELIM$F_FAMSTR ;;
+ n) let "F_NAME++"
+ F_NAMESTR=$OPTARG$DELIM$F_NAMESTR ;;
+ p) let "F_PID++"
+ F_PIDSTR=$OPTARG$DELIM$F_PIDSTR ;;
+ P) let "F_PROT++"
+ F_PROTSTR=$OPTARG$DELIM$F_PROTSTR ;;
+ t) let "F_TYPE++"
+ F_TYPESTR=$OPTARG$DELIM$F_TYPESTR ;;
+ u) uid=`awk -F: '$1 == name {print $3}' name=$OPTARG /etc/passwd`
+ if [[ $uid != "" ]]; then
+ let "F_UID++"
+ F_UIDSTR=$uid$DELIM$F_UIDSTR
+ else
+ echo "ERROR: Unknown user:" $OPTARG
+ let "ERROR++"
+ fi ;;
+ h|?|*) usage
+ exit 1 ;;
+ esac
+done
+
+if [[ $ERROR > 0 ]]; then
+ exit 1
+fi
+
+if [[ $F_FAM > 0 || $F_NAME > 0 || $F_PID > 0 ||
+ $F_PROT > 0 || $F_TYPE > 0 || $F_UID > 0 ]]; then
+ FILTER=1
+fi
+
+#
+# Pass a timezone adjustment value to the stap script
+#
+TZ=`date "+%z"`
+TZ_SIGN=`echo $TZ | cut -c1`
+TZ_HOURS=`echo $TZ | cut -c2-3`
+TZ_MINS=`echo $TZ | cut -c4-5`
+TZ_ADJUST=$TZ_SIGN$((10#$TZ_HOURS*60*60+10#$TZ_MINS*60))
+
+#
+# Start the systemtap script
+#
+stap -e '
+global execname, user, if_tx, if_rx, if_dev
+global sk_tx, sk_rx, sk_pid
+global f_name_str, f_pid_str, f_prot_str, f_fam_str, f_type_str, f_uid_str
+global f_name, f_pid, f_prot, f_fam, f_type, f_uid
+
+probe begin
+{
+ # If no filters specified, skip filter processing
+ if ('$FILTER' == 0) next
+
+ f_name_str = "'$F_NAMESTR'"
+ f_pid_str = "'$F_PIDSTR'"
+ f_prot_str = "'$F_PROTSTR'"
+ f_fam_str = "'$F_FAMSTR'"
+ f_type_str = "'$F_TYPESTR'"
+ f_uid_str = "'$F_UIDSTR'"
+
+ delim = "'$DELIM'"
+ error = 0
+
+ # Protocols
+ if ('$F_PROT') {
+ prot = tokenize(f_prot_str, delim)
+ while (prot != "") {
+ p = sock_prot_str2num(prot)
+ if (p < 0) {
+ printf("ERROR: Unknown protocol: %s\n", prot)
+ error++
+ } else
+ f_prot[p] = 1
+ prot = tokenize("", delim)
+ }
+ }
+
+ # Protocol families
+ if ('$F_FAM') {
+ fam = tokenize(f_fam_str, delim)
+ while (fam != "") {
+ f = sock_fam_str2num(fam)
+ if (f < 0) {
+ printf("ERROR: Unknown protocol family: %s\n", fam)
+ error++
+ } else
+ f_fam[f] = 1
+ fam = tokenize("", delim)
+ }
+ }
+
+ # Process names
+ if ('$F_NAME') {
+ pname = tokenize(f_name_str, delim)
+ while (pname != "") {
+ f_name[pname] = 1
+ pname = tokenize("", delim)
+ }
+ }
+
+ # Process IDs
+ if ('$F_PID') {
+ pid = tokenize(f_pid_str, delim)
+ while (pid != "") {
+ f_pid[strtol(pid, 10)] = 1
+ pid = tokenize("", delim)
+ }
+ }
+
+ # Socket types
+ if ('$F_TYPE') {
+ stype = tokenize(f_type_str, delim)
+ while (stype != "") {
+ t = sock_type_str2num(stype)
+ if (t < 0) {
+ printf("ERROR: Unknown socket type: %s\n", stype)
+ error++
+ } else
+ f_type[t] = 1
+ stype = tokenize("", delim)
+ }
+ }
+
+ # User IDs
+ if ('$F_UID') {
+ uid = tokenize(f_uid_str, delim)
+ while (uid != "") {
+ f_uid[strtol(uid, 10)] = 1
+ uid = tokenize("", delim)
+ }
+ }
+
+ if (error) exit()
+}
+
+probe netdev.transmit
+{
+ if ('$P_DEVICES') {
+ if_tx[dev_name] <<< length
+ if_dev[dev_name] ++
+ }
+}
+
+probe netdev.receive
+{
+ if ('$P_DEVICES') {
+ if_rx[dev_name] <<< length
+ if_dev[dev_name] ++
+ }
+}
+
+probe socket.send
+{
+ if (!success) next
+
+ pid = pid()
+ uid = uid()
+ ename = execname()
+
+ # Check filters
+ if ('$FILTER') {
+ if ('$F_PROT' && !(protocol in f_prot)) next
+ if ('$F_FAM' && !(family in f_fam)) next
+ if ('$F_PID' && !(pid in f_pid)) next
+ if ('$F_NAME' && !(ename in f_name)) next
+ if ('$F_UID' && !(uid in f_uid)) next
+ if ('$F_TYPE' && !(type in f_type)) next
+ }
+
+ execname[pid] = ename
+ user[pid] = uid
+ sk_tx[pid, protocol, family] <<< size
+ sk_pid[pid, protocol, family] += size
+}
+
+probe socket.receive
+{
+ if (!success) next
+
+ pid = pid()
+ uid = uid()
+ ename = execname()
+
+ # Check filters
+ if ('$FILTER') {
+ if ('$F_PROT' && !(protocol in f_prot)) next
+ if ('$F_FAM' && !(family in f_fam)) next
+ if ('$F_PID' && !(pid in f_pid)) next
+ if ('$F_NAME' && !(ename in f_name)) next
+ if ('$F_UID' && !(uid in f_uid)) next
+ if ('$F_TYPE' && !(type in f_type)) next
+ }
+
+ execname[pid] = ename
+ user[pid] = uid
+ sk_rx[pid, protocol, family] <<< size
+ sk_pid[pid, protocol, family] += size
+}
+
+function print_activity()
+{
+ # Print top processes
+ max = '$P_NUMTOP'
+ time = gettimeofday_s() + '$TZ_ADJUST'
+
+ printf("======================= %s ========================\n", ctime(time))
+ printf("------------------------------- PROCESSES -------------------------------\n")
+ printf("%-5s %-5s %7s %7s %7s %7s %-4s %-8s %-15s\n",
+ "PID", "UID", "#SEND", "#RECV", "SEND_KB",
+ "RECV_KB", "PROT", "FAMILY", "COMMAND")
+ foreach ([pid, prot, fam] in sk_pid- limit max) {
+ n_sk_tx = @count(sk_tx[pid, prot, fam])
+ n_sk_rx = @count(sk_rx[pid, prot, fam])
+ printf("%-5d %-5d %7d %7d %7d %7d %-4s %-8s %-15s\n",
+ pid, user[pid], n_sk_tx, n_sk_rx,
+ n_sk_tx ? @sum(sk_tx[pid, prot, fam])/1024 : 0,
+ n_sk_rx ? @sum(sk_rx[pid, prot, fam])/1024 : 0,
+ sock_prot_num2str(prot), sock_fam_num2str(fam),
+ execname[pid])
+ }
+
+ # Print top network devices
+ if ('$P_DEVICES') {
+ max = '$P_NUMTOP'
+ printf("-------------------------------- DEVICES --------------------------------\n")
+ printf("%-7s %13s %13s %15s %15s\n",
+ "DEV", "#XMIT", "#RECV", "XMIT_KB", "RECV_KB")
+ foreach ([dev] in if_dev- limit max) {
+ n_if_tx = @count(if_tx[dev])
+ n_if_rx = @count(if_rx[dev])
+ printf("%-7s %13d %13d %15d %15d\n", dev, n_if_tx, n_if_rx,
+ n_if_tx ? @sum(if_tx[dev])/1024 : 0,
+ n_if_rx ? @sum(if_rx[dev])/1024 : 0)
+ }
+ }
+
+ printf("=========================================================================\n\n")
+
+ delete execname
+ delete user
+ delete sk_tx
+ delete sk_rx
+ delete sk_pid
+ delete if_tx
+ delete if_rx
+ delete if_dev
+}
+
+
+probe timer.s('$P_INTERVAL')
+{
+ print_activity()
+}
+'
diff --git a/testsuite/systemtap.examples/socktop.txt b/testsuite/systemtap.examples/socktop.txt
new file mode 100644
index 00000000..0ebce003
--- /dev/null
+++ b/testsuite/systemtap.examples/socktop.txt
@@ -0,0 +1,66 @@
+#./socktop -d
+
+======================= Mon Jan 29 12:27:24 2007 ========================
+------------------------------- PROCESSES -------------------------------
+PID UID #SEND #RECV SEND_KB RECV_KB PROT FAMILY COMMAND
+3051 0 0 3159 0 4702 TCP INET firefox-bin
+2578 0 121 101 164 181 IP LOCAL Xvnc
+3051 0 74 180 176 164 IP LOCAL firefox-bin
+2578 0 8 79 39 0 TCP INET Xvnc
+2583 0 2 1 5 0 IP LOCAL xterm
+-------------------------------- DEVICES --------------------------------
+DEV #XMIT #RECV XMIT_KB RECV_KB
+eth0 2236 3448 182 4875
+=========================================================================
+
+======================= Mon Jan 29 12:27:29 2007 ========================
+------------------------------- PROCESSES -------------------------------
+PID UID #SEND #RECV SEND_KB RECV_KB PROT FAMILY COMMAND
+2578 0 580 582 1300 1315 IP LOCAL Xvnc
+3051 0 296 600 970 965 IP LOCAL firefox-bin
+3051 0 0 664 0 987 TCP INET firefox-bin
+2695 0 62 145 298 297 IP LOCAL wnck-applet
+2578 0 23 131 88 0 TCP INET Xvnc
+2685 0 85 211 42 34 IP LOCAL metacity
+2583 0 2 3 4 0 IP LOCAL xterm
+2620 0 40 78 0 2 IP LOCAL gnome-settings-
+2688 0 3 7 0 0 IP LOCAL gnome-panel
+2690 0 1 7 0 0 IP LOCAL nautilus
+-------------------------------- DEVICES --------------------------------
+DEV #XMIT #RECV XMIT_KB RECV_KB
+eth0 580 881 124 1030
+=========================================================================
+
+
+# ./socktop -d -P TCP -P UDP
+
+======================= Mon Jan 29 12:29:15 2007 ========================
+------------------------------- PROCESSES -------------------------------
+PID UID #SEND #RECV SEND_KB RECV_KB PROT FAMILY COMMAND
+2578 0 16 183 27 1 TCP INET Xvnc
+-------------------------------- DEVICES --------------------------------
+DEV #XMIT #RECV XMIT_KB RECV_KB
+eth0 135 204 35 9
+=========================================================================
+
+======================= Mon Jan 29 12:29:20 2007 ========================
+------------------------------- PROCESSES -------------------------------
+PID UID #SEND #RECV SEND_KB RECV_KB PROT FAMILY COMMAND
+3051 0 1 1814 0 3236 TCP INET firefox-bin
+2578 0 52 155 198 1 TCP INET Xvnc
+3051 0 4 4 0 0 UDP INET firefox-bin
+-------------------------------- DEVICES --------------------------------
+DEV #XMIT #RECV XMIT_KB RECV_KB
+eth0 1574 2589 297 3366
+=========================================================================
+
+======================= Mon Jan 29 12:29:25 2007 ========================
+------------------------------- PROCESSES -------------------------------
+PID UID #SEND #RECV SEND_KB RECV_KB PROT FAMILY COMMAND
+3051 0 0 2508 0 3721 TCP INET firefox-bin
+2578 0 2 39 10 0 TCP INET Xvnc
+-------------------------------- DEVICES --------------------------------
+DEV #XMIT #RECV XMIT_KB RECV_KB
+eth0 1767 2698 123 3858
+=========================================================================
+
diff --git a/testsuite/systemtap.examples/syscalls_by_pid.stp b/testsuite/systemtap.examples/syscalls_by_pid.stp
new file mode 100755
index 00000000..47aa4955
--- /dev/null
+++ b/testsuite/systemtap.examples/syscalls_by_pid.stp
@@ -0,0 +1,28 @@
+#! /usr/bin/env stap
+
+# Copyright (C) 2006 IBM Corp.
+#
+# This file is part of systemtap, and is free software. You can
+# redistribute it and/or modify it under the terms of the GNU General
+# Public License (GPL); either version 2, or (at your option) any
+# later version.
+
+#
+# Print the system call count by process ID in descending order.
+#
+
+global syscalls
+
+probe begin {
+ print ("Collecting data... Type Ctrl-C to exit and display results\n")
+}
+
+probe syscall.* {
+ syscalls[pid()]++
+}
+
+probe end {
+ printf ("%-10s %-s\n", "#SysCalls", "PID")
+ foreach (pid in syscalls-)
+ printf("%-10d %-d\n", syscalls[pid], pid)
+}
diff --git a/testsuite/systemtap.examples/syscalls_by_pid.txt b/testsuite/systemtap.examples/syscalls_by_pid.txt
new file mode 100644
index 00000000..4943a139
--- /dev/null
+++ b/testsuite/systemtap.examples/syscalls_by_pid.txt
@@ -0,0 +1,35 @@
+# stap syscalls_by_pid.stp
+Collecting data... Type Ctrl-C to exit and display results
+^C
+#SysCalls PID
+2293 31866
+765 31081
+567 30983
+557 30965
+554 31008
+523 30985
+273 30991
+118 9585
+115 2130
+77 30928
+65 1988
+50 31006
+42 2492
+40 31077
+36 2487
+35 2490
+23 2257
+22 2366
+20 8682
+20 2048
+17 31197
+16 31067
+14 2313
+10 31011
+8 1
+5 31074
+3 1978
+3 1975
+3 2467
+3 30932
+
diff --git a/testsuite/systemtap.examples/syscalls_by_proc.stp b/testsuite/systemtap.examples/syscalls_by_proc.stp
new file mode 100755
index 00000000..af7d6932
--- /dev/null
+++ b/testsuite/systemtap.examples/syscalls_by_proc.stp
@@ -0,0 +1,28 @@
+#! /usr/bin/env stap
+
+# Copyright (C) 2006 IBM Corp.
+#
+# This file is part of systemtap, and is free software. You can
+# redistribute it and/or modify it under the terms of the GNU General
+# Public License (GPL); either version 2, or (at your option) any
+# later version.
+
+#
+# Print the system call count by process name in descending order.
+#
+
+global syscalls
+
+probe begin {
+ print ("Collecting data... Type Ctrl-C to exit and display results\n")
+}
+
+probe syscall.* {
+ syscalls[execname()]++
+}
+
+probe end {
+ printf ("%-10s %-s\n", "#SysCalls", "Process Name")
+ foreach (proc in syscalls-)
+ printf("%-10d %-s\n", syscalls[proc], proc)
+}
diff --git a/testsuite/systemtap.examples/syscalls_by_proc.txt b/testsuite/systemtap.examples/syscalls_by_proc.txt
new file mode 100644
index 00000000..dd554083
--- /dev/null
+++ b/testsuite/systemtap.examples/syscalls_by_proc.txt
@@ -0,0 +1,58 @@
+# stap syscalls_by_proc.stp
+Collecting data... Type Ctrl-C to exit and display results
+^C
+#SysCalls Process Name
+53832 make
+15275 sh
+6764 staprun
+2291 gcc
+2225 mixer_applet2
+1638 gnome-settings-
+1603 gnome-panel
+1577 rm
+1567 nautilus
+1557 trashapplet
+1443 cat
+1404 sshd
+1207 cc1
+779 ls
+764 gnome-vfs-daemo
+638 bash
+610 collect2
+356 mkdir
+354 artsd
+340 hald-addon-stor
+338 hidd
+280 ld
+260 irqbalance
+238 xterm
+212 automount
+182 sed
+176 as
+141 dnsdomainname
+130 date
+129 cmp
+124 clock-applet
+122 nm-applet
+104 grep
+88 hostname
+75 whoami
+70 rpc.idmapd
+68 httpd
+68 python
+61 gam_server
+56 pam_timestamp_c
+53 wc
+49 sendmail
+46 echo
+40 tail
+39 expr
+37 uname
+35 pam-panel-icon
+24 init
+17 mapping-daemon
+9 syslogd
+3 klogd
+3 hald
+3 gconfd-2
+1 cupsd
diff --git a/testsuite/systemtap.examples/syscalltimes b/testsuite/systemtap.examples/syscalltimes
new file mode 100755
index 00000000..84ca77a9
--- /dev/null
+++ b/testsuite/systemtap.examples/syscalltimes
@@ -0,0 +1,248 @@
+#!/bin/bash
+
+# Syscalltimes systemtap script
+# Copyright (C) 2007 IBM Corp.
+#
+# This file is part of systemtap, and is free software. You can
+# redistribute it and/or modify it under the terms of the GNU General
+# Public License (GPL); either version 2, or (at your option) any
+# later version.
+
+###
+### syscalltime - Combination shell/systemtap script to measure system call
+### counts and times. Can be filtered by process IDs, process
+### names and users.
+###
+
+# Filter options
+F_PIDSTR=""; F_PID=0 # Filter by process ID
+F_EXECSTR=""; F_EXEC=0 # Filter by process name
+F_UIDSTR=""; F_UID=0 # Filter by user
+FILTER=0 # Any filters specified?
+
+# Print options
+P_TOTALS=0 # Print totals
+P_VERBOSE_STR="" # Print verbose build output
+
+DELIM=","
+
+function usage {
+ echo "USAGE: syscalltimes [-n pname]... [-p pid]... [-u username]..."
+ echo " [-v]... [-t] [-h]"
+ echo " -n pname # filter by this process name"
+ echo " -p pid # filter by this process ID"
+ echo " -u username # filter by this user"
+ echo " -t # print totals (default with filters: OFF"
+ echo " default without filters: ON)"
+ echo " -v # print verbose output during SystemTap module creation"
+ echo " -h # print this help text"
+ echo ""
+ echo "NOTE: This script can take long time to build. Use -v[vv] to monitor"
+ echo " the module creation and build process."
+}
+
+# Process options
+while getopts n:p:u:vth option; do
+ case $option in
+ n) let "F_EXEC++"
+ F_EXECSTR=$OPTARG$DELIM$F_EXECSTR ;;
+
+ p) let "F_PID++"
+ F_PIDSTR=$OPTARG$DELIM$F_PIDSTR ;;
+
+ u) uid=`awk -F: '$1 == name {print $3}' name=$OPTARG /etc/passwd`
+ if [[ $uid != "" ]]; then
+ let "F_UID++"
+ F_UIDSTR=$uid$DELIM$F_UIDSTR
+ else
+ echo "ERROR: Unknown user:" $OPTARG
+ let "ERROR++"
+ fi ;;
+
+ v) P_VERBOSE_STR="-v "$P_VERBOSE_STR ;;
+
+ t) P_TOTALS=1 ;;
+
+ h|?|*) usage
+ exit 1 ;;
+ esac
+done
+
+if [[ $ERROR > 0 ]]; then
+ exit 1
+fi
+
+if [[ $F_EXEC > 0 || $F_PID > 0 || $F_UID > 0 ]]; then
+ FILTER=1
+fi
+
+echo "Creating and building SystemTap module..."
+
+#
+# SystemTap script
+#
+stap $P_VERBOSE_STR -e '
+global start, timebycall, timebypid, timebyuid, timebyexec
+global f_exec_str, f_pid_str, f_uid_str
+global f_exec, f_pid, f_uid
+global prt_totals, filter_str
+
+probe begin {
+ printf("Collecting data - type Ctrl-C to print output and exit...\n")
+
+ # If no filters specified, skip filter processing
+ if ('$FILTER' == 0) {
+ filter_str = " (unfiltered)"
+ prt_totals = 1 // On by default if no filtering
+ next
+ } else
+ filter_str = " (filtered)"
+
+ prt_totals = '$P_TOTALS'
+ f_exec_str = "'$F_EXECSTR'"
+ f_pid_str = "'$F_PIDSTR'"
+ f_uid_str = "'$F_UIDSTR'"
+
+ delim = "'$DELIM'"
+
+ # Process names
+ if ('$F_EXEC') {
+ pname = tokenize(f_exec_str, delim)
+ while (pname != "") {
+ f_exec[pname] = 1
+ pname = tokenize("", delim)
+ }
+ }
+
+ # Process IDs
+ if ('$F_PID') {
+ pid = tokenize(f_pid_str, delim)
+ while (pid != "") {
+ f_pid[strtol(pid, 10)] = 1
+ pid = tokenize("", delim)
+ }
+ }
+
+ # User IDs
+ if ('$F_UID') {
+ uid = tokenize(f_uid_str, delim)
+ while (uid != "") {
+ f_uid[strtol(uid, 10)] = 1
+ uid = tokenize("", delim)
+ }
+ }
+}
+
+probe syscall.* {
+ start[name, tid()] = gettimeofday_ns()
+}
+
+probe syscall.*.return {
+ # Skip if we have not seen this before
+ if (!([name, tid()] in start)) next
+
+ delta = gettimeofday_ns() - start[name, tid()]
+
+ # Check filters
+ if ('$FILTER') {
+ target = 0
+ if (pid() in f_pid) {
+ timebypid[name, pid()] <<< delta
+ target = 1
+ }
+ if (uid() in f_uid) {
+ timebyuid[name, uid()] <<< delta
+ target = 1
+ }
+ if (execname() in f_exec) {
+ timebyexec[name, execname()] <<< delta
+ target = 1
+ }
+ } else
+ target = 1
+
+ # Totals
+ if (target && prt_totals)
+ timebycall[name] <<< delta
+
+ delete start[name, tid()]
+}
+
+function print_header() {
+ printf("%22s %10s %12s %12s %12s %12s\n",
+ "System Call", "Count", "Total ns",
+ "Avg ns", "Min ns", "Max ns")
+}
+
+probe end {
+ if (prt_totals) {
+ printf("\nTimes for all processes%s:\n\n", filter_str)
+ print_header()
+ foreach (call in timebycall)
+ printf("%22s %10d %12d %12d %12d %12d\n", call,
+ @count(timebycall[call]),
+ @sum(timebycall[call]),
+ @avg(timebycall[call]),
+ @min(timebycall[call]),
+ @max(timebycall[call]))
+ }
+
+ if ('$F_PID') {
+ curpid = -1
+ foreach ([call, pid-] in timebypid) {
+ if (curpid != pid) {
+ curpid = pid
+ printf("\nTimes for process ID %d:\n\n", curpid)
+ print_header()
+ }
+ printf("%22s %10d %12d %12d %12d %12d\n", call,
+ @count(timebypid[call, pid]),
+ @sum(timebypid[call, pid]),
+ @avg(timebypid[call, pid]),
+ @min(timebypid[call, pid]),
+ @max(timebypid[call, pid]))
+ }
+ printf("\n")
+ }
+
+ if ('$F_EXEC') {
+ curexec = ""
+ foreach ([call, exec-] in timebyexec) {
+ if (curexec != exec) {
+ curexec = exec
+ printf("\nTimes for process name %s:\n\n", curexec)
+ print_header()
+ }
+ printf("%22s %10d %12d %12d %12d %12d\n", call,
+ @count(timebyexec[call, exec]),
+ @sum(timebyexec[call, exec]),
+ @avg(timebyexec[call, exec]),
+ @min(timebyexec[call, exec]),
+ @max(timebyexec[call, exec]))
+ }
+ printf("\n")
+ }
+
+ if ('$F_UID') {
+ curuid = -1
+ foreach ([call, uid-] in timebyuid) {
+ if (curuid != uid) {
+ curuid = uid
+ printf("\nTimes for user ID %d:\n\n", curuid)
+ print_header()
+ }
+ printf("%22s %10d %12d %12d %12d %12d\n", call,
+ @count(timebyuid[call, uid]),
+ @sum(timebyuid[call, uid]),
+ @avg(timebyuid[call, uid]),
+ @min(timebyuid[call, uid]),
+ @max(timebyuid[call, uid]))
+ }
+ printf("\n")
+ }
+
+ delete timebycall
+ delete timebypid
+ delete timebyuid
+ delete timebyexec
+}'
diff --git a/testsuite/systemtap.examples/syscalltimes.txt b/testsuite/systemtap.examples/syscalltimes.txt
new file mode 100644
index 00000000..d50f73ad
--- /dev/null
+++ b/testsuite/systemtap.examples/syscalltimes.txt
@@ -0,0 +1,155 @@
+# ./syscalltimes -h
+USAGE: syscalltimes [-n pname]... [-p pid]... [-u username]...
+ [-v]... [-t] [-h]
+ -n pname # filter by this process name
+ -p pid # filter by this process ID
+ -u username # filter by this user
+ -t # print totals (default with filters: OFF
+ default without filters: ON)
+ -v # print verbose output during SystemTap module creation
+ -h # print this help text
+
+NOTE: This script can take long time to build. Use -v[vv] to monitor
+ the module creation and build process.
+
+
+# ./syscalltimes -n top -n vi
+Creating and building SystemTap module...
+Collecting data - type Ctrl-C to print output and exit...
+
+Times for process name vi:
+
+ System Call Count Total ns Avg ns Min ns Max ns
+ access 4 59169 14792 7770 27556
+ rt_sigprocmask 6 32879 5479 5328 6132
+ rt_sigaction 22 119127 5414 5291 6293
+ select 15 1605144751 107009650 7386 1117677549
+ sysinfo 1 13178 13178 13178 13178
+ lseek 2 12869 6434 6331 6538
+ getuid 3 16839 5613 5468 5757
+ getrlimit 1 5558 5558 5558 5558
+ munmap 8 103326 12915 9689 19190
+ getpid 1 5639 5639 5639 5639
+ unlink 3 143502 47834 20291 97191
+ arch_prctl 1 6296 6296 6296 6296
+ chdir 6 58086 9681 7213 16062
+ getcwd 9 81327 9036 6820 17583
+ read 28 341507 12196 6007 54806
+ fcntl 4 23418 5854 5478 6459
+ sigaltstack 1 5845 5845 5845 5845
+ mprotect 13 130272 10020 8255 17130
+ statfs 1 10223 10223 10223 10223
+ fstat 20 118660 5933 5446 7050
+ readlink 1 17884 17884 17884 17884
+ readlinkat 1 7889 7889 7889 7889
+ socket 2 24932 12466 8090 16842
+ stat 13 120911 9300 7376 19549
+ ioctl 19 135172 7114 5504 11711
+ execve 1 262658 262658 262658 262658
+ write 15 382744 25516 8391 136359
+ uname 1 6772 6772 6772 6772
+ close 30 210468 7015 5478 12543
+ fchdir 6 34269 5711 5496 6185
+ open 31 474649 15311 7807 54475
+ chmod 1 12865 12865 12865 12865
+ brk 6 48116 8019 5782 10240
+ lstat 2 15369 7684 7334 8035
+ connect 2 29287 14643 10616 18671
+
+Times for process name top:
+
+ System Call Count Total ns Avg ns Min ns Max ns
+ arch_prctl 1 6424 6424 6424 6424
+ fcntl 97 607311 6260 5170 10873
+ read 970 12341710 12723 5574 446707
+ lseek 11 66250 6022 5481 7165
+ rt_sigaction 71 380049 5352 5255 6374
+ access 5 66406 13281 8942 24323
+ select 3 6385526578 2128508859 499261647 2999551597
+ getdents 21 889837 42373 6386 73490
+ getuid 1 5494 5494 5494 5494
+ munmap 15 174255 11617 8872 17670
+ write 10 2309851 230985 16248 2006254
+ uname 1 10474 10474 10474 10474
+ close 932 5749946 6169 5348 21248
+ ioctl 14 122233 8730 5824 14243
+ execve 1 261447 261447 261447 261447
+ brk 4 26527 6631 5493 8285
+ connect 2 28533 14266 10756 17777
+ open 934 9289314 9945 8473 30315
+ mprotect 10 97990 9799 8295 14636
+ stat 455 3834994 8428 7920 26084
+ socket 2 21980 10990 8990 12990
+ fstat 26 150418 5785 5426 7127
+ alarm 90 536017 5955 5543 11487
+
+
+# ./syscalltimes -v
+Creating and building SystemTap module...
+Pass 1: parsed user script and 42 library script(s) in 200usr/10sys/218real ms.
+Pass 2: analyzed script: 768 probe(s), 15 function(s), 15 embed(s), 13 global(s) in 35870usr/140sys/36036real ms.
+Pass 3: using cached /root/.systemtap/cache/d5/stap_d5fcd430388d4f4a30f63d03aaa3eb80_392196.c
+Pass 4: using cached /root/.systemtap/cache/d5/stap_d5fcd430388d4f4a30f63d03aaa3eb80_392196.ko
+Pass 5: starting run.
+Collecting data - type Ctrl-C to print output and exit...
+
+Times for all processes (unfiltered):
+
+ System Call Count Total ns Avg ns Min ns Max ns
+ writev 681 6526983 9584 6807 18709
+ write 421 4367057 10373 6424 52077
+ uname 15 98071 6538 6336 6787
+ close 459 9528659 20759 5265 1346856
+ inotify_add_watch 17 164258 9662 8000 17280
+ ioctl 1205 28994711 24062 5211 2928218
+ execve 12 2148953 179079 10195 280392
+ brk 309 2400150 7767 5383 23454
+ lstat 5 43864 8772 7938 10426
+ connect 24 352784 14699 10679 25868
+ getppid 12 71219 5934 5812 6123
+ wait4 24 20952033 873001 5664 3387688
+ open 377 22181286 58836 8819 3011655
+ dup2 18 109197 6066 5865 6403
+ bind 3 25322 8440 8263 8759
+ poll 1034 36509105361 35308612 5499 1999784046
+ getgid 12 65851 5487 5335 5667
+ compat_execve 12 3012173 251014 182782 472356
+ mprotect 150 1434021 9560 7854 13812
+ gettimeofday 10 60416 6041 5238 7429
+ recvmsg 9 116065 12896 6889 37388
+ readlink 12 638216 53184 46337 64203
+ readlinkat 12 530499 44208 37794 55136
+ stat 140 1244798 8891 6702 17331
+ socket 39 435318 11162 7642 16694
+ getsockname 3 18899 6299 6198 6443
+ statfs 6 62737 10456 10311 10671
+ fstat 238 1400126 5882 5502 12739
+ geteuid 12 73475 6122 5248 14048
+ readv 27 349998 12962 7150 21210
+ arch_prctl 21 135320 6443 6231 6832
+ nanosleep 28 8927802107 318850075 150954837 2001911237
+ futex 595 8755563465 14715232 5431 1000945645
+ read 2586 5154654212 1993292 5622 4985306501
+ getpgrp 12 67137 5594 5469 5740
+ fcntl 51 289553 5677 5353 6835
+ pipe 12 122220 10185 8771 13959
+ setitimer 159 1004756 6319 5551 8776
+ lseek 4 24304 6076 5900 6253
+ mmap2 19 182403 9600 7496 13574
+ access 105 1220874 11627 8077 33600
+ rt_sigreturn 93 665180 7152 5541 8265
+ rt_sigaction 171 967575 5658 5278 18684
+ rt_sigprocmask 132 760337 5760 5273 14170
+ clock_gettime 151 997395 6605 5275 9090
+ pread 192 2387721 12436 5679 43553
+ select 925 24357064459 26331961 6669 2861600879
+ getegid 12 63624 5302 5200 5466
+ getpid 12 66761 5563 5348 5701
+ getuid 12 67112 5592 5483 5790
+ sendto 3 54766 18255 17541 19501
+ munmap 116 1432698 12350 8634 48526
+ getdents 6 57855 9642 6248 13313
+ times 10 59281 5928 5514 6617
+ ppoll 24 4799366329 199973597 199872030 200070128
+Pass 5: run completed in 20usr/90sys/8215real ms.
+
diff --git a/testsuite/systemtap.examples/wait4time.stp b/testsuite/systemtap.examples/wait4time.stp
new file mode 100755
index 00000000..568239b9
--- /dev/null
+++ b/testsuite/systemtap.examples/wait4time.stp
@@ -0,0 +1,60 @@
+#! /usr/bin/env stap
+
+/*
+ * Copyright (C) 2006 Daniel Berrange, Red Hat Inc.
+ * Copyright (C) 2007 Will Cohen, Red Hat, Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Print out the amount of time spent in the read and write systemcall
+ * when a process closes each file is closed. Note that the script needs
+ * to be running before the open operations occur for the script
+ * to record data.
+ *
+ * Format is:
+ * timestamp pid (executabable) wait4: time_us pid
+ *
+ * 155789807 4196 (ssh) wait4: 12 4197
+ * 158270531 3215 (bash) wait4: 5410460 -1
+ * 158270659 3215 (bash) wait4: 9 -1
+ * 158557461 2614 (sendmail) wait4: 27 -1
+ * 158557487 2614 (sendmail) wait4: 5 -1
+ *
+ */
+
+global start
+global entry_wait4
+global wait4_pid
+
+function timestamp:long() {
+ return gettimeofday_us() - start
+}
+
+function proc:string() {
+ return sprintf("%d (%s)", pid(), execname())
+}
+
+probe begin {
+ start = gettimeofday_us()
+}
+
+probe syscall.wait4 {
+ t = gettimeofday_us(); p = pid()
+ entry_wait4[p] = t
+ wait4_pid[p]=pid
+}
+
+probe syscall.wait4.return {
+ t = gettimeofday_us(); p = pid()
+ elapsed_time = t - entry_wait4[p]
+ printf("%d %s wait4: %d %d\n", timestamp(), proc(), elapsed_time,
+ wait4_pid[p])
+ delete entry_wait4[p]
+ delete wait4_pid[p]
+}