summaryrefslogtreecommitdiffstats
path: root/examples/small_demos
diff options
context:
space:
mode:
Diffstat (limited to 'examples/small_demos')
-rw-r--r--examples/small_demos/click.wavbin0 -> 1290 bytes
-rwxr-xr-xexamples/small_demos/close.stp7
-rw-r--r--examples/small_demos/demo_script.txt103
-rwxr-xr-xexamples/small_demos/key.stp22
-rwxr-xr-xexamples/small_demos/keyhack.stp15
-rwxr-xr-xexamples/small_demos/kmalloc.stp22
-rwxr-xr-xexamples/small_demos/kmalloc2.stp26
-rwxr-xr-xexamples/small_demos/prof.stp35
-rw-r--r--examples/small_demos/return.wavbin0 -> 6584 bytes
-rwxr-xr-xexamples/small_demos/sys.stp17
-rwxr-xr-xexamples/small_demos/top.stp28
11 files changed, 275 insertions, 0 deletions
diff --git a/examples/small_demos/click.wav b/examples/small_demos/click.wav
new file mode 100644
index 00000000..8214b229
--- /dev/null
+++ b/examples/small_demos/click.wav
Binary files differ
diff --git a/examples/small_demos/close.stp b/examples/small_demos/close.stp
new file mode 100755
index 00000000..341667f8
--- /dev/null
+++ b/examples/small_demos/close.stp
@@ -0,0 +1,7 @@
+probe syscall.close {
+ printf("%s: %s(%s) = ", execname(), name, argstr)
+}
+
+probe syscall.close.return {
+ printf("%s\n", returnstr(returnp))
+}
diff --git a/examples/small_demos/demo_script.txt b/examples/small_demos/demo_script.txt
new file mode 100644
index 00000000..40408c4d
--- /dev/null
+++ b/examples/small_demos/demo_script.txt
@@ -0,0 +1,103 @@
+> cd /root/systemtap
+
+A systemtap script can be as simple as a simgle line. For example,
+thge 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 script 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 Sycall 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 "stpd" 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/examples/small_demos/key.stp b/examples/small_demos/key.stp
new file mode 100755
index 00000000..0489524a
--- /dev/null
+++ b/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")
+ else
+ system("play click.wav")
+ }
+}
+
+probe begin {
+ printf("TYPEWRITER ON\n")
+}
+
+probe end {
+ printf("DONE\n")
+}
diff --git a/examples/small_demos/keyhack.stp b/examples/small_demos/keyhack.stp
new file mode 100755
index 00000000..3137baad
--- /dev/null
+++ b/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/examples/small_demos/kmalloc.stp b/examples/small_demos/kmalloc.stp
new file mode 100755
index 00000000..9157928d
--- /dev/null
+++ b/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/examples/small_demos/kmalloc2.stp b/examples/small_demos/kmalloc2.stp
new file mode 100755
index 00000000..2622dd2f
--- /dev/null
+++ b/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/examples/small_demos/prof.stp b/examples/small_demos/prof.stp
new file mode 100755
index 00000000..986be65e
--- /dev/null
+++ b/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_*") {
+ 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 (ms):%5d\ttotal(ms):%7d\n",
+ x, @count(ttime[x]), @avg(ttime[x]), @sum(ttime[x]))
+}
+
+global calltime, ttime
diff --git a/examples/small_demos/return.wav b/examples/small_demos/return.wav
new file mode 100644
index 00000000..20f978cc
--- /dev/null
+++ b/examples/small_demos/return.wav
Binary files differ
diff --git a/examples/small_demos/sys.stp b/examples/small_demos/sys.stp
new file mode 100755
index 00000000..c25055de
--- /dev/null
+++ b/examples/small_demos/sys.stp
@@ -0,0 +1,17 @@
+#!/usr/bin/env stap
+
+# print all system calls on the system
+
+probe syscall.* {
+ if (execname() != "stpd")
+ printf("%s: %s (%s) = ", execname(), name, argstr)
+}
+
+probe syscall.*.return {
+ if (execname() != "stpd")
+ printf("%s\n", retstr)
+}
+
+probe end {
+ printf("\n")
+}
diff --git a/examples/small_demos/top.stp b/examples/small_demos/top.stp
new file mode 100755
index 00000000..26d35ec8
--- /dev/null
+++ b/examples/small_demos/top.stp
@@ -0,0 +1,28 @@
+#!/usr/bin/env stap
+#
+# This script continuously lists the top 20 systemcalls on the system
+#
+
+global syscalls
+
+function print_top () {
+ cnt=0
+ log ("SYSCALL\t\t\t\tCOUNT")
+ foreach ([name] in syscalls-) {
+ printf("%-20s\t\t%5d\n",name, syscalls[name])
+ if (cnt++ == 20)
+ break
+ }
+ printf("--------------------------------------\n")
+ delete syscalls
+}
+
+probe kernel.function("sys_*") {
+ syscalls[probefunc()]++
+}
+
+# print top syscalls every 5 seconds
+probe timer.ms(5000) {
+ print_top ()
+}
+