diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2008-04-24 13:55:34 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2008-04-24 13:55:34 -0400 |
commit | fe44e686c32ccb684bd5ec6df57aed00532fc024 (patch) | |
tree | 260953c84c8679572d65bf83a65884050f91d2f7 /testsuite/systemtap.examples | |
parent | f72154b33e67069cd7c308d24255574b9fbacb1d (diff) | |
parent | 478e10649195945adf7153fe5254932df1e2a902 (diff) | |
download | systemtap-steved-fe44e686c32ccb684bd5ec6df57aed00532fc024.tar.gz systemtap-steved-fe44e686c32ccb684bd5ec6df57aed00532fc024.tar.xz systemtap-steved-fe44e686c32ccb684bd5ec6df57aed00532fc024.zip |
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
* 'master' of ssh://sources.redhat.com/git/systemtap:
Made kernel 2.6.25 changes in task_finder.c.
Move examples to testsuite/systemtap.examples
Diffstat (limited to 'testsuite/systemtap.examples')
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 Binary files differnew file mode 100644 index 00000000..8214b229 --- /dev/null +++ b/testsuite/systemtap.examples/small_demos/click.wav 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 Binary files differnew file mode 100644 index 00000000..20f978cc --- /dev/null +++ b/testsuite/systemtap.examples/small_demos/return.wav 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] +} |