summaryrefslogtreecommitdiffstats
path: root/testsuite/systemtap.examples/small_demos
diff options
context:
space:
mode:
authorWilliam Cohen <wcohen@localhost.localdomain>2008-04-24 12:20:13 -0400
committerWilliam Cohen <wcohen@localhost.localdomain>2008-04-24 12:20:13 -0400
commit7f79ea13a0f64573ce13353257d322ae49ef0c27 (patch)
tree60de8da5af4c2bcc26abfb9430fdca66bdc20b98 /testsuite/systemtap.examples/small_demos
parentf90f92615df6ff2a62282359281889597e5dbf17 (diff)
downloadsystemtap-steved-7f79ea13a0f64573ce13353257d322ae49ef0c27.tar.gz
systemtap-steved-7f79ea13a0f64573ce13353257d322ae49ef0c27.tar.xz
systemtap-steved-7f79ea13a0f64573ce13353257d322ae49ef0c27.zip
Move examples to testsuite/systemtap.examples
Diffstat (limited to 'testsuite/systemtap.examples/small_demos')
-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
16 files changed, 486 insertions, 0 deletions
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 ()
+}
+