From e1d96810d0c2c1da6ec36eb81c642bcc6cf420c8 Mon Sep 17 00:00:00 2001 From: hunt Date: Mon, 20 Mar 2006 16:05:24 +0000 Subject: *** empty log message *** --- examples/click.wav | Bin 1290 -> 0 bytes examples/key.stp | 22 -------- examples/prof.stp | 35 ------------ examples/return.wav | Bin 6584 -> 0 bytes examples/small_demos/click.wav | Bin 0 -> 1290 bytes examples/small_demos/close.stp | 7 +++ examples/small_demos/demo_script.txt | 103 +++++++++++++++++++++++++++++++++++ examples/small_demos/key.stp | 22 ++++++++ examples/small_demos/keyhack.stp | 15 +++++ examples/small_demos/kmalloc.stp | 22 ++++++++ examples/small_demos/kmalloc2.stp | 26 +++++++++ examples/small_demos/prof.stp | 35 ++++++++++++ examples/small_demos/return.wav | Bin 0 -> 6584 bytes examples/small_demos/sys.stp | 17 ++++++ examples/small_demos/top.stp | 28 ++++++++++ examples/top.stp | 28 ---------- 16 files changed, 275 insertions(+), 85 deletions(-) delete mode 100644 examples/click.wav delete mode 100755 examples/key.stp delete mode 100755 examples/prof.stp delete mode 100644 examples/return.wav create mode 100644 examples/small_demos/click.wav create mode 100755 examples/small_demos/close.stp create mode 100644 examples/small_demos/demo_script.txt create mode 100755 examples/small_demos/key.stp create mode 100755 examples/small_demos/keyhack.stp create mode 100755 examples/small_demos/kmalloc.stp create mode 100755 examples/small_demos/kmalloc2.stp create mode 100755 examples/small_demos/prof.stp create mode 100644 examples/small_demos/return.wav create mode 100755 examples/small_demos/sys.stp create mode 100755 examples/small_demos/top.stp delete mode 100755 examples/top.stp (limited to 'examples') diff --git a/examples/click.wav b/examples/click.wav deleted file mode 100644 index 8214b229..00000000 Binary files a/examples/click.wav and /dev/null differ diff --git a/examples/key.stp b/examples/key.stp deleted file mode 100755 index 6334cbbf..00000000 --- a/examples/key.stp +++ /dev/null @@ -1,22 +0,0 @@ -#! /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_keycode") { - if ($down) { - if ($keycode == 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/prof.stp b/examples/prof.stp deleted file mode 100755 index 986be65e..00000000 --- a/examples/prof.stp +++ /dev/null @@ -1,35 +0,0 @@ -#!/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/return.wav b/examples/return.wav deleted file mode 100644 index 20f978cc..00000000 Binary files a/examples/return.wav and /dev/null differ diff --git a/examples/small_demos/click.wav b/examples/small_demos/click.wav new file mode 100644 index 00000000..8214b229 Binary files /dev/null and b/examples/small_demos/click.wav 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 Binary files /dev/null and b/examples/small_demos/return.wav 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 () +} + diff --git a/examples/top.stp b/examples/top.stp deleted file mode 100755 index 26d35ec8..00000000 --- a/examples/top.stp +++ /dev/null @@ -1,28 +0,0 @@ -#!/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 () -} - -- cgit