Repository: brendangregg/DTrace-book-scripts Branch: master Commit: e304ae66b8bc Files: 245 Total size: 306.6 KB Directory structure: gitextract_q2h7k1q3/ ├── Chap1/ │ ├── chpt1_exec.d │ └── read-syscall.d ├── Chap10/ │ ├── cpudispqlen.d │ ├── libmysql_snoop.d │ ├── mysqld_pid_qtime.d │ ├── mysqld_qchit.d │ ├── mysqld_qslower.d │ ├── mysqld_qsnoop.d │ ├── pg_pid_qtime.d │ ├── pg_qslower.d │ ├── qtime.d │ ├── ssdlatency.d │ └── sysdispqlen.d ├── Chap11/ │ ├── cuckoo.d │ ├── keylatency.d │ ├── networkwho.d │ ├── nosetuid.d │ ├── nosnoopforyou.d │ ├── reporter.sh │ ├── sshkeysnoop.d │ └── watchexec.d ├── Chap12/ │ ├── cswstat.d │ ├── kmem_osx.d │ ├── kmem_track.d │ ├── koffcpu.d │ ├── koncpu.d │ ├── ktrace.d │ ├── kwtrace.d │ ├── priclass.d │ ├── putnexts.d │ ├── segkmem.d │ ├── taskq.d │ └── writek.d ├── Chap2/ │ └── chap2_pexec.d ├── Chap3/ │ ├── brk.d │ ├── disk_io.d │ ├── fstop10.d │ ├── fstop10_enhanced.d │ ├── iotimeq.d │ ├── kprof.d │ ├── kprof_func.d │ ├── lat.d │ ├── mmap.d │ ├── net.d │ ├── nfs.d │ ├── pf.d │ ├── plat.d │ ├── rq.d │ ├── rw_bytes.d │ ├── rwa.d │ ├── scrwtop10.d │ ├── sctop10.d │ ├── sock.d │ ├── sock_j.d │ ├── vmtop10.d │ └── wrun.d ├── Chap4/ │ ├── bitesize.d │ ├── disklatency.d │ ├── geomiosnoop.d │ ├── ideerr.d │ ├── idelatency.d │ ├── iderw.d │ ├── iolatency.d │ ├── iotypes.d │ ├── mptevents.d │ ├── mptlatency.d │ ├── mptsasscsi.d │ ├── rwtime.d │ ├── satacmds.d │ ├── satalatency.d │ ├── satareasons.d │ ├── satarw.d │ ├── scsicmds.d │ ├── scsilatency.d │ ├── scsireasons.d │ ├── scsirw.d │ ├── sdqueue.d │ ├── sdretry.d │ └── seeksize.d ├── Chap5/ │ ├── cdrom.d │ ├── dnlcps.d │ ├── dvd.d │ ├── fserrors.d │ ├── fsflush.d │ ├── fsflush_cpu.d │ ├── fsrtpk.d │ ├── fsrwcount.d │ ├── fsrwtime.d │ ├── fssnoop.d │ ├── fswho.d │ ├── hfsfileread.d │ ├── hfsslower.d │ ├── hfssnoop.d │ ├── maclife.d │ ├── macvfssnoop.d │ ├── mmap.d │ ├── nfs3fileread.d │ ├── nfs3sizes.d │ ├── nfswizard.d │ ├── pcfsrw.d │ ├── perturbation.d │ ├── readtype.d │ ├── sollife.d │ ├── solvfssnoop.d │ ├── spasync.d │ ├── sysfs.d │ ├── tmpgetpage.d │ ├── tmpusers.d │ ├── ufsimiss.d │ ├── ufsreadahead.d │ ├── ufssnoop.d │ ├── vfslife.d │ ├── vfssnoop.d │ ├── writetype.d │ ├── zfsslower.d │ ├── zfssnoop.d │ ├── zioprint.d │ ├── ziosnoop.d │ └── ziotype.d ├── Chap6/ │ ├── icmpsnoop.d │ ├── icmpstat.d │ ├── ipfbtsnoop.d │ ├── ipio.d │ ├── ipproto.d │ ├── ipstat.d │ ├── macops.d │ ├── ngelink.d │ ├── ngesnoop.d │ ├── so1stbyte.d │ ├── soaccept.d │ ├── socketio.d │ ├── socketiosort.d │ ├── soclose.d │ ├── soconnect.d │ ├── soconnect_mac.d │ ├── soerrors.d │ ├── sotop.d │ ├── superping.d │ ├── tcp1stbyte.d │ ├── tcp_rwndclosed.d │ ├── tcpaccept.d │ ├── tcpacceptx.d │ ├── tcpbytes.d │ ├── tcpconnect.d │ ├── tcpconnlat.d │ ├── tcpfbtwatch.d │ ├── tcpio.d │ ├── tcpioshort.d │ ├── tcpnmap.d │ ├── tcpsize.d │ ├── tcpsnoop.d │ ├── tcpsnoop_snv.d │ ├── tcpstat.d │ ├── tcpstate.d │ ├── tcpwatch.d │ ├── udpio.d │ ├── udpstat.d │ └── xdrshow.d ├── Chap7/ │ ├── cifserrors.d │ ├── cifsfbtnofile.d │ ├── cifsfileio.d │ ├── cifsops.d │ ├── cifsrwsnoop.d │ ├── cifsrwtime.d │ ├── dnsgetname.d │ ├── fcerror.d │ ├── fcwho.d │ ├── ftpdfileio.d │ ├── ftpdxfer.d │ ├── getaddrinfo.d │ ├── httpclients.d │ ├── httpdurls.d │ ├── httperrors.d │ ├── httpio.d │ ├── iscsicmds.d │ ├── iscsirwsnoop.d │ ├── iscsirwsnoopsdt.d │ ├── iscsirwtime.d │ ├── iscsiterr.d │ ├── iscsiwho.d │ ├── ldapsyslog.d │ ├── nfsv3commit.d │ ├── nfsv3disk.d │ ├── nfsv3errors.d │ ├── nfsv3fbtrws.d │ ├── nfsv3fileio.d │ ├── nfsv3ops.d │ ├── nfsv3rwsnoop.d │ ├── nfsv3rwtime.d │ ├── nfsv3syncwrite.d │ ├── nfsv4commit.d │ ├── nfsv4deleg.d │ ├── nfsv4errors.d │ ├── nfsv4fileio.d │ ├── nfsv4ops.d │ ├── nfsv4rwsnoop.d │ ├── nfsv4rwtime.d │ ├── nfsv4syncwrite.d │ ├── nismatch.d │ ├── proftpdcmd.d │ ├── proftpdio.d │ ├── proftpdtime.d │ ├── scpwatcher.d │ ├── scsicmds.d │ ├── sshcipher.d │ ├── sshcipher2.d │ ├── sshcipher3.d │ ├── sshconnect.d │ ├── sshdactivity.d │ ├── tnftpdcmd.d │ └── weblatency.d ├── Chap8/ │ ├── j_calls.d │ ├── j_calltime.d │ ├── j_flow.d │ ├── j_thread.d │ ├── js_calls.d │ ├── js_calltime.d │ ├── js_flowinfo.d │ ├── php_calls.d │ ├── php_flowinfo.d │ ├── pl_calls.d │ ├── pl_calltime.d │ ├── pl_flowinfo.d │ ├── pl_who.d │ ├── py_calls.d │ ├── py_calltime.d │ ├── py_flowinfo.d │ ├── py_who.d │ ├── rb_calls.d │ ├── rb_calltime.d │ ├── rb_flowinfo.d │ ├── rb_who.d │ ├── sh_calls.d │ ├── sh_flowinfo.d │ ├── sh_who.d │ ├── tcl_calls.d │ ├── tcl_procflow.d │ └── tcl_who.d ├── Chap9/ │ ├── kill.d │ ├── procsnoop.d │ ├── sigdist.d │ ├── threaded.d │ ├── uoffcpu.d │ └── uoncpu.d └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: Chap1/chpt1_exec.d ================================================ dtrace -n 'proc:::exec-success { trace(curpsinfo->pr_psargs); }' ================================================ FILE: Chap1/read-syscall.d ================================================ dtrace -n 'syscall::read:entry /execname != "dtrace"/ { @reads[execname, fds[arg0].fi_pathname] = count(); }' ================================================ FILE: Chap10/cpudispqlen.d ================================================ #!/usr/sbin/dtrace -s /* * cpudispqlen.d * * Example script from Chapter 10 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Sampling at 1001 Hertz... Hit Ctrl-C to end.\n"); } profile:::profile-1001hz { @["Per-CPU disp queue length:"] = lquantize(curthread->t_cpu->cpu_disp->disp_nrunnable, 0, 64, 1); } ================================================ FILE: Chap10/libmysql_snoop.d ================================================ #!/usr/sbin/dtrace -Zs /* * libmysql_snoop.d * * Example script from Chapter 10 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-8s %6s %3s %s\n", "TIME(ms)", "Q(ms)", "RET", "QUERY"); timezero = timestamp; } pid$target::mysql_query:entry, pid$target::mysql_real_query:entry { self->query = copyinstr(arg1); self->start = timestamp; } pid$target::mysql_query:return, pid$target::mysql_real_query:return /self->start/ { this->time = (timestamp - self->start) / 1000000; this->now = (timestamp - timezero) / 1000000; printf("%-8d %6d %3d %s\n", this->now, this->time, arg1, self->query); self->start = 0; self->query = 0; } ================================================ FILE: Chap10/mysqld_pid_qtime.d ================================================ #!/usr/sbin/dtrace -s /* * mysqld_pid_qtime.d * * Example script from Chapter 10 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } pid$target::*dispatch_command*:entry { self->query = copyinstr(arg2); self->start = timestamp; } pid$target::*dispatch_command*:return /self->start/ { @time[self->query] = quantize(timestamp - self->start); self->query = 0; self->start = 0; } dtrace:::END { printf("MySQL query execution latency (ns):\n"); printa(@time); } ================================================ FILE: Chap10/mysqld_qchit.d ================================================ #!/usr/sbin/dtrace -s /* * mysqld_qchit.d * * Example script from Chapter 10 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); hits = 0; misses = 0; } mysql*:::query-cache-hit, mysql*:::query-cache-miss { this->query = copyinstr(arg0); } mysql*:::query-cache-hit, mysql*:::query-cache-miss /strlen(this->query) > 60/ { this->query[57] = '.'; this->query[58] = '.'; this->query[59] = '.'; this->query[60] = 0; } mysql*:::query-cache-hit { @cache[this->query, "hit"] = count(); hits++; } mysql*:::query-cache-miss { @cache[this->query, "miss"] = count(); misses++; } dtrace:::END { printf(" %-60s %6s %6s\n", "QUERY", "RESULT", "COUNT"); printa(" %-60s %6s %@6d\n", @cache); total = hits + misses; printf("\nHits : %d\n", hits); printf("Misses : %d\n", misses); printf("Hit Rate : %d%%\n", total ? (hits * 100) / total : 0); } ================================================ FILE: Chap10/mysqld_qslower.d ================================================ #!/usr/sbin/dtrace -s /* * mysqld_qslower.d * * Example script from Chapter 10 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option defaultargs #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%5s %5s %5s %5s %s\n", "QRYms", "EXCms", "CPUms", "CACHE", "QUERY"); min_ns = $1 * 1000000; } mysql*:::query-start { self->query = copyinstr(arg0); self->start = timestamp; self->vstart = vtimestamp; } mysql*:::query-cache-hit, mysql*:::query-cache-miss { self->cache = probename == "query-cache-hit" ? "hit" : "miss"; } mysql*:::query-exec-start { self->estart = timestamp; } mysql*:::query-exec-done /self->estart/ { self->exec = timestamp - self->estart; self->estart = 0; } mysql*:::query-done /self->start && (timestamp - self->start) >= min_ns/ { this->time = (timestamp - self->start) / 1000000; this->vtime = (vtimestamp - self->vstart) / 1000000; this->etime = self->exec / 1000000; printf("%5d %5d %5d %5s %s\n", this->time, this->etime, this->vtime, self->cache, self->query); } mysql*:::query-done { self->start = 0; self->vstart = 0; self->exec = 0; self->cache = 0; self->query = 0; } ================================================ FILE: Chap10/mysqld_qsnoop.d ================================================ #!/usr/sbin/dtrace -s /* * mysqld_qsnoop.d * * Example script from Chapter 10 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-8s %-16s %-18s %5s %3s %s\n", "TIME(ms)", "DATABASE", "USER@HOST", "ms", "RET", "QUERY"); timezero = timestamp; } mysql*:::query-start { self->query = copyinstr(arg0); self->db = copyinstr(arg2); self->who = strjoin(copyinstr(arg3), strjoin("@", copyinstr(arg4))); self->start = timestamp; } mysql*:::query-done /self->start/ { this->now = (timestamp - timezero) / 1000000; this->time = (timestamp - self->start) / 1000000; printf("%-8d %-16.16s %-18.18s %5d %3d %s\n", this->now, self->db, self->who, this->time, (int)arg0, self->query); self->start = 0; self->query = 0; self->db = 0; self->who = 0; } ================================================ FILE: Chap10/pg_pid_qtime.d ================================================ #!/usr/sbin/dtrace -s /* * pg_pid_qtime.d * * Example script from Chapter 10 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } pid$target::exec_simple_query:entry { self->query = copyinstr(arg0); self->start = timestamp; } pid$target::exec_simple_query:return /self->start/ { @time[self->query] = quantize(timestamp - self->start); self->start = 0; self->query = 0; } dtrace:::END { printf("PostgreSQL simple query execution latency (ns):\n"); printa(@time); } ================================================ FILE: Chap10/pg_qslower.d ================================================ #!/usr/sbin/dtrace -s /* * pg_qslower.d * * Example script from Chapter 10 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option defaultargs #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-8s %5s %5s %5s %s\n", "TIMEms", "QRYms", "EXCms", "CPUms", "QUERY"); min_ns = $1 * 1000000; timezero = timestamp; } postgresql*:::query-start { self->start = timestamp; self->vstart = vtimestamp; } postgresql*:::query-execute-start { self->estart = timestamp; } postgresql*:::query-execute-done /self->estart/ { self->exec = timestamp - self->estart; self->estart = 0; } postgresql*:::query-done /self->start && (timestamp - self->start) >= min_ns/ { this->now = (timestamp - timezero) / 1000000; this->time = (timestamp - self->start) / 1000000; this->vtime = (vtimestamp - self->vstart) / 1000000; this->etime = self->exec / 1000000; printf("%-8d %5d %5d %5d %s\n", this->now, this->time, this->etime, this->vtime, copyinstr(arg0)); } postgresql*:::query-done { self->start = 0; self->vstart = 0; self->exec = 0; } ================================================ FILE: Chap10/qtime.d ================================================ #!/usr/sbin/dtrace -s /* * qtime.d * * Example script from Chapter 10 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ sched:::enqueue { a[args[0]->pr_lwpid, args[1]->pr_pid, args[2]->cpu_id] = timestamp; } sched:::dequeue /a[args[0]->pr_lwpid, args[1]->pr_pid, args[2]->cpu_id]/ { @[args[2]->cpu_id] = quantize(timestamp - a[args[0]->pr_lwpid, args[1]->pr_pid, args[2]->cpu_id]); a[args[0]->pr_lwpid, args[1]->pr_pid, args[2]->cpu_id] = 0; } ================================================ FILE: Chap10/ssdlatency.d ================================================ #!/usr/sbin/dtrace -s /* * ssdlatency.d * * Example script from Chapter 10 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ fbt:ssd:ssdstrategy:entry { start[arg0] = timestamp; } fbt:ssd:ssd_buf_iodone:entry /start[arg2]/ { @time["ssd I/O latency (ns)"] = quantize(timestamp - start[arg2]); start[arg2] = 0; } ================================================ FILE: Chap10/sysdispqlen.d ================================================ #!/usr/sbin/dtrace -s /* * sysdispqlen.d * * Example script from Chapter 10 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Sampling at 1001 Hertz... Hit Ctrl-C to end.\n"); } profile:::profile-1001hz { @["System wide disp queue length:"] = sum(curthread->t_cpu->cpu_disp->disp_nrunnable); } profile:::tick-1sec { normalize(@, 1001); printa(@); trunc(@); } ================================================ FILE: Chap11/cuckoo.d ================================================ #!/usr/sbin/dtrace -s /* * cuckoo.d * * Example script from Chapter 11 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-20s %6s %6s %6s %s\n", "TIME", "PID", "PPID", "UID", "TEXT"); } fbt::cnwrite:entry { this->iov = args[1]->uio_iov; this->len = this->iov->iov_len; this->text = stringof((char *)copyin((uintptr_t)this->iov->iov_base, this->len)); this->text[this->len] = '\0'; printf("%-20Y %6d %6d %6d %s\n", walltimestamp, pid, ppid, uid, this->text); } ================================================ FILE: Chap11/keylatency.d ================================================ #!/usr/sbin/dtrace -s /* * keylatency.d * * Example script from Chapter 11 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet /* process name to monitor */ inline string TARGET = "bash"; self string lastkey; dtrace:::BEGIN { printf("Tracing %s keystrokes... Hit Ctrl-C to end.\n", TARGET); } syscall::read:entry /execname == TARGET && arg0 == 0/ { self->buf = arg1; self->start = timestamp; } syscall::read:return /self->buf && arg0 == 1/ { this->latency = timestamp - self->start; this->key = stringof((char *)copyin(self->buf, arg0)); this->key = this->key == "\r" ? "NL" : this->key; /* return */ this->key = this->key == "\t" ? "TAB" : this->key; /* tab */ this->key = this->key == "\177" ? "BS" : this->key; /* backspace */ @a[self->lastkey != NULL ? self->lastkey : " ", this->key] = avg(this->latency); @c[self->lastkey != NULL ? self->lastkey : " ", this->key] = count(); self->lastkey = this->key; self->start = 0; } syscall::read:return /self->buf/ { self->buf = 0; self->start = 0; } dtrace:::END { normalize(@a, 1000000); printf("Average Keystroke Latency for %s processes (ms):\n\n", TARGET); printf("%34s %8s\n", "LATENCY", "COUNT"); printa("%16s -> %3s %10@d %@8d\n", @a, @c); } ================================================ FILE: Chap11/networkwho.d ================================================ #!/usr/sbin/dtrace -s /* * networkwho.d * * Example script from Chapter 11 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option defaultargs #pragma D option switchrate=10hz dtrace:::BEGIN /$1 == 0/ { printf("USAGE: networkwho.d PID\n"); exit(1); } syscall::connect:entry, syscall::listen:entry /pid == $1/ { ustack(); } syscall::write*:entry, syscall::send*:entry /pid == $1/ { trace(fds[arg0].fi_fs); ustack(); } ================================================ FILE: Chap11/nosetuid.d ================================================ #!/usr/sbin/dtrace -s /* * nosetuid.d * * Example script from Chapter 11 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option destructive inline int ALLOWED_UID = 517; dtrace:::BEGIN { printf("Watching setuid(), allowing only uid %d...\n", ALLOWED_UID); } /* * Kill setuid() processes who are becomming root, from non-root, and who * are not the allowed UID. */ syscall::setuid:entry /arg0 == 0 && curpsinfo->pr_uid != 0 && curpsinfo->pr_uid != ALLOWED_UID/ { printf("%Y KILLED %s %d -> %d\n", walltimestamp, execname, curpsinfo->pr_uid, arg0); raise(9); } ================================================ FILE: Chap11/nosnoopforyou.d ================================================ #!/usr/sbin/dtrace -Cs /* * nosnoopforyou.d * * Example script from Chapter 11 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option destructive /* /usr/include/sys/dlpi.h: */ #define DL_PROMISCON_REQ 0x1f dtrace:::BEGIN { trace("Preventing promiscuity...\n"); } fbt::dld_wput_nondata:entry { this->mp = args[1]; this->prim = ((union DL_primitives *)this->mp->b_rptr)->dl_primitive; } fbt::dld_wput_nondata:entry /this->prim == DL_PROMISCON_REQ/ { printf("%Y KILLED %s PID:%d PPID:%d\n", walltimestamp, execname, pid, ppid); /* raise(9); */ } ================================================ FILE: Chap11/reporter.sh ================================================ #!/bin/sh echo "$*" >> /var/log/execlog.txt ================================================ FILE: Chap11/sshkeysnoop.d ================================================ #!/usr/sbin/dtrace -s /* * sshkeysnoop.d - A program to print keystroke details from ssh. * Written in DTrace (Solaris 10 build 63). * * Example script from Chapter 11 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. * * WARNING: This is a demonstration program, please do not use this for * illegal purposes in your country such as breeching privacy. */ #pragma D option quiet /* * Print header */ dtrace:::BEGIN { /* print header */ printf("%5s %5s %5s %5s %s\n", "UID", "PID", "PPID", "TYPE", "TEXT"); } /* * Print ssh execution */ syscall::exec*:return /execname == "ssh"/ { /* print output line */ printf("%5d %5d %5d %5s %s\n\n", curpsinfo->pr_euid, pid, curpsinfo->pr_ppid, "cmd", stringof(curpsinfo->pr_psargs)); } /* * Determine which fd is /dev/tty */ syscall::open*:entry /execname == "ssh"/ { self->path = arg0; } syscall::open*:return /self->path && copyinstr(self->path) == "/dev/tty"/ { /* track this syscall */ self->ok = 1; } syscall::open*:return { self->path = 0; } syscall::open*:return /self->ok/ { /* save fd number */ self->fd = arg0; } /* * Print ssh keystrokes */ syscall::read*:entry /execname == "ssh" && arg0 == self->fd/ { /* remember buffer address */ self->buf = arg1; } syscall::read*:return /self->buf != NULL && arg0 < 2/ { this->text = (char *)copyin(self->buf, arg0); /* print output line */ printf("%5d %5d %5d %5s %s\n", curpsinfo->pr_euid, pid, curpsinfo->pr_ppid, "key", stringof(this->text)); self->buf = NULL; } ================================================ FILE: Chap11/watchexec.d ================================================ #!/usr/sbin/dtrace -s /* * watchexec.d * * Example script from Chapter 11 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option destructive #pragma D option quiet inline string REPORT_CMD = "/usr/local/bin/reporter.sh"; dtrace:::BEGIN { /* * Ensure this contains all the reporting commands, * otherwise this script will be a feedback loop: */ ALLOWED[REPORT_CMD] = 1; ALLOWED["/bin/sh"] = 1; /* * Commands to allow. * Example list (from Solaris) in alphabetical order: */ ALLOWED["/bin/bash"] = 1; ALLOWED["/lib/svc/bin/svcio"] = 1; ALLOWED["/sbin/sh"] = 1; ALLOWED["/usr/apache2/current/bin/httpd"] = 1; ALLOWED["/usr/bin/basename"] = 1; ALLOWED["/usr/bin/cat"] = 1; ALLOWED["/usr/bin/chmod"] = 1; ALLOWED["/usr/bin/chown"] = 1; ALLOWED["/usr/bin/grep"] = 1; ALLOWED["/usr/bin/head"] = 1; ALLOWED["/usr/bin/ls"] = 1; ALLOWED["/usr/bin/pgrep"] = 1; ALLOWED["/usr/bin/pkill"] = 1; ALLOWED["/usr/bin/ssh"] = 1; ALLOWED["/usr/bin/svcprop"] = 1; ALLOWED["/usr/bin/tput"] = 1; ALLOWED["/usr/bin/tr"] = 1; ALLOWED["/usr/bin/uname"] = 1; ALLOWED["/usr/lib/nfs/mountd"] = 1; ALLOWED["/usr/lib/nfs/nfsd"] = 1; ALLOWED["/usr/sfw/bin/openssl"] = 1; ALLOWED["/usr/xpg4/bin/sh"] = 1; printf("Reporting unknown exec()s to %s...\n", REPORT_CMD); } syscall::exec*:entry /ALLOWED[copyinstr(arg0)] != 1/ { /* * Customize arguments for reporting command: */ system("%s %s %d %d %d %Y\n", REPORT_CMD, copyinstr(arg0), uid, pid, ppid, walltimestamp); } ================================================ FILE: Chap12/cswstat.d ================================================ #!/usr/sbin/dtrace -s /* * cswstat.d * * Example script from Chapter 12 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { /* print header */ printf("%-20s %8s %12s %12s\n", "TIME", "NUM", "CSWTIME(us)", "AVGTIME(us)"); times = 0; num = 0; } sched:::off-cpu { /* csw start */ num++; start[cpu] = timestamp; } sched:::on-cpu /start[cpu]/ { /* csw end */ times += timestamp - start[cpu]; start[cpu] = 0; } profile:::tick-1sec { /* print output */ printf("%20Y %8d %12d %12d\n", walltimestamp, num, times/1000, num == 0 ? 0 : times/(1000 * num)); times = 0; num = 0; } ================================================ FILE: Chap12/kmem_osx.d ================================================ #!/usr/sbin/dtrace -s /* * kmem_osx.d * * Example script from Chapter 12 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet fbt::kmem_alloc:entry { @alloc[arg2] = count(); } fbt::kmem_free:entry { @free[arg2] = count(); } END { printf("%-16s %-8s %-8s\n", "SIZE", "ALLOCS", "FREES"); printa("%-16d %-@8d %-@8d\n", @alloc, @free); } ================================================ FILE: Chap12/kmem_track.d ================================================ #!/usr/sbin/dtrace -s /* * kmem_track.d * * Example script from Chapter 12 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet fbt::kmem_cache_alloc:entry { @alloc[args[0]->cache_name] = count(); } fbt::kmem_cache_free:entry { @free[args[0]->cache_name] = count(); } tick-1sec { printf("%-32s %-8s %-8s\n", "CACHE NAME", "ALLOCS", "FREES"); printa("%-32s %-@8d %-@8d\n", @alloc, @free); trunc(@alloc); trunc(@free); } ================================================ FILE: Chap12/koffcpu.d ================================================ #!/usr/sbin/dtrace -s /* * koffcpu.d * * Example script from Chapter 12 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ sched:::off-cpu { self->start = timestamp; } sched:::on-cpu /self->start/ { this->delta = (timestamp - self->start) / 1000; @["off-cpu (us):", stack()] = quantize(this->delta); self->start = 0; } ================================================ FILE: Chap12/koncpu.d ================================================ #!/usr/sbin/dtrace -s /* * koncpu.d * * Example script from Chapter 12 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ profile:::profile-1001 { @["\n on-cpu stack (count @1001hz):", stack()] = count(); } ================================================ FILE: Chap12/ktrace.d ================================================ #!/usr/sbin/dtrace -s /* * ktrace.d * * Example script from Chapter 12 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option flowindent syscall::$1:entry { self->flag = 1; } fbt::: /self->flag/ { } syscall::$1:return /self->flag/ { self->flag = 0; exit(0); } ================================================ FILE: Chap12/kwtrace.d ================================================ #!/usr/sbin/dtrace -s /* * kwtrace.d * * Example script from Chapter 12 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option flowindent syscall::write:entry /fds[arg0].fi_fs == $$1/ { self->flag = 1; } fbt::: /self->flag/ { } syscall::write:return /self->flag/ { self->flag = 0; exit(0); } ================================================ FILE: Chap12/priclass.d ================================================ #!/usr/sbin/dtrace -s /* * priclass.d * * Example script from Chapter 12 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Sampling... Hit Ctrl-C to end.\n"); } profile:::profile-1001hz { @count[stringof(curlwpsinfo->pr_clname)] = lquantize(curlwpsinfo->pr_pri, 0, 170, 10); } ================================================ FILE: Chap12/putnexts.d ================================================ #!/usr/sbin/dtrace -s /* * putnexts.d * * Example script from Chapter 12 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ fbt::putnext:entry { @[stringof(args[0]->q_qinfo->qi_minfo->mi_idname), stack(5)] = count(); } ================================================ FILE: Chap12/segkmem.d ================================================ #!/usr/sbin/dtrace -s /* * segkmem.d * * Example script from Chapter 12 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet fbt::segkmem_xalloc:entry { @segkmem_alloc[args[0]->vm_name, arg2] = count(); } fbt::segkmem_free_vn:entry { @segkmem_free[args[0]->vm_name, arg2] = count(); } END { printf("%-16s %-8s %-8s %-8s\n", "VMEM NAME", "SIZE", "ALLOCS", "FREES"); printa("%-16s %-8d %-@8d %-@8d\n", @segkmem_alloc, @segkmem_free); } ================================================ FILE: Chap12/taskq.d ================================================ #!/usr/sbin/dtrace -s /* * taskq.d * * Example script from Chapter 12 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing... Interval 10 seconds, or Ctrl-C.\n"); } sdt:::taskq-enqueue { this->tq = (taskq_t *)arg0; this->tqe = (taskq_ent_t *)arg1; @c[this->tq->tq_name, this->tqe->tqent_func] = count(); time[arg1] = timestamp; } sdt:::taskq-exec-start /time[arg1]/ { this->wait = timestamp - time[arg1]; this->tq = (taskq_t *)arg0; this->tqe = (taskq_ent_t *)arg1; @w[this->tq->tq_name, this->tqe->tqent_func] = sum(this->wait); time[arg1] = timestamp; } sdt:::taskq-exec-end /time[arg1]/ { this->exec = timestamp - time[arg1]; this->tq = (taskq_t *)arg0; this->tqe = (taskq_ent_t *)arg1; @e[this->tq->tq_name, this->tqe->tqent_func] = sum(this->exec); time[arg1] = 0; } profile:::tick-10s, dtrace:::END { normalize(@w, 1000000); normalize(@e, 1000000); printf("\n %-22s %-25s %8s %9s %9s\n", "TASKQ NAME", "FUNCTION", "COUNT", "T_WAITms", "T_EXECms"); printa(" %-22.22s %-25.25a %8@d %@9d %@9d\n", @c, @w, @e); trunc(@c); trunc(@w); trunc(@e); } ================================================ FILE: Chap12/writek.d ================================================ #!/usr/sbin/dtrace -s /* * writek.d * * Example script from Chapter 12 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet syscall::write:entry /fds[arg0].fi_fs == "nfs4"/ { self->st = timestamp; } fbt::$1:entry /self->st/ { self->kst[probefunc] = timestamp; } fbt::$1:return /self->kst[probefunc]/ { @ktime[probefunc] = sum(timestamp - self->kst[probefunc]); self->kst[probefunc] = 0; } syscall::write:return /self->st/ { @write_syscall_time = sum(timestamp - self->st); self->st = 0; exit(0); } END { printa("Write syscall: %@d (nanoseconds)\n", @write_syscall_time); printa("Kernel function %s() time: %@d (nanoseconds)\n", @ktime); } ================================================ FILE: Chap2/chap2_pexec.d ================================================ #!/usr/sbin/dtrace -s /* * chap2_pexec.d * * Example script from Chapter 2 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-20s %6s %6s %6s %s\n", "ENDTIME", "UID", "PPID", "PID", "PROCESS"); } proc:::exec-success { printf("%-20Y %6d %6d %6d %s\n", walltimestamp, uid, ppid, pid, execname); } ================================================ FILE: Chap3/brk.d ================================================ #!/usr/sbin/dtrace -qs /* * brk.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ self int endds; syscall::brk:entry /pid == $target && !self->endds/ { self->endds = arg0; } syscall::brk:entry /pid == $target && self->endds != arg0/ { printf("Allocated %d\n", arg0 - self->endds); self->endds = arg0; } ================================================ FILE: Chap3/disk_io.d ================================================ #!/usr/sbin/dtrace -Cs /* * disk_io.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #define PRINT_HDR printf("%-8s %-16s %-8s %-16s\n", "RPS", "RD BYTES", "WPS", "WR BYTES"); dtrace:::BEGIN { PRINT_HDR } io:::start /execname == $$1 && args[0]->b_flags & B_READ/ { @rps = count(); @rbytes = sum(args[0]->b_bcount); } io:::start /execname == $$1 && args[0]->b_flags & B_WRITE/ { @wps = count(); @wbytes = sum(args[0]->b_bcount); } tick-1sec { printa("%-@8d %-@16d %-@8d %-@16d\n", @rps, @rbytes, @wps, @wbytes); trunc(@rps); trunc(@rbytes); trunc(@wps); trunc(@wbytes); } tick-1sec /x++ == 20/ { PRINT_HDR x = 0; } ================================================ FILE: Chap3/fstop10.d ================================================ #!/usr/sbin/dtrace -qs /* * fstop10.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ fsinfo::: { @[execname, probefunc] = count(); } END { trunc(@, 10); printf("%-16s %-16s %-8s\n", "EXEC", "FS FUNC", "COUNT"); printa("%-16s %-16s %-@8d\n", @); } ================================================ FILE: Chap3/fstop10_enhanced.d ================================================ #!/usr/sbin/dtrace -qs /* * fstop10_enhanced.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ fsinfo::: { @[execname, probename, args[0]->fi_fs, args[0]->fi_pathname] = count(); } END { trunc(@, 10); printf("%-16s %-8s %-8s %-32s %-8s\n", "EXEC", "FS FUNC", "FS TYPE", "PATH", "COUNT"); printa("%-16s %-8s %-8s %-32s %-@8d\n", @); } ================================================ FILE: Chap3/iotimeq.d ================================================ #!/usr/sbin/dtrace -s /* * iotimeq.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing...Output afer 10 seconds, or Ctrl-C\n"); } io:::start { start[args[0]->b_edev, args[0]->b_blkno] = timestamp; } io:::done /start[args[0]->b_edev, args[0]->b_blkno]/ { this->elapsed = (timestamp - start[args[0]->b_edev, args[0]->b_blkno]) / 1000000; @iot[args[1]->dev_statname, args[0]->b_flags & B_READ ? "READS(ms)" : "WRITES(ms)"] = quantize(this->elapsed); start[args[0]->b_edev, args[0]->b_blkno] = 0; } tick-10sec { printa(@iot); exit(0); } ================================================ FILE: Chap3/kprof.d ================================================ #!/usr/sbin/dtrace -s /* * kprof.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ profile-997hz /arg0 && curthread->t_pri != -1/ { @[stack()] = count(); } tick-10sec { trunc(@, 10); printa(@); exit(0); } ================================================ FILE: Chap3/kprof_func.d ================================================ #!/usr/sbin/dtrace -s /* * kprof_func.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet profile-997hz /arg0 && curthread->t_pri != -1/ { @[func(caller), func(arg0)] = count(); } tick-10sec { trunc(@, 20); printf("%-24s %-32s %-8s\n", "CALLER", "FUNCTION", "COUNT"); printa("%-24a %-32a %-@8d\n", @); exit(0); } ================================================ FILE: Chap3/lat.d ================================================ #!/usr/sbin/dtrace -s /* * lat.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet sched:::enqueue { s[args[0]->pr_lwpid, args[1]->pr_pid] = timestamp; } sched:::dequeue /this->start = s[args[0]->pr_lwpid, args[1]->pr_pid]/ { this->time = timestamp - this->start; @lat_avg[args[2]->cpu_id] = avg(this->time); @lat_max[args[2]->cpu_id] = max(this->time); @lat_min[args[2]->cpu_id] = min(this->time); s[args[0]->pr_lwpid, args[1]->pr_pid] = 0; } tick-1sec { printf("%-8s %-12s %-12s %-12s\n", "CPU", "AVG(ns)", "MAX(ns)", "MIN(ns)"); printa("%-8d %-@12d %-@12d %-@12d\n", @lat_avg, @lat_max, @lat_min); trunc(@lat_avg); trunc(@lat_max); trunc(@lat_min); } ================================================ FILE: Chap3/mmap.d ================================================ #!/usr/sbin/dtrace -s /* * mmap.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option flowindent syscall::mmap:entry { self->flag = 1; } fbt::: /self->flag/ { } syscall::mmap:return /self->flag/ { self->flag = 0; exit(0); } ================================================ FILE: Chap3/net.d ================================================ #!/usr/sbin/dtrace -s /* * net.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet syscall::*read:entry, syscall::*write:entry /fds[arg0].fi_fs == "sockfs"/ { @ior[probefunc] = count(); @net_bytes[probefunc] = sum(arg2); } tick-1sec { printf("%-8s %-16s %-16s\n", "FUNC", "OPS PER SEC", "BYTES PER SEC"); printa("%-8s %-@16d %-@16d\n", @ior, @net_bytes); trunc(@ior); trunc(@net_bytes); printf("\n"); } ================================================ FILE: Chap3/nfs.d ================================================ #!/usr/sbin/dtrace -s /* * nfs.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet fbt:nfs:nfs4_getapage:entry /execname == "m2loader"/ { self->st = timestamp; @calls = count(); } fbt:nfs:nfs4_getapage:return /self->st/ { @mint = min(timestamp - self->st); @maxt = max(timestamp - self->st); @avgt = avg(timestamp - self->st); @t["ns"] = quantize(timestamp - self->st); self->st = 0; } END { normalize(@mint, 1000); normalize(@maxt, 1000); normalize(@avgt, 1000); printf("%-8s %-8s %-8s %-8s\n", "CALLS", "MIN(us)", "MAX(us)", "AVG(us)"); printa("%-@8d %-@8d %-@8d %-@8d\n", @calls, @mint, @maxt, @avgt); printf("\n"); printa(@t); } ================================================ FILE: Chap3/pf.d ================================================ #!/usr/sbin/dtrace -s /* * pf.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing...Ouput after 10 seconds, or Ctrl-C\n"); } fbt:unix:pagefault:entry { @st[execname] = count(); self->pfst = timestamp } fbt:unix:pagefault:return /self->pfst/ { @pft[execname] = sum(timestamp - self->pfst); self->pfst = 0; } tick-10s { printf("Pagefault counts by execname ...\n"); printa(@st); printf("\nPagefault times(ns) by execname...\n"); printa(@pft); trunc(@st); trunc(@pft); } ================================================ FILE: Chap3/plat.d ================================================ #!/usr/sbin/dtrace -s /* * plat.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet sched:::enqueue /args[1]->pr_pid == $target/ { s[args[2]->cpu_id] = timestamp; } sched:::dequeue /s[args[2]->cpu_id]/ { @lat_sum[args[1]->pr_pid] = sum(timestamp - s[args[2]->cpu_id]); s[args[2]->cpu_id] = 0; } tick-1sec { normalize(@lat_sum, 1000); printa("PROCESS: %d spent %@d microseconds waiting for a CPU\n", @lat_sum); trunc(@lat_sum); } ================================================ FILE: Chap3/rq.d ================================================ #!/usr/sbin/dtrace -s /* * rq.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet sched:::enqueue { this->len = qlen[args[2]->cpu_id]++; @[args[2]->cpu_id] = lquantize(this->len, 0, 100); } sched:::dequeue /qlen[args[2]->cpu_id]/ { qlen[args[2]->cpu_id]--; } ================================================ FILE: Chap3/rw_bytes.d ================================================ #! /usr/sbin/dtrace -qs /* * rw_bytes.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ syscall::read:entry, syscall::write:entry /fds[arg0].fi_fs == "sockfs"/ { self->flag = 1 } syscall::read:return, syscall::write:return /(int)arg0 != -1 && self->flag/ { @[probefunc] = sum(arg0); } syscall::read:return, syscall::write:return { self->flag = 0; } ================================================ FILE: Chap3/rwa.d ================================================ #!/usr/sbin/dtrace -s /* * rwa.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing... Output after 10 seconds, or Ctrl-C\n"); } syscall::$1:entry /execname == $$2/ { self->fd = arg0; self->st = timestamp; } syscall::$1:return /self->st/ { @iot[pid, probefunc, fds[self->fd].fi_pathname] = sum(timestamp - self->st); self->fd = 0; self->st = 0; } tick-10sec { normalize(@iot, 1000); printf("%-8s %-8s %-32s %-16s\n", "PID", "SYSCALL", "PATHNAME", "TIME(us)"); printa("%-8d %-8s %-32s %-@16d\n", @iot); } ================================================ FILE: Chap3/scrwtop10.d ================================================ #!/usr/sbin/dtrace -s /* * scrwtop10.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet syscall::*read*:entry, syscall::*write*:entry { @[execname, probefunc, fds[arg0].fi_fs] = count(); } END { trunc(@, 10); printf("%-16s %-16s %-8s %-8s\n", "EXEC", "SYSCALL", "FS", "COUNT"); printa("%-16s %-16s %-8s %-@8d\n", @); } ================================================ FILE: Chap3/sctop10.d ================================================ #!/usr/sbin/dtrace -s /* * sctop10.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet syscall:::entry { @[execname, probefunc] = count(); } END { trunc(@, 10); printf("%-16s %-16s %-8s\n", "EXEC", "SYSCALL", "COUNT"); printa("%-16s %-16s %-@8d\n", @); } ================================================ FILE: Chap3/sock.d ================================================ #!/usr/sbin/dtrace -s /* * sock.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet fbt:sockfs::entry { @[execname, probefunc] = count(); } END { printf("%-16s %-24s %-8s\n", "EXEC", "SOCKFS FUNC", "COUNT"); printa("%-16s %-24s %-@8d\n", @); } ================================================ FILE: Chap3/sock_j.d ================================================ #!/usr/sbin/dtrace -s /* * sock_j.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet fbt:sockfs::entry /execname == "java"/ { @[probefunc] = count(); self->st[stackdepth] = timestamp; } fbt:sockfs::return /self->st[stackdepth]/ { @sockfs_times[pid, probefunc] = sum(timestamp - self->st[stackdepth]); self->st[stackdepth] = 0; } tick-1sec { normalize(@sockfs_times, 1000); printf("%-8s %-24s %-16s\n", "PID", "SOCKFS FUNC", "TIME(ms)"); printa("%-8d %-24s %-@16d\n", @sockfs_times); printf("\nSOCKFS CALLS PER SECOND:\n"); printa(@); trunc(@); trunc(@sockfs_times); printf("\n\n"); } ================================================ FILE: Chap3/vmtop10.d ================================================ #!/usr/sbin/dtrace -s /* * vmtop10.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet vminfo::: { @[execname, probefunc, probename] = count(); } tick-1sec { trunc(@, 10); printf("%-16s %-16s %-16s %-8s\n", "EXEC", "FUNCTION", "NAME", "COUNT"); printa("%-16s %-16s %-16s %-@8d\n", @); trunc(@); printf("\n"); } ================================================ FILE: Chap3/wrun.d ================================================ #!/usr/sbin/dtrace -s /* * wrun.d * * Example script from Chapter 3 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet inline int MAX = 10; dtrace:::BEGIN { start = timestamp; printf("Tracing for %d seconds...hit Ctrl-C to terminate sooner\n", MAX); } sched:::on-cpu /pid == $target/ { self->ts = timestamp; } sched:::off-cpu /self->ts/ { @[cpu] = sum(timestamp - self->ts); self->ts = 0; } profile:::tick-1sec /++x == MAX/ { exit(0); } dtrace:::END { printf("\nCPU distribution over %d milliseconds:\n\n", (timestamp - start) / 1000000); printf("CPU microseconds\n--- ------------\n"); normalize(@, 1000); printa("%3d %@d\n", @); } ================================================ FILE: Chap4/bitesize.d ================================================ #!/usr/sbin/dtrace -s /* * bitesize.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } io:::start { this->size = args[0]->b_bcount; @Size[pid, curpsinfo->pr_psargs] = quantize(this->size); } dtrace:::END { printf("\n%8s %s\n", "PID", "CMD"); printa("%8d %S\n%@d\n", @Size); } ================================================ FILE: Chap4/disklatency.d ================================================ #!/usr/sbin/dtrace -s /* * disklatency.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } io:::start { start_time[arg0] = timestamp; } io:::done /this->start = start_time[arg0]/ { this->delta = (timestamp - this->start) / 1000; @[args[1]->dev_statname, args[1]->dev_major, args[1]->dev_minor] = quantize(this->delta); start_time[arg0] = 0; } dtrace:::END { printa(" %s (%d,%d), us:\n%@d\n", @); } ================================================ FILE: Chap4/geomiosnoop.d ================================================ #!/usr/sbin/dtrace -s /* * geomiosnoop.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz /* from /usr/src/sys/sys/bio.h */ inline int BIO_READ = 0x01; inline int BIO_WRITE = 0x02; dtrace:::BEGIN { printf("%5s %5s %1s %10s %6s %16s %-8s %s\n", "UID", "PID", "D", "OFFSET(KB)", "BYTES", "COMM", "VNODE", "INFO"); } fbt::g_vfs_strategy:entry { /* attempt to fetch the filename from the namecache */ this->file = args[1]->b_vp->v_cache_dd != NULL ? stringof(args[1]->b_vp->v_cache_dd->nc_name) : ""; printf("%5d %5d %1s %10d %6d %16s %-8x %s \n", uid, pid, args[1]->b_iocmd & BIO_READ ? "R" : "W", args[1]->b_iooffset / 1024, args[1]->b_bcount, execname, (uint64_t)args[1]->b_vp, this->file); } fbt::g_dev_strategy:entry { printf("%5d %5d %1s %10d %6d %16s %-8s %s\n", uid, pid, args[0]->bio_cmd & BIO_READ ? "R" : "W", args[0]->bio_offset / 1024, args[0]->bio_bcount, execname, "", stringof(args[0]->bio_dev->si_name)); } ================================================ FILE: Chap4/ideerr.d ================================================ #!/usr/sbin/dtrace -s /* * ideerr.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet string dcmd[uchar_t]; dtrace:::BEGIN { /* * These command and error descriptions are from the DCMD_* and DERR_* * definitions in /usr/include/sys/dktp/dadkio.h: */ dcmd[1] = "Read Sectors/Blocks"; dcmd[2] = "Write Sectors/Blocks"; dcmd[3] = "Format Tracks"; dcmd[4] = "Format entire drive"; dcmd[5] = "Recalibrate"; dcmd[6] = "Seek to Cylinder"; dcmd[7] = "Read Verify sectors on disk"; dcmd[8] = "Read manufacturers defect list"; dcmd[9] = "Lock door"; dcmd[10] = "Unlock door"; dcmd[11] = "Start motor"; dcmd[12] = "Stop motor"; dcmd[13] = "Eject medium"; dcmd[14] = "Update geometry"; dcmd[15] = "Get removable disk status"; dcmd[16] = "cdrom pause"; dcmd[17] = "cdrom resume"; dcmd[18] = "cdrom play by track and index"; dcmd[19] = "cdrom play msf"; dcmd[20] = "cdrom sub channel"; dcmd[21] = "cdrom read mode 1"; dcmd[22] = "cdrom read table of contents header"; dcmd[23] = "cdrom read table of contents entry"; dcmd[24] = "cdrom read offset"; dcmd[25] = "cdrom mode 2"; dcmd[26] = "cdrom volume control"; dcmd[27] = "flush write cache to physical medium"; derr[0] = "success"; derr[1] = "address mark not found"; derr[2] = "track 0 not found"; derr[3] = "aborted command"; derr[4] = "write fault"; derr[5] = "ID not found"; derr[6] = "drive busy"; derr[7] = "uncorrectable data error"; derr[8] = "bad block detected"; derr[9] = "invalid cdb"; derr[10] = "hard device error- no retry"; derr[11] = "Illegal length indication"; derr[12] = "End of media detected"; derr[13] = "Media change requested"; derr[14] = "Recovered from error"; derr[15] = "Device not ready"; derr[16] = "Medium error"; derr[17] = "Hardware error"; derr[18] = "Illegal request"; derr[19] = "Unit attention"; derr[20] = "Data protection"; derr[21] = "Miscompare"; derr[22] = "Interface CRC error"; derr[23] = "Reserved"; /* from CPS_* definitions in /usr/include/sys/dktp/cmpkt.h */ reason[0] = "success"; reason[1] = "failure"; reason[2] = "fail+err"; reason[3] = "aborted"; printf("Tracing... Hit Ctrl-C to end.\n"); } fbt::dadk_pktcb:entry { this->pktp = args[0]; this->cmd = *(char *)this->pktp->cp_cdbp; this->cmd_text = dcmd[this->cmd] != NULL ? dcmd[this->cmd] : lltostr(this->cmd); this->reason = this->pktp->cp_reason; this->reason_text = reason[this->reason] != NULL ? reason[this->reason] : lltostr(this->reason); this->err = *(char *)this->pktp->cp_scbp; this->err_text = derr[this->err] != NULL ? derr[this->err] : lltostr(this->err); @[this->cmd_text, this->reason_text, this->err_text] = count(); } dtrace:::END { printf("%-36s %8s %27s %s\n", "IDE COMMAND", "REASON", "ERROR", "COUNT"); printa("%-36s %8s %27s %@d\n", @); } ================================================ FILE: Chap4/idelatency.d ================================================ #!/usr/sbin/dtrace -s /* * idelatency.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet string dcmd[uchar_t]; dtrace:::BEGIN { /* * These command descriptions are from the DCMD_* definitions * in /usr/include/sys/dktp/dadkio.h: */ dcmd[1] = "Read Sectors/Blocks"; dcmd[2] = "Write Sectors/Blocks"; dcmd[3] = "Format Tracks"; dcmd[4] = "Format entire drive"; dcmd[5] = "Recalibrate"; dcmd[6] = "Seek to Cylinder"; dcmd[7] = "Read Verify sectors on disk"; dcmd[8] = "Read manufacturers defect list"; dcmd[9] = "Lock door"; dcmd[10] = "Unlock door"; dcmd[11] = "Start motor"; dcmd[12] = "Stop motor"; dcmd[13] = "Eject medium"; dcmd[14] = "Update geometry"; dcmd[15] = "Get removable disk status"; dcmd[16] = "cdrom pause"; dcmd[17] = "cdrom resume"; dcmd[18] = "cdrom play by track and index"; dcmd[19] = "cdrom play msf"; dcmd[20] = "cdrom sub channel"; dcmd[21] = "cdrom read mode 1"; dcmd[22] = "cdrom read table of contents header"; dcmd[23] = "cdrom read table of contents entry"; dcmd[24] = "cdrom read offset"; dcmd[25] = "cdrom mode 2"; dcmd[26] = "cdrom volume control"; dcmd[27] = "flush write cache to physical medium"; /* from CPS_* definitions in /usr/include/sys/dktp/cmpkt.h */ reason[0] = "success"; reason[1] = "failure"; reason[2] = "fail+err"; reason[3] = "aborted"; printf("Tracing... Hit Ctrl-C to end.\n"); } /* IDE command start */ fbt::dadk_pktprep:return { start[arg1] = timestamp; } /* IDE command completion */ fbt::dadk_pktcb:entry /start[arg0]/ { this->pktp = args[0]; this->delta = (timestamp - start[arg0]) / 1000; this->cmd = *((uchar_t *)this->pktp->cp_cdbp); this->cmd_text = dcmd[this->cmd] != NULL ? dcmd[this->cmd] : lltostr(this->cmd); this->reason = this->pktp->cp_reason; this->reason_text = reason[this->reason] != NULL ? reason[this->reason] : lltostr(this->reason); @num[this->cmd_text, this->reason_text] = count(); @average[this->cmd_text, this->reason_text] = avg(this->delta); @total[this->cmd_text, this->reason_text] = sum(this->delta); start[arg0] = 0; } dtrace:::END { normalize(@total, 1000); printf("\n %-36s %8s %8s %10s %10s\n", "IDE COMMAND", "REASON", "COUNT", "AVG(us)", "TOTAL(ms)"); printa(" %-36s %8s %@8d %@10d %@10d\n", @num, @average, @total); } ================================================ FILE: Chap4/iderw.d ================================================ #!/usr/sbin/dtrace -s /* * iderw.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet string dcmd[uchar_t]; dtrace:::BEGIN { /* * These commands of interest are from the DCMD_* definitions in * /usr/include/sys/dktp/dadkio.h: */ dcmd[1] = "Read Sectors/Blocks"; dcmd[2] = "Write Sectors/Blocks"; dcmd[27] = "flush write cache"; /* from CPS_* definitions in /usr/include/sys/dktp/cmpkt.h */ reason[0] = "success"; reason[1] = "failure"; reason[2] = "fail+err"; reason[3] = "aborted"; printf("Tracing... Hit Ctrl-C to end.\n"); } fbt::dadk_pktprep:entry { self->size = args[2]->b_bcount; } /* IDE command start */ fbt::dadk_pktprep:return { start[arg1] = timestamp; size[arg1] = self->size; self->size = 0; } /* IDE command completion */ fbt::dadk_pktcb:entry /start[arg0]/ { this->pktp = args[0]; this->cmd = *((uchar_t *)this->pktp->cp_cdbp); } /* Only match desired commands: read/write/flush-cache */ fbt::dadk_pktcb:entry /start[arg0] && dcmd[this->cmd] != NULL/ { this->delta = (timestamp - start[arg0]) / 1000; this->cmd_text = dcmd[this->cmd] != NULL ? dcmd[this->cmd] : lltostr(this->cmd); this->size = size[arg0]; @num[this->cmd_text] = count(); @avg_size[this->cmd_text] = avg(this->size); @avg_time[this->cmd_text] = avg(this->delta); @sum_size[this->cmd_text] = sum(this->size); @sum_time[this->cmd_text] = sum(this->delta); @plot_size[this->cmd_text] = quantize(this->size); @plot_time[this->cmd_text] = quantize(this->delta); start[arg0] = 0; size[arg0] = 0; } dtrace:::END { normalize(@avg_size, 1024); normalize(@sum_size, 1048576); normalize(@sum_time, 1000); printf(" %-20s %8s %10s %10s %10s %11s\n", "DIR", "COUNT", "AVG(KB)", "TOTAL(MB)", "AVG(us)", "TOTAL(ms)"); printa(" %-20s %@8d %@10d %@10d %@10d %@11d\n", @num, @avg_size, @sum_size, @avg_time, @sum_time); printf("\n\nIDE I/O size (bytes):\n"); printa(@plot_size); printf("\nIDE I/O latency (us):\n"); printa(@plot_time); } ================================================ FILE: Chap4/iolatency.d ================================================ #!/usr/sbin/dtrace -s /* * iolatency.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ io:::start { start[arg0] = timestamp; } io:::done /start[arg0]/ { @time["disk I/O latency (ns)"] = quantize(timestamp - start[arg0]); start[arg0] = 0; } ================================================ FILE: Chap4/iotypes.d ================================================ #!/usr/sbin/dtrace -s /* * iotypes.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } io:::start { start_time[arg0] = timestamp; } io:::done /this->start = start_time[arg0]/ { this->delta = (timestamp - this->start) / 1000; this->type = args[0]->b_flags & B_READ ? "read" : "write"; this->type = args[0]->b_flags & B_PHYS ? strjoin("phys-", this->type) : this->type; this->type = args[0]->b_flags & B_ASYNC ? strjoin("async-", this->type) : this->type; this->pageio = args[0]->b_flags & B_PAGEIO ? "yes" : "no"; this->error = args[0]->b_error != 0 ? strjoin("Error:", lltostr(args[0]->b_error)) : "Success"; @num[this->type, this->pageio, this->error] = count(); @average[this->type, this->pageio, this->error] = avg(this->delta); @total[this->type, this->pageio, this->error] = sum(this->delta); start_time[arg0] = 0; } dtrace:::END { normalize(@total, 1000); printf("\n %-18s %6s %10s %11s %11s %12s\n", "TYPE", "PAGEIO", "RESULT", "COUNT", "AVG(us)", "TOTAL(ms)"); printa(" %-18s %6s %10s %@11d %@11d %@12d\n", @num, @average, @total); } ================================================ FILE: Chap4/mptevents.d ================================================ #!/usr/sbin/dtrace -s /* * mptevents.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { /* * These MPI_EVENT_* definitions are from uts/common/sys/mpt/mpi_ioc.h */ mpi_event[0x00000000] = "NONE"; mpi_event[0x00000001] = "LOG_DATA"; mpi_event[0x00000002] = "STATE_CHANGE"; mpi_event[0x00000003] = "UNIT_ATTENTION"; mpi_event[0x00000004] = "IOC_BUS_RESET"; mpi_event[0x00000005] = "EXT_BUS_RESET"; mpi_event[0x00000006] = "RESCAN"; mpi_event[0x00000007] = "LINK_STATUS_CHANGE"; mpi_event[0x00000008] = "LOOP_STATE_CHANGE"; mpi_event[0x00000009] = "LOGOUT"; mpi_event[0x0000000A] = "EVENT_CHANGE"; mpi_event[0x0000000B] = "INTEGRATED_RAID"; mpi_event[0x0000000C] = "SCSI_DEVICE_STATUS_CHANGE"; mpi_event[0x0000000D] = "ON_BUS_TIMER_EXPIRED"; mpi_event[0x0000000E] = "QUEUE_FULL"; mpi_event[0x0000000F] = "SAS_DEVICE_STATUS_CHANGE"; mpi_event[0x00000010] = "SAS_SES"; mpi_event[0x00000011] = "PERSISTENT_TABLE_FULL"; mpi_event[0x00000012] = "SAS_PHY_LINK_STATUS"; mpi_event[0x00000013] = "SAS_DISCOVERY_ERROR"; mpi_event[0x00000014] = "IR_RESYNC_UPDATE"; mpi_event[0x00000015] = "IR2"; mpi_event[0x00000016] = "SAS_DISCOVERY"; mpi_event[0x00000017] = "SAS_BROADCAST_PRIMITIVE"; mpi_event[0x00000018] = "SAS_INIT_DEVICE_STATUS_CHANGE"; mpi_event[0x00000019] = "SAS_INIT_TABLE_OVERFLOW"; mpi_event[0x0000001A] = "SAS_SMP_ERROR"; mpi_event[0x0000001B] = "SAS_EXPANDER_STATUS_CHANGE"; mpi_event[0x00000021] = "LOG_ENTRY_ADDED"; sas_discovery[0x00000000] = "SAS_DSCVRY_COMPLETE"; sas_discovery[0x00000001] = "SAS_DSCVRY_IN_PROGRESS"; dev_stat[0x03] = "ADDED"; dev_stat[0x04] = "NOT_RESPONDING"; dev_stat[0x05] = "SMART_DATA"; dev_stat[0x06] = "NO_PERSIST_ADDED"; dev_stat[0x07] = "UNSUPPORTED"; dev_stat[0x08] = "INTERNAL_DEVICE_RESET"; dev_stat[0x09] = "TASK_ABORT_INTERNAL"; dev_stat[0x0A] = "ABORT_TASK_SET_INTERNAL"; dev_stat[0x0B] = "CLEAR_TASK_SET_INTERNAL"; dev_stat[0x0C] = "QUERY_TASK_INTERNAL"; dev_stat[0x0D] = "ASYNC_NOTIFICATION"; dev_stat[0x0E] = "CMPL_INTERNAL_DEV_RESET"; dev_stat[0x0F] = "CMPL_TASK_ABORT_INTERNAL"; printf("%-20s %-6s %-3s %s\n", "TIME", "MODULE", "CPU", "EVENT"); } sdt:mpt::handle-event-sync { this->mpt = (mpt_t *)arg0; this->mpt_name = strjoin("mpt", lltostr(this->mpt->m_instance)); this->event_text = mpi_event[arg1] != NULL ? mpi_event[arg1] : lltostr(arg1); printf("%-20Y %-6s %-3d -> %s\n", walltimestamp, this->mpt_name, cpu, this->event_text); } sdt:mpt::handle-event-sync /arg1 == 0x00000016/ { self->mpt = (mpt_t *)arg0; self->discovery = 1; } fbt::mpt_handle_event_sync:return /self->discovery/ { /* remove the PHY_BITS from the discovery status */ this->cond = self->mpt->m_discovery & 0x0000FFFF; this->cond_text = sas_discovery[this->cond] != NULL ? sas_discovery[this->cond] : lltostr(this->cond); printf("%-20Y %-6s %-3d -> discovery status: %s\n", walltimestamp, this->mpt_name, cpu, this->cond_text); self->mpt = 0; self->discovery = 0; } sdt:mpt::device-status-change { this->mpt = (mpt_t *)arg0; this->mpt_name = strjoin("mpt", lltostr(this->mpt->m_instance)); this->reason = arg2; this->reason_text = dev_stat[this->reason] != NULL ? dev_stat[this->reason] : lltostr(this->reason); printf("%-20Y %-6s %-3d -> device change: %s\n", walltimestamp, this->mpt_name, cpu, this->reason_text); printf("%-20Y %-6s %-3d wwn=%x\n", walltimestamp, this->mpt_name, cpu, arg3); } sdt:mpt::event-sas-phy-link-status { this->mpt = (mpt_t *)arg0; this->mpt_name = strjoin("mpt", lltostr(this->mpt->m_instance)); this->phynum = arg1; printf("%-20Y %-6s %-3d -> phy link status, phy=%d\n", walltimestamp, this->mpt_name, cpu, this->phynum); } ================================================ FILE: Chap4/mptlatency.d ================================================ #!/usr/sbin/dtrace -s /* * mptlatency.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ dtrace:::BEGIN { /* See /usr/include/sys/scsi/generic/commands.h for the full list. */ scsi_cmd[0x00] = "test_unit_ready"; scsi_cmd[0x08] = "read"; scsi_cmd[0x0a] = "write"; scsi_cmd[0x12] = "inquiry"; scsi_cmd[0x17] = "release"; scsi_cmd[0x1a] = "mode_sense"; scsi_cmd[0x1b] = "load/start/stop"; scsi_cmd[0x1c] = "get_diagnostic_results"; scsi_cmd[0x1d] = "send_diagnostic_command"; scsi_cmd[0x25] = "read_capacity"; scsi_cmd[0x28] = "read(10)"; scsi_cmd[0x2a] = "write(10)"; scsi_cmd[0x35] = "synchronize_cache"; scsi_cmd[0x4d] = "log_sense"; scsi_cmd[0x5e] = "persistent_reserve_in"; scsi_cmd[0xa0] = "report_luns"; } sdt:mpt::io-time-on-hba-non-a-reply { this->mpt = (mpt_t *)arg0; this->mpt_cmd = (mpt_cmd_t *)arg1; this->mpt_name = strjoin("mpt", lltostr(this->mpt->m_instance)); this->delta = (this->mpt_cmd->cmd_io_done_time - this->mpt_cmd->cmd_io_start_time) / 1000; this->code = *this->mpt_cmd->cmd_cdb; this->cmd_text = scsi_cmd[this->code] != NULL ? scsi_cmd[this->code] : lltostr(this->code); @[this->mpt_name, this->cmd_text] = quantize(this->delta); } dtrace:::END { printf("Command Latency (us):\n"); printa(@); } ================================================ FILE: Chap4/mptsasscsi.d ================================================ #!/usr/sbin/dtrace -Cs /* * mptsasscsi.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet /* From uts/common/sys/mpt/mpi_ioc.h */ #define MPI_PORTFACTS_PORTTYPE_INACTIVE 0x00 #define MPI_PORTFACTS_PORTTYPE_SCSI 0x01 #define MPI_PORTFACTS_PORTTYPE_FC 0x10 #define MPI_PORTFACTS_PORTTYPE_ISCSI 0x20 #define MPI_PORTFACTS_PORTTYPE_SAS 0x30 dtrace:::BEGIN { /* See /usr/include/sys/scsi/generic/commands.h for the full list. */ scsi_cmd[0x00] = "test_unit_ready"; scsi_cmd[0x08] = "read"; scsi_cmd[0x0a] = "write"; scsi_cmd[0x12] = "inquiry"; scsi_cmd[0x17] = "release"; scsi_cmd[0x1a] = "mode_sense"; scsi_cmd[0x1b] = "load/start/stop"; scsi_cmd[0x1c] = "get_diagnostic_results"; scsi_cmd[0x1d] = "send_diagnostic_command"; scsi_cmd[0x25] = "read_capacity"; scsi_cmd[0x28] = "read(10)"; scsi_cmd[0x2a] = "write(10)"; scsi_cmd[0x35] = "synchronize_cache"; scsi_cmd[0x4d] = "log_sense"; scsi_cmd[0x5e] = "persistent_reserve_in"; scsi_cmd[0xa0] = "report_luns"; printf("Tracing... Hit Ctrl-C to end.\n"); } fbt::mpt_start_cmd:entry /args[0]->m_port_type[0] == MPI_PORTFACTS_PORTTYPE_SAS/ { this->mpt = args[0]; this->mpt_name = strjoin("mpt", lltostr(this->mpt->m_instance)); this->node_name = this->mpt->m_dip != NULL ? stringof(((struct dev_info *)this->mpt->m_dip)->devi_node_name) : ""; this->scsi_pkt = args[1]->cmd_pkt; this->code = *this->scsi_pkt->pkt_cdbp; this->cmd_text = scsi_cmd[this->code] != NULL ? scsi_cmd[this->code] : lltostr(this->code); @cmd[this->node_name, this->mpt_name, this->cmd_text] = count(); } dtrace:::END { printf(" %-16s %-12s %-36s %s\n", "DEVICE NODE", "MODULE", "SCSI CMD", "COUNT"); printa(" %-16s %-12s %-36s %@d\n", @cmd); } ================================================ FILE: Chap4/rwtime.d ================================================ #!/usr/sbin/dtrace -s /* * rwtime.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } io:::start { start_time[arg0] = timestamp; } io:::done /(args[0]->b_flags & B_READ) && (this->start = start_time[arg0])/ { this->delta = (timestamp - this->start) / 1000; @plots["read I/O, us"] = quantize(this->delta); @avgs["average read I/O, us"] = avg(this->delta); start_time[arg0] = 0; } io:::done /!(args[0]->b_flags & B_READ) && (this->start = start_time[arg0])/ { this->delta = (timestamp - this->start) / 1000; @plots["write I/O, us"] = quantize(this->delta); @avgs["average write I/O, us"] = avg(this->delta); start_time[arg0] = 0; } dtrace:::END { printa(" %s\n%@d\n", @plots); printa(@avgs); } ================================================ FILE: Chap4/satacmds.d ================================================ #!/usr/sbin/dtrace -Zs /* * satacmds.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet string sata_cmd[uchar_t]; dtrace:::BEGIN { /* * These are from the SATA_DIR_* and SATA_OPMODE_* definitions in * /usr/include/sys/sata/sata_hba.h: */ sata_dir[1] = "no-data"; sata_dir[2] = "read"; sata_dir[4] = "write"; sata_opmode[0] = "ints+async"; /* interrupts and asynchronous */ sata_opmode[1] = "poll"; /* polling */ sata_opmode[4] = "synch"; /* synchronous */ sata_opmode[5] = "synch+poll"; /* (valid?) */ /* * These SATA command descriptions were generated from the SATAC_* * definitions in /usr/include/sys/sata/sata_defs.h: */ sata_cmd[0x90] = "diagnose command"; sata_cmd[0x10] = "restore cmd, 4 bits step rate"; sata_cmd[0x50] = "format track command"; sata_cmd[0xef] = "set features"; sata_cmd[0xe1] = "idle immediate"; sata_cmd[0xe0] = "standby immediate"; sata_cmd[0xde] = "door lock"; sata_cmd[0xdf] = "door unlock"; sata_cmd[0xe3] = "idle"; sata_cmd[0xe2] = "standby"; sata_cmd[0x08] = "ATAPI device reset"; sata_cmd[0x92] = "Download microcode"; sata_cmd[0xed] = "media eject"; sata_cmd[0xe7] = "flush write-cache"; sata_cmd[0xec] = "IDENTIFY DEVICE"; sata_cmd[0xa1] = "ATAPI identify packet device"; sata_cmd[0x91] = "initialize device parameters"; sata_cmd[0xa0] = "ATAPI packet"; sata_cmd[0xc4] = "read multiple w/DMA"; sata_cmd[0x20] = "read sector"; sata_cmd[0x40] = "read verify"; sata_cmd[0xc8] = "read DMA"; sata_cmd[0x70] = "seek"; sata_cmd[0xa2] = "queued/overlap service"; sata_cmd[0xc6] = "set multiple mode"; sata_cmd[0xca] = "write (multiple) w/DMA"; sata_cmd[0xc5] = "write multiple"; sata_cmd[0x30] = "write sector"; sata_cmd[0x24] = "read sector extended (LBA48)"; sata_cmd[0x25] = "read DMA extended (LBA48)"; sata_cmd[0x29] = "read multiple extended (LBA48)"; sata_cmd[0x34] = "write sector extended (LBA48)"; sata_cmd[0x35] = "write DMA extended (LBA48)"; sata_cmd[0x39] = "write multiple extended (LBA48)"; sata_cmd[0xc7] = "read DMA / may be queued"; sata_cmd[0x26] = "read DMA ext / may be queued"; sata_cmd[0xcc] = "write DMA / may be queued"; sata_cmd[0x36] = "write DMA ext / may be queued"; sata_cmd[0xe4] = "read port mult reg"; sata_cmd[0xe8] = "write port mult reg"; sata_cmd[0x60] = "First-Party-DMA read queued"; sata_cmd[0x61] = "First-Party-DMA write queued"; sata_cmd[0x2f] = "read log"; sata_cmd[0xb0] = "SMART"; sata_cmd[0xe5] = "check power mode"; printf("Tracing... Hit Ctrl-C to end.\n"); } /* * Trace SATA command start by probing the entry to the SATA HBA driver. Four * different drivers are covered here; add yours here if it is missing. */ fbt::nv_sata_start:entry, fbt::bcm_sata_start:entry, fbt::ahci_tran_start:entry, fbt::mv_start:entry { this->dev = (struct dev_info *)arg0; this->sata_pkt = (sata_pkt_t *)arg1; this->modname = this->dev != NULL ? stringof(this->dev->devi_node_name) : ""; this->dir = this->sata_pkt->satapkt_cmd.satacmd_flags.sata_data_direction; this->dir_text = sata_dir[this->dir] != NULL ? sata_dir[this->dir] : ""; this->cmd = this->sata_pkt->satapkt_cmd.satacmd_cmd_reg; this->cmd_text = sata_cmd[this->cmd] != NULL ? sata_cmd[this->cmd] : lltostr(this->cmd); this->op_mode = this->sata_pkt->satapkt_op_mode; this->op_text = sata_opmode[this->op_mode] != NULL ? sata_opmode[this->op_mode] : lltostr(this->op_mode); @[this->modname, this->dir_text, this->cmd_text, this->op_text] = count(); } dtrace:::END { printf(" %-14s %-9s %-30s %-10s %s\n", "DEVICE NODE", "DIR", "COMMAND", "OPMODE", "COUNT"); printa(" %-14s %-9s %-30s %-10s %@d\n", @); } ================================================ FILE: Chap4/satalatency.d ================================================ #!/usr/sbin/dtrace -Zs /* * satalatency.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet string sata_cmd[uchar_t]; dtrace:::BEGIN { /* * Some SATAC_* definitions from /usr/include/sys/sata/sata_defs.h, for * commands commonly issued. More can be added from satacmds.d. */ sata_cmd[0x20] = "read sector"; sata_cmd[0x25] = "read DMA extended"; sata_cmd[0x35] = "write DMA extended"; sata_cmd[0x30] = "write sector"; sata_cmd[0x40] = "read verify"; sata_cmd[0x70] = "seek"; sata_cmd[0x90] = "diagnose command"; sata_cmd[0xb0] = "SMART"; sata_cmd[0xec] = "IDENTIFY DEVICE"; sata_cmd[0xe5] = "check power mode"; sata_cmd[0xe7] = "flush write-cache"; sata_cmd[0xef] = "set features"; /* * These are SATA_PKT_* from /usr/include/sys/sata/sata_hba.h: */ sata_reason[-1] = "Not completed, busy"; sata_reason[0] = "Success"; sata_reason[1] = "Device reported error"; sata_reason[2] = "Not accepted, queue full"; sata_reason[3] = "Not completed, port error"; sata_reason[4] = "Cmd unsupported"; sata_reason[5] = "Aborted by request"; sata_reason[6] = "Operation timeout"; sata_reason[7] = "Aborted by reset request"; printf("Tracing... Hit Ctrl-C to end.\n"); } /* * Trace SATA command start by probing the entry to the SATA HBA * driver. Four different drivers are covered here; add yours here * if it is missing. */ fbt::nv_sata_start:entry, fbt::bcm_sata_start:entry, fbt::ahci_tran_start:entry, fbt::mv_start:entry { start[arg1] = timestamp; } fbt::sata_pkt_free:entry /start[(uint64_t)args[0]->txlt_sata_pkt]/ { this->sata_pkt = args[0]->txlt_sata_pkt; this->delta = (timestamp - start[(uint64_t)this->sata_pkt]) / 1000; this->cmd = this->sata_pkt->satapkt_cmd.satacmd_cmd_reg; this->cmd_text = sata_cmd[this->cmd] != NULL ? sata_cmd[this->cmd] : lltostr(this->cmd); this->reason = this->sata_pkt->satapkt_reason; this->reason_text = sata_reason[this->reason] != NULL ? sata_reason[this->reason] : lltostr(this->reason); @num[this->cmd_text, this->reason_text] = count(); @average[this->cmd_text, this->reason_text] = avg(this->delta); @total[this->cmd_text, this->reason_text] = sum(this->delta); start[(uint64_t)this->sata_pkt] = 0; } dtrace:::END { normalize(@total, 1000); printf("\n %-18s %23s %10s %10s %10s\n", "SATA COMMAND", "COMPLETION", "COUNT", "AVG(us)", "TOTAL(ms)"); printa(" %-18s %23s %@10d %@10d %@10d\n", @num, @average, @total); } ================================================ FILE: Chap4/satareasons.d ================================================ #!/usr/sbin/dtrace -s /* * satareasons.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet string sata_cmd[uchar_t]; dtrace:::BEGIN { /* * These are SATA_DIR_* from /usr/include/sys/sata/sata_hba.h: */ sata_dir[1] = "no-data"; sata_dir[2] = "read"; sata_dir[4] = "write"; /* * Some SATAC_* definitions from /usr/include/sys/sata/sata_defs.h, for * commands commonly issued. More can be added from satacmds.d. */ sata_cmd[0x20] = "read sector"; sata_cmd[0x25] = "read DMA extended"; sata_cmd[0x35] = "write DMA extended"; sata_cmd[0x30] = "write sector"; sata_cmd[0x40] = "read verify"; sata_cmd[0x70] = "seek"; sata_cmd[0x90] = "diagnose command"; sata_cmd[0xb0] = "SMART"; sata_cmd[0xec] = "IDENTIFY DEVICE"; sata_cmd[0xe5] = "check power mode"; sata_cmd[0xe7] = "flush write-cache"; sata_cmd[0xef] = "set features"; /* * These are SATA_PKT_* from /usr/include/sys/sata/sata_hba.h: */ sata_reason[-1] = "Not completed, busy"; sata_reason[0] = "Success"; sata_reason[1] = "Device reported error"; sata_reason[2] = "Not accepted, queue full"; sata_reason[3] = "Not completed, port error"; sata_reason[4] = "Cmd unsupported"; sata_reason[5] = "Aborted by request"; sata_reason[6] = "Operation timeout"; sata_reason[7] = "Aborted by reset request"; printf("Tracing... Hit Ctrl-C to end.\n"); } fbt::sd_start_cmds:entry { /* see the sd_start_cmds() source to understand the following logic */ self->bp = args[1] != NULL ? args[1] : args[0]->un_waitq_headp; } fbt::sd_start_cmds:return { self->bp = 0; } fbt::sata_hba_start:entry /self->bp->b_dip/ { statname[args[0]->txlt_sata_pkt] = xlate (self->bp)->dev_statname; } fbt::sata_pkt_free:entry /args[0]->txlt_sata_pkt->satapkt_cmd.satacmd_cmd_reg/ { this->sata_pkt = args[0]->txlt_sata_pkt; this->devname = statname[this->sata_pkt] != NULL ? statname[this->sata_pkt] : ""; this->dir = this->sata_pkt->satapkt_cmd.satacmd_flags.sata_data_direction; this->dir_text = sata_dir[this->dir] != NULL ? sata_dir[this->dir] : ""; this->cmd = this->sata_pkt->satapkt_cmd.satacmd_cmd_reg; this->cmd_text = sata_cmd[this->cmd] != NULL ? sata_cmd[this->cmd] : lltostr(this->cmd); this->reason = this->sata_pkt->satapkt_reason; this->reason_text = sata_reason[this->reason] != NULL ? sata_reason[this->reason] : lltostr(this->reason); statname[this->sata_pkt] = 0; @[this->devname, this->dir_text, this->cmd_text, this->reason_text] = count(); } dtrace:::END { printf(" %-8s %-10s %-20s %25s %s\n", "DEVICE", "DIR", "COMMAND", "REASON", "COUNT"); printa(" %-8s %-10s %-20s %25s %@d\n", @); } ================================================ FILE: Chap4/satarw.d ================================================ #!/usr/sbin/dtrace -s /* * satarw.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { /* * SATA_DIR of type 1 normally means no-data, but we can call it * sync-cache as that's the only type 1 we are tracing. */ sata_dir[1] = "sync-cache"; sata_dir[2] = "read"; sata_dir[4] = "write"; printf("Tracing... Hit Ctrl-C to end.\n"); } /* cache the I/O size while it is still easy to determine */ fbt::sd_start_cmds:entry { /* see the sd_start_cmds() source to understand the following logic */ this->bp = args[1] != NULL ? args[1] : args[0]->un_waitq_headp; self->size = this->bp != NULL ? this->bp->b_bcount : 0; } fbt::sd_start_cmds:return { self->size = 0; } /* trace generic SATA driver functions for read, write and sync-cache */ fbt::sata_txlt_read:entry, fbt::sata_txlt_write:entry, fbt::sata_txlt_synchronize_cache:entry { this->sata_pkt = args[0]->txlt_sata_pkt; start[(uint64_t)this->sata_pkt] = timestamp; size[(uint64_t)this->sata_pkt] = self->size; } /* SATA command completed */ fbt::sata_pkt_free:entry /start[(uint64_t)args[0]->txlt_sata_pkt]/ { this->sata_pkt = args[0]->txlt_sata_pkt; this->delta = (timestamp - start[(uint64_t)this->sata_pkt]) / 1000; this->size = size[(uint64_t)this->sata_pkt]; this->dir = this->sata_pkt->satapkt_cmd.satacmd_flags.sata_data_direction; this->dir_text = sata_dir[this->dir] != NULL ? sata_dir[this->dir] : ""; @num[this->dir_text] = count(); @avg_size[this->dir_text] = avg(this->size); @avg_time[this->dir_text] = avg(this->delta); @sum_size[this->dir_text] = sum(this->size); @sum_time[this->dir_text] = sum(this->delta); @plot_size[this->dir_text] = quantize(this->size); @plot_time[this->dir_text] = quantize(this->delta); start[(uint64_t)this->sata_pkt] = 0; size[(uint64_t)this->sata_pkt] = 0; } dtrace:::END { normalize(@avg_size, 1024); normalize(@sum_size, 1048576); normalize(@sum_time, 1000); printf(" %-10s %10s %10s %10s %10s %12s\n", "DIR", "COUNT", "AVG(KB)", "TOTAL(MB)", "AVG(us)", "TOTAL(ms)"); printa(" %-10s %@10d %@10d %@10d %@10d %@12d\n", @num, @avg_size, @sum_size, @avg_time, @sum_time); printf("\n\nSATA I/O size (bytes):\n"); printa(@plot_size); printf("\nSATA I/O latency (us):\n"); printa(@plot_time); } ================================================ FILE: Chap4/scsicmds.d ================================================ #!/usr/sbin/dtrace -s /* * scsicmds.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet string scsi_cmd[uchar_t]; dtrace:::BEGIN { /* * The following was generated from the SCSI_CMDS_KEY_STRINGS * definitions in /usr/include/sys/scsi/generic/commands.h using sed. */ scsi_cmd[0x00] = "test_unit_ready"; scsi_cmd[0x01] = "rezero/rewind"; scsi_cmd[0x03] = "request_sense"; scsi_cmd[0x04] = "format"; scsi_cmd[0x05] = "read_block_limits"; scsi_cmd[0x07] = "reassign"; scsi_cmd[0x08] = "read"; scsi_cmd[0x0a] = "write"; scsi_cmd[0x0b] = "seek"; scsi_cmd[0x0f] = "read_reverse"; scsi_cmd[0x10] = "write_file_mark"; scsi_cmd[0x11] = "space"; scsi_cmd[0x12] = "inquiry"; scsi_cmd[0x13] = "verify"; scsi_cmd[0x14] = "recover_buffer_data"; scsi_cmd[0x15] = "mode_select"; scsi_cmd[0x16] = "reserve"; scsi_cmd[0x17] = "release"; scsi_cmd[0x18] = "copy"; scsi_cmd[0x19] = "erase_tape"; scsi_cmd[0x1a] = "mode_sense"; scsi_cmd[0x1b] = "load/start/stop"; scsi_cmd[0x1c] = "get_diagnostic_results"; scsi_cmd[0x1d] = "send_diagnostic_command"; scsi_cmd[0x1e] = "door_lock"; scsi_cmd[0x23] = "read_format_capacity"; scsi_cmd[0x25] = "read_capacity"; scsi_cmd[0x28] = "read(10)"; scsi_cmd[0x2a] = "write(10)"; scsi_cmd[0x2b] = "seek(10)"; scsi_cmd[0x2e] = "write_verify"; scsi_cmd[0x2f] = "verify(10)"; scsi_cmd[0x30] = "search_data_high"; scsi_cmd[0x31] = "search_data_equal"; scsi_cmd[0x32] = "search_data_low"; scsi_cmd[0x33] = "set_limits"; scsi_cmd[0x34] = "read_position"; scsi_cmd[0x35] = "synchronize_cache"; scsi_cmd[0x37] = "read_defect_data"; scsi_cmd[0x39] = "compare"; scsi_cmd[0x3a] = "copy_verify"; scsi_cmd[0x3b] = "write_buffer"; scsi_cmd[0x3c] = "read_buffer"; scsi_cmd[0x3e] = "read_long"; scsi_cmd[0x3f] = "write_long"; scsi_cmd[0x44] = "report_densities/read_header"; scsi_cmd[0x4c] = "log_select"; scsi_cmd[0x4d] = "log_sense"; scsi_cmd[0x55] = "mode_select(10)"; scsi_cmd[0x56] = "reserve(10)"; scsi_cmd[0x57] = "release(10)"; scsi_cmd[0x5a] = "mode_sense(10)"; scsi_cmd[0x5e] = "persistent_reserve_in"; scsi_cmd[0x5f] = "persistent_reserve_out"; scsi_cmd[0x80] = "write_file_mark(16)"; scsi_cmd[0x81] = "read_reverse(16)"; scsi_cmd[0x83] = "extended_copy"; scsi_cmd[0x88] = "read(16)"; scsi_cmd[0x8a] = "write(16)"; scsi_cmd[0x8c] = "read_attribute"; scsi_cmd[0x8d] = "write_attribute"; scsi_cmd[0x8f] = "verify(16)"; scsi_cmd[0x91] = "space(16)"; scsi_cmd[0x92] = "locate(16)"; scsi_cmd[0x9e] = "service_action_in(16)"; scsi_cmd[0x9f] = "service_action_out(16)"; scsi_cmd[0xa0] = "report_luns"; scsi_cmd[0xa2] = "security_protocol_in"; scsi_cmd[0xa3] = "maintenance_in"; scsi_cmd[0xa4] = "maintenance_out"; scsi_cmd[0xa8] = "read(12)"; scsi_cmd[0xa9] = "service_action_out(12)"; scsi_cmd[0xaa] = "write(12)"; scsi_cmd[0xab] = "service_action_in(12)"; scsi_cmd[0xac] = "get_performance"; scsi_cmd[0xAF] = "verify(12)"; scsi_cmd[0xb5] = "security_protocol_out"; printf("Tracing... Hit Ctrl-C to end.\n"); } fbt::scsi_transport:entry { this->dev = (struct dev_info *)args[0]->pkt_address.a_hba_tran->tran_hba_dip; this->nodename = this->dev != NULL ? stringof(this->dev->devi_node_name) : ""; this->code = *args[0]->pkt_cdbp; this->cmd = scsi_cmd[this->code] != NULL ? scsi_cmd[this->code] : lltostr(this->code); @[this->nodename, this->cmd] = count(); } dtrace:::END { printf(" %-24s %-36s %s\n", "DEVICE NODE", "SCSI COMMAND", "COUNT"); printa(" %-24s %-36s %@d\n", @); } ================================================ FILE: Chap4/scsilatency.d ================================================ #!/usr/sbin/dtrace -s /* * scsilatency.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet string scsi_cmd[uchar_t]; dtrace:::BEGIN { /* See /usr/include/sys/scsi/generic/commands.h for the full list. */ scsi_cmd[0x00] = "test_unit_ready"; scsi_cmd[0x08] = "read"; scsi_cmd[0x0a] = "write"; scsi_cmd[0x12] = "inquiry"; scsi_cmd[0x17] = "release"; scsi_cmd[0x1a] = "mode_sense"; scsi_cmd[0x1b] = "load/start/stop"; scsi_cmd[0x1c] = "get_diagnostic_results"; scsi_cmd[0x1d] = "send_diagnostic_command"; scsi_cmd[0x25] = "read_capacity"; scsi_cmd[0x28] = "read(10)"; scsi_cmd[0x2a] = "write(10)"; scsi_cmd[0x35] = "synchronize_cache"; scsi_cmd[0x4d] = "log_sense"; scsi_cmd[0x5e] = "persistent_reserve_in"; scsi_cmd[0xa0] = "report_luns"; printf("Tracing... Hit Ctrl-C to end.\n"); } fbt::scsi_transport:entry { start[arg0] = timestamp; } fbt::scsi_destroy_pkt:entry /start[arg0]/ { this->delta = (timestamp - start[arg0]) / 1000; this->code = *args[0]->pkt_cdbp; this->cmd = scsi_cmd[this->code] != NULL ? scsi_cmd[this->code] : lltostr(this->code); this->reason = args[0]->pkt_reason == 0 ? "Success" : strjoin("Fail:", lltostr(args[0]->pkt_reason)); @num[this->cmd, this->reason] = count(); @average[this->cmd, this->reason] = avg(this->delta); @total[this->cmd, this->reason] = sum(this->delta); start[arg0] = 0; } dtrace:::END { normalize(@total, 1000); printf("\n %-26s %-12s %11s %11s %11s\n", "SCSI COMMAND", "COMPLETION", "COUNT", "AVG(us)", "TOTAL(ms)"); printa(" %-26s %-12s %@11d %@11d %@11d\n", @num, @average, @total); } ================================================ FILE: Chap4/scsireasons.d ================================================ #!/usr/sbin/dtrace -s /* * scsireasons.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { /* * The following was generated from the CMD_* pkt_reason definitions * in /usr/include/sys/scsi/scsi_pkt.h using sed. */ scsi_reason[0] = "no transport errors- normal completion"; scsi_reason[1] = "transport stopped with not normal state"; scsi_reason[2] = "dma direction error occurred"; scsi_reason[3] = "unspecified transport error"; scsi_reason[4] = "Target completed hard reset sequence"; scsi_reason[5] = "Command transport aborted on request"; scsi_reason[6] = "Command timed out"; scsi_reason[7] = "Data Overrun"; scsi_reason[8] = "Command Overrun"; scsi_reason[9] = "Status Overrun"; scsi_reason[10] = "Message not Command Complete"; scsi_reason[11] = "Target refused to go to Message Out phase"; scsi_reason[12] = "Extended Identify message rejected"; scsi_reason[13] = "Initiator Detected Error message rejected"; scsi_reason[14] = "Abort message rejected"; scsi_reason[15] = "Reject message rejected"; scsi_reason[16] = "No Operation message rejected"; scsi_reason[17] = "Message Parity Error message rejected"; scsi_reason[18] = "Bus Device Reset message rejected"; scsi_reason[19] = "Identify message rejected"; scsi_reason[20] = "Unexpected Bus Free Phase occurred"; scsi_reason[21] = "Target rejected our tag message"; scsi_reason[22] = "Command transport terminated on request"; scsi_reason[24] = "The device has been removed"; printf("Tracing... Hit Ctrl-C to end.\n"); } fbt::scsi_init_pkt:entry /args[2] != NULL/ { self->name = xlate (args[2])->dev_statname; } fbt::scsi_init_pkt:return { pkt_name[arg1] = self->name; self->name = 0; } fbt::scsi_destroy_pkt:entry { this->code = args[0]->pkt_reason; this->reason = scsi_reason[this->code] != NULL ? scsi_reason[this->code] : ""; @all[this->reason] = count(); } fbt::scsi_destroy_pkt:entry /this->code != 0/ { this->name = pkt_name[arg0] != NULL ? pkt_name[arg0] : ""; @errors[pkt_name[arg0], this->reason] = count(); } fbt::scsi_destroy_pkt:entry { pkt_name[arg0] = 0; } dtrace:::END { printf("\nSCSI I/O completion reason summary:\n"); printa(@all); printf("\n\nSCSI I/O reason errors by disk device and reason:\n\n"); printf(" %-16s %-44s %s\n", "DEVICE", "ERROR REASON", "COUNT"); printa(" %-16s %-44s %@d\n", @errors); } ================================================ FILE: Chap4/scsirw.d ================================================ #!/usr/sbin/dtrace -s /* * scsirw.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } fbt::sd_setup_rw_pkt:entry { self->in__sd_setup_rw_pkt = 1; } fbt::sd_setup_rw_pkt:return { self->in__sd_setup_rw_pkt = 0; } fbt::scsi_init_pkt:entry /self->in__sd_setup_rw_pkt/ { self->buf = args[2]; } /* Store start time and size for read and write commands */ fbt::scsi_init_pkt:return /self->buf/ { start[arg1] = timestamp; size[arg1] = self->buf->b_bcount; dir[arg1] = self->buf->b_flags & B_WRITE ? "write" : "read"; self->buf = 0; } fbt::sd_send_scsi_SYNCHRONIZE_CACHE:entry { self->in__sync_cache = 1; } fbt::sd_send_scsi_SYNCHRONIZE_CACHE:return { self->in__sync_cache = 0; } /* Store start time for sync-cache commands */ fbt::scsi_init_pkt:return /self->in__sync_cache/ { start[arg1] = timestamp; dir[arg1] = "sync-cache"; } /* SCSI command completed */ fbt::scsi_destroy_pkt:entry /start[arg0]/ { this->delta = (timestamp - start[arg0]) / 1000; this->size = size[arg0]; this->dir = dir[arg0]; @num[this->dir] = count(); @avg_size[this->dir] = avg(this->size); @avg_time[this->dir] = avg(this->delta); @sum_size[this->dir] = sum(this->size); @sum_time[this->dir] = sum(this->delta); @plot_size[this->dir] = quantize(this->size); @plot_time[this->dir] = quantize(this->delta); start[arg0] = 0; size[arg0] = 0; dir[arg0] = 0; } dtrace:::END { normalize(@avg_size, 1024); normalize(@sum_size, 1048576); normalize(@sum_time, 1000); printf(" %-10s %10s %10s %10s %10s %12s\n", "DIR", "COUNT", "AVG(KB)", "TOTAL(MB)", "AVG(us)", "TOTAL(ms)"); printa(" %-10s %@10d %@10d %@10d %@10d %@12d\n", @num, @avg_size, @sum_size, @avg_time, @sum_time); printf("\n\nSCSI I/O size (bytes):\n"); printa(@plot_size); printf("\nSCSI I/O latency (us):\n"); printa(@plot_time); } ================================================ FILE: Chap4/sdqueue.d ================================================ #!/usr/sbin/dtrace -s /* * sdqueue.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } fbt::sd_add_buf_to_waitq:entry /args[1]->b_dip/ { start_time[arg1] = timestamp; } sdt:::scsi-transport-dispatch /this->start = start_time[arg0]/ { this->delta = (timestamp - this->start) / 1000; this->bp = (buf_t *)arg0; this->dev = xlate (this->bp)->dev_statname; this->path = xlate (this->bp)->dev_pathname; @avg[this->dev, this->path] = avg(this->delta); @plot[this->dev, this->path] = lquantize(this->delta / 1000, 0, 1000, 100); start_time[arg0] = 0; } dtrace:::END { printf("Wait queue time by disk (ms):\n"); printa("\n %-12s %-50s\n%@d", @plot); printf("\n\n %-12s %-50s %12s\n", "DEVICE", "PATH", "AVG_WAIT(us)"); printa(" %-12s %-50s %@12d\n", @avg); } ================================================ FILE: Chap4/sdretry.d ================================================ #!/usr/sbin/dtrace -s /* * sdretry.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... output every 10 seconds.\n"); } fbt::sd_set_retry_bp:entry { @[xlate (args[1])->dev_statname, xlate (args[1])->dev_major, xlate (args[1])->dev_minor] = count(); } tick-10sec { printf("\n%Y:\n", walltimestamp); printf("%28s %-3s,%-4s %s\n", "DEVICE", "MAJ", "MIN", "RETRIES"); printa("%28s %-03d,%-4d %@d\n", @); trunc(@); } ================================================ FILE: Chap4/seeksize.d ================================================ #!/usr/sbin/dtrace -s /* * seeksize.d * * Example script from Chapter 4 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } self int last[dev_t]; io:::start /self->last[args[0]->b_edev] != 0/ { this->last = self->last[args[0]->b_edev]; this->dist = (int)(args[0]->b_blkno - this->last) > 0 ? args[0]->b_blkno - this->last : this->last - args[0]->b_blkno; @Size[pid, curpsinfo->pr_psargs] = quantize(this->dist); } io:::start { self->last[args[0]->b_edev] = args[0]->b_blkno + args[0]->b_bcount / 512; } dtrace:::END { printf("\n%8s %s\n", "PID", "CMD"); printa("%8d %S\n%@d\n", @Size); } ================================================ FILE: Chap5/cdrom.d ================================================ #!/usr/sbin/dtrace -Zs /* * cdrom.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { trace("Tracing hsfs (cdrom) mountfs...\n"); } fbt::hs_mountfs:entry { printf("%Y: Mounting %s... ", walltimestamp, stringof(arg2)); self->start = timestamp; } fbt::hs_mountfs:return /self->start/ { this->time = (timestamp - self->start) / 1000000; printf("result: %d%s, time: %d ms\n", arg1, arg1 ? "" : " (SUCCESS)", this->time); self->start = 0; } ================================================ FILE: Chap5/dnlcps.d ================================================ #!/usr/sbin/dtrace -s /* * dnlcps.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } fbt::dnlc_lookup:return { this->code = arg1 == 0 ? 0 : 1; @Result[execname, pid] = lquantize(this->code, 0, 1, 1); } dtrace:::END { printa(" CMD: %-16s PID: %d\n%@d\n", @Result); } ================================================ FILE: Chap5/dvd.d ================================================ #!/usr/sbin/dtrace -Zs /* * dvd.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { trace("Tracing udfs (dvd) mountfs...\n"); } fbt::ud_mountfs:entry { printf("%Y: Mounting %s... ", walltimestamp, stringof(arg2)); self->start = timestamp; } fbt::ud_mountfs:return /self->start/ { this->time = (timestamp - self->start) / 1000000; printf("result: %d%s, time: %d ms\n", arg1, arg1 ? "" : " (SUCCESS)", this->time); self->start = 0; } ================================================ FILE: Chap5/fserrors.d ================================================ #!/usr/sbin/dtrace -s /* * fserrors.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing syscall errors... Hit Ctrl-C to end.\n"); } syscall::read*:entry, syscall::write*:entry { self->fd = arg0; } syscall::open*:entry, syscall::stat*:entry { self->ptr = arg0; } syscall::read*:return, syscall::write*:return /(int)arg0 < 0 && self->fd > 2/ { self->path = fds[self->fd].fi_pathname; } syscall::open*:return, syscall::stat*:return /(int)arg0 < 0 && self->ptr/ { self->path = copyinstr(self->ptr); } syscall::read*:return, syscall::write*:return, syscall::open*:return, syscall::stat*:return /(int)arg0 < 0 && self->path != NULL/ { @[execname, probefunc, errno, self->path] = count(); self->path = 0; } syscall::read*:return, syscall::write*:return { self->fd = 0; } syscall::open*:return, syscall::stat*:return { self->ptr = 0; } dtrace:::END { printf("%16s %16s %3s %8s %s\n", "PROCESSES", "SYSCALL", "ERR", "COUNT", "PATH"); printa("%16s %16s %3d %@8d %s\n", @); } ================================================ FILE: Chap5/fsflush.d ================================================ #!/usr/sbin/dtrace -s /* * fsflush.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet BEGIN { lexam = 0; lscan = 0; llock = 0; lmod = 0; lcoal = 0; lrel = 0; ltime = 0; printf("%10s %10s %10s %10s %10s %10s %10s\n", "SCANNED", "EXAMINED", "LOCKED", "MODIFIED", "COALESCE", "RELEASES", "TIME(ns)"); } tick-1s /lexam/ { printf("%10d %10d %10d %10d %10d %10d %10d\n", `fsf_total.fsf_scan, `fsf_total.fsf_examined - lexam, `fsf_total.fsf_locked - llock, `fsf_total.fsf_modified - lmod, `fsf_total.fsf_coalesce - lcoal, `fsf_total.fsf_releases - lrel, `fsf_total.fsf_time - ltime); lexam = `fsf_total.fsf_examined; lscan = `fsf_total.fsf_scan; llock = `fsf_total.fsf_locked; lmod = `fsf_total.fsf_modified; lcoal = `fsf_total.fsf_coalesce; lrel = `fsf_total.fsf_releases; ltime = `fsf_total.fsf_time; } /* * First time through */ tick-1s /!lexam/ { lexam = `fsf_total.fsf_examined; lscan = `fsf_total.fsf_scan; llock = `fsf_total.fsf_locked; lmod = `fsf_total.fsf_modified; lcoal = `fsf_total.fsf_coalesce; ltime = `fsf_total.fsf_time; lrel = `fsf_total.fsf_releases; } ================================================ FILE: Chap5/fsflush_cpu.d ================================================ #!/usr/sbin/dtrace -s /* * fsflush_cpu.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing fsflush...\n"); @fopbytes = sum(0); @iobytes = sum(0); } fbt::fsflush_do_pages:entry { self->vstart = vtimestamp; } fbt::fop_putpage:entry /self->vstart/ { @fopbytes = sum(arg2); } io:::start /self->vstart/ { @iobytes = sum(args[0]->b_bcount); @ionum = count(); } fbt::fsflush_do_pages:return /self->vstart/ { normalize(@fopbytes, 1024); normalize(@iobytes, 1024); this->delta = (vtimestamp - self->vstart) / 1000000; printf("%Y %4d ms, ", walltimestamp, this->delta); printa("fop: %7@d KB, ", @fopbytes); printa("device: %7@d KB ", @iobytes); printa("%5@d I/O", @ionum); printf("\n"); self->vstart = 0; clear(@fopbytes); clear(@iobytes); clear(@ionum); } ================================================ FILE: Chap5/fsrtpk.d ================================================ #!/usr/sbin/dtrace -Zs /* * fsrtpk.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ /* trace read() variants, but not readlink() or __pthread*() (macosx) */ syscall::read:entry, syscall::readv:entry, syscall::pread*:entry, syscall::*read*nocancel:entry { self->fd = arg0; self->start = timestamp; } syscall::*read*:return /self->start && arg0 > 0/ { this->kb = (arg1 / 1024) ? arg1 / 1024 : 1; this->ns_per_kb = (timestamp - self->start) / this->kb; @[fds[self->fd].fi_fs, probefunc, fds[self->fd].fi_mount] = quantize(this->ns_per_kb); } syscall::*read*:return { self->fd = 0; self->start = 0; } dtrace:::END { printa("\n %s %s (ns per kb) \t%s%@d", @); } ================================================ FILE: Chap5/fsrwcount.d ================================================ #!/usr/sbin/dtrace -Zs /* * fsrwcount.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } /* trace read() variants, but not readlink() or __pthread*() (macosx) */ syscall::read:entry, syscall::readv:entry, syscall::pread*:entry, syscall::*read*nocancel:entry, syscall::*write*:entry { @[fds[arg0].fi_fs, probefunc, fds[arg0].fi_mount] = count(); } dtrace:::END { printf(" %-9s %-16s %-40s %7s\n", "FS", "SYSCALL", "MOUNTPOINT", "COUNT"); printa(" %-9.9s %-16s %-40s %@7d\n", @); } ================================================ FILE: Chap5/fsrwtime.d ================================================ #!/usr/sbin/dtrace -Zs /* * fsrwtime.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ /* trace read() variants, but not readlink() or __pthread*() (macosx) */ syscall::read:entry, syscall::readv:entry, syscall::pread*:entry, syscall::*read*nocancel:entry, syscall::*write*:entry { self->fd = arg0; self->start = timestamp; } syscall::*read*:return, syscall::*write*:return /self->start/ { this->delta = (timestamp - self->start) / 1000; @[fds[self->fd].fi_fs, probefunc, fds[self->fd].fi_mount] = quantize(this->delta); self->fd = 0; self->start = 0; } dtrace:::END { printa("\n %s %s (us) \t%s%@d", @); } ================================================ FILE: Chap5/fssnoop.d ================================================ #!/usr/sbin/dtrace -s /* * fssnoop.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option defaultargs #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-12s %6s %6s %-12.12s %-12s %-6s %s\n", "TIME(ms)", "UID", "PID", "PROCESS", "CALL", "BYTES", "PATH"); } fsinfo::: /execname != "dtrace" && ($$1 == NULL || $$1 == execname)/ { printf("%-12d %6d %6d %-12.12s %-12s %-6d %s\n", timestamp / 1000000, uid, pid, execname, probename, arg1, args[0]->fi_pathname); } ================================================ FILE: Chap5/fswho.d ================================================ #!/usr/sbin/dtrace -s /* * fswho.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } fsinfo:::read, fsinfo:::write { @[execname, probename == "read" ? "R" : "W", args[0]->fi_fs, args[0]->fi_mount] = sum(arg1); } dtrace:::END { normalize(@, 1024); printf(" %-16s %1s %12s %-10s %s\n", "PROCESSES", "D", "KBYTES", "FS", "MOUNTPOINT"); printa(" %-16s %1.1s %@12d %-10s %s\n", @); } ================================================ FILE: Chap5/hfsfileread.d ================================================ #!/usr/sbin/dtrace -s /* * hfsfileread.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing HFS+ file reads... Hit Ctrl-C to end.\n"); } fbt::hfs_vnop_read:entry { this->read = (struct vnop_read_args *)arg0; this->path = this->read->a_vp->v_name; this->bytes = this->read->a_uio->uio_resid_64; @r[this->path ? stringof(this->path) : ""] = sum(this->bytes); } fbt::hfs_vnop_strategy:entry /((struct vnop_strategy_args *)arg0)->a_bp->b_flags & B_READ/ { this->strategy = (struct vnop_strategy_args *)arg0; this->path = this->strategy->a_bp->b_vp->v_name; this->bytes = this->strategy->a_bp->b_bcount; @s[this->path ? stringof(this->path) : ""] = sum(this->bytes); } dtrace:::END { printf(" %-56s %10s %10s\n", "FILE", "READ(B)", "DISK(B)"); printa(" %-56s %@10d %@10d\n", @r, @s); } ================================================ FILE: Chap5/hfsslower.d ================================================ #!/usr/sbin/dtrace -s /* * hfsslower.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option defaultargs #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-20s %-16s %1s %4s %6s %s\n", "TIME", "PROCESS", "D", "KB", "ms", "FILE"); min_ns = $1 * 1000000; } /* see bsd/hfs/hfs_vnops.c */ fbt::hfs_vnop_read:entry { this->read = (struct vnop_read_args *)arg0; self->path = this->read->a_vp->v_name; self->kb = this->read->a_uio->uio_resid_64 / 1024; self->start = timestamp; } fbt::hfs_vnop_write:entry { this->write = (struct vnop_write_args *)arg0; self->path = this->write->a_vp->v_name; self->kb = this->write->a_uio->uio_resid_64 / 1024; self->start = timestamp; } fbt::hfs_vnop_read:return, fbt::hfs_vnop_write:return /self->start && (timestamp - self->start) >= min_ns/ { this->iotime = (timestamp - self->start) / 1000000; this->dir = probefunc == "hfs_vnop_read" ? "R" : "W"; printf("%-20Y %-16s %1s %4d %6d %s\n", walltimestamp, execname, this->dir, self->kb, this->iotime, self->path != NULL ? stringof(self->path) : ""); } fbt::hfs_vnop_read:return, fbt::hfs_vnop_write:return { self->path = 0; self->kb = 0; self->start = 0; } ================================================ FILE: Chap5/hfssnoop.d ================================================ #!/usr/sbin/dtrace -s /* * hfssnoop.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-12s %6s %6s %-12.12s %-14s %-4s %s\n", "TIME(ms)", "UID", "PID", "PROCESS", "CALL", "KB", "FILE"); } /* see bsd/hfs/hfs_vnops.c */ fbt::hfs_vnop_read:entry { this->read = (struct vnop_read_args *)arg0; self->path = this->read->a_vp->v_name; self->kb = this->read->a_uio->uio_resid_64 / 1024; } fbt::hfs_vnop_write:entry { this->write = (struct vnop_write_args *)arg0; self->path = this->write->a_vp->v_name; self->kb = this->write->a_uio->uio_resid_64 / 1024; } fbt::hfs_vnop_read:entry, fbt::hfs_vnop_write:entry { printf("%-12d %6d %6d %-12.12s %-14s %-4d %s\n", timestamp / 1000000, uid, pid, execname, probefunc, self->kb, self->path != NULL ? stringof(self->path) : ""); self->path = 0; self->kb = 0; } ================================================ FILE: Chap5/maclife.d ================================================ #!/usr/sbin/dtrace -s /* * maclife.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-12s %6s %6s %-12.12s %-12s %s\n", "TIME(ms)", "UID", "PID", "PROCESS", "CALL", "DIR/FILE"); } /* see sys/bsd/sys/vnode_if.h */ fbt::VNOP_CREATE:entry, fbt::VNOP_REMOVE:entry { this->path = ((struct vnode *)arg0)->v_name; this->name = ((struct componentname *)arg2)->cn_nameptr; printf("%-12d %6d %6d %-12.12s %-12s %s/%s\n", timestamp / 1000000, uid, pid, execname, probefunc, this->path != NULL ? stringof(this->path) : "", stringof(this->name)); } ================================================ FILE: Chap5/macvfssnoop.d ================================================ #!/usr/sbin/dtrace -s /* * macvfssnoop.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option defaultargs #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-12s %6s %6s %-12.12s %-12s %-4s %s\n", "TIME(ms)", "UID", "PID", "PROCESS", "CALL", "KB", "PATH"); } /* see sys/bsd/sys/vnode_if.h */ fbt::VNOP_READ:entry, fbt::VNOP_WRITE:entry { self->path = ((struct vnode *)arg0)->v_name; self->kb = ((struct uio *)arg1)->uio_resid_64 / 1024; } fbt::VNOP_OPEN:entry { self->path = ((struct vnode *)arg0)->v_name; self->kb = 0; } fbt::VNOP_CLOSE:entry, fbt::VNOP_IOCTL:entry, fbt::VNOP_GETATTR:entry, fbt::VNOP_READDIR:entry { self->path = ((struct vnode *)arg0)->v_name; self->kb = 0; } fbt::VNOP_READ:entry, fbt::VNOP_WRITE:entry, fbt::VNOP_OPEN:entry, fbt::VNOP_CLOSE:entry, fbt::VNOP_IOCTL:entry, fbt::VNOP_GETATTR:entry, fbt::VNOP_READDIR:entry /execname != "dtrace" && ($$1 == NULL || $$1 == execname)/ { printf("%-12d %6d %6d %-12.12s %-12s %-4d %s\n", timestamp / 1000000, uid, pid, execname, probefunc, self->kb, self->path != NULL ? stringof(self->path) : ""); } fbt::VNOP_READ:entry, fbt::VNOP_WRITE:entry, fbt::VNOP_OPEN:entry, fbt::VNOP_CLOSE:entry, fbt::VNOP_IOCTL:entry, fbt::VNOP_GETATTR:entry, fbt::VNOP_READDIR:entry { self->path = 0; self->kb = 0; } ================================================ FILE: Chap5/mmap.d ================================================ #!/usr/sbin/dtrace -Cs /* * mmap.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #include #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%6s %-12s %-4s %-8s %-8s %-8s %s\n", "PID", "PROCESS", "PROT", "FLAGS", "OFFS(KB)", "SIZE(KB)", "PATH"); } syscall::mmap*:entry /fds[arg4].fi_pathname != ""/ { /* see mmap(2) and /usr/include/sys/mman.h */ printf("%6d %-12.12s %s%s%s %s%s%s%s%s%s%s%s %-8d %-8d %s\n", pid, execname, arg2 & PROT_EXEC ? "E" : "-", /* pages can be executed */ arg2 & PROT_WRITE ? "W" : "-", /* pages can be written */ arg2 & PROT_READ ? "R" : "-", /* pages can be read */ arg3 & MAP_INITDATA ? "I" : "-", /* map data segment */ arg3 & MAP_TEXT ? "T" : "-", /* map code segment */ arg3 & MAP_ALIGN ? "L" : "-", /* addr specifies alignment */ arg3 & MAP_ANON ? "A" : "-", /* map anon pages directly */ arg3 & MAP_NORESERVE ? "N" : "-", /* don't reserve swap area */ arg3 & MAP_FIXED ? "F" : "-", /* user assigns address */ arg3 & MAP_PRIVATE ? "P" : "-", /* changes are private */ arg3 & MAP_SHARED ? "S" : "-", /* share changes */ arg5 / 1024, arg1 / 1024, fds[arg4].fi_pathname); } ================================================ FILE: Chap5/nfs3fileread.d ================================================ #!/usr/sbin/dtrace -s /* * nfs3fileread.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing NFSv3 client file reads... Hit Ctrl-C to end.\n"); } fbt::nfs3_read:entry { this->path = args[0]->v_path; this->bytes = args[1]->uio_resid; @r[this->path ? stringof(this->path) : ""] = sum(this->bytes); } fbt::nfs3_directio_read:entry { this->path = args[0]->v_path; this->bytes = args[1]->uio_resid; @n[this->path ? stringof(this->path) : ""] = sum(this->bytes); } fbt::nfs3_getpage:entry { this->path = args[0]->v_path; this->bytes = arg2; @n[this->path ? stringof(this->path) : ""] = sum(this->bytes); } dtrace:::END { printf(" %-56s %10s %10s\n", "FILE", "READ(B)", "NET(B)"); printa(" %-56s %@10d %@10d\n", @r, @n); } ================================================ FILE: Chap5/nfs3sizes.d ================================================ #!/usr/sbin/dtrace -s /* * nfs3sizes.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing NFSv3 client file reads... Hit Ctrl-C to end.\n"); } fbt::nfs3_read:entry { @q["NFS read size (bytes)"] = quantize(args[1]->uio_resid); @s["NFS read (bytes)"] = sum(args[1]->uio_resid); } fbt::nfs3_directio_read:entry { @q["NFS network read size (bytes)"] = quantize(args[1]->uio_resid); @s["NFS network read (bytes)"] = sum(args[1]->uio_resid); } fbt::nfs3_getpage:entry { @q["NFS network read size (bytes)"] = quantize(arg2); @s["NFS network read (bytes)"] = sum(arg2); } ================================================ FILE: Chap5/nfswizard.d ================================================ #!/usr/sbin/dtrace -s /* * nfswizard.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); scriptstart = walltimestamp; timestart = timestamp; } io:nfs::start { /* tally file sizes */ @file[args[2]->fi_pathname] = sum(args[0]->b_bcount); /* time response */ start[args[0]->b_addr] = timestamp; /* overall stats */ @rbytes = sum(args[0]->b_flags & B_READ ? args[0]->b_bcount : 0); @wbytes = sum(args[0]->b_flags & B_READ ? 0 : args[0]->b_bcount); @events = count(); } io:nfs::done /start[args[0]->b_addr]/ { /* calculate and save response time stats */ this->elapsed = timestamp - start[args[0]->b_addr]; @maxtime = max(this->elapsed); @avgtime = avg(this->elapsed); @qnztime = quantize(this->elapsed / 1000); } dtrace:::END { /* print header */ printf("NFS Client Wizard. %Y -> %Y\n\n", scriptstart, walltimestamp); /* print read/write stats */ printa("Read: %@d bytes ", @rbytes); normalize(@rbytes, 1000000); printa("(%@d Mb)\n", @rbytes); printa("Write: %@d bytes ", @wbytes); normalize(@wbytes, 1000000); printa("(%@d Mb)\n\n", @wbytes); /* print throughput stats */ denormalize(@rbytes); normalize(@rbytes, (timestamp - timestart) / 1000000); printa("Read: %@d Kb/sec\n", @rbytes); denormalize(@wbytes); normalize(@wbytes, (timestamp - timestart) / 1000000); printa("Write: %@d Kb/sec\n\n", @wbytes); /* print time stats */ printa("NFS I/O events: %@d\n", @events); normalize(@avgtime, 1000000); printa("Avg response time: %@d ms\n", @avgtime); normalize(@maxtime, 1000000); printa("Max response time: %@d ms\n\n", @maxtime); printa("Response times (us):%@d\n", @qnztime); /* print file stats */ printf("Top 25 files accessed (bytes):\n"); printf(" %-64s %s\n", "PATHNAME", "BYTES"); trunc(@file, 25); printa(" %-64s %@d\n", @file); } ================================================ FILE: Chap5/pcfsrw.d ================================================ #!/usr/sbin/dtrace -s /* * pcfsrw.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-20s %1s %4s %6s %3s %s\n", "TIME", "D", "KB", "ms", "ERR", "PATH"); } fbt::pcfs_read:entry, fbt::pcfs_write:entry, fbt::pcfs_readdir:entry { self->path = args[0]->v_path; self->kb = args[1]->uio_resid / 1024; self->start = timestamp; } fbt::pcfs_read:return, fbt::pcfs_write:return, fbt::pcfs_readdir:return /self->start/ { this->iotime = (timestamp - self->start) / 1000000; this->dir = probefunc == "pcfs_read" ? "R" : "W"; printf("%-20Y %1s %4d %6d %3d %s\n", walltimestamp, this->dir, self->kb, this->iotime, arg1, self->path != NULL ? stringof(self->path) : ""); self->start = 0; self->path = 0; self->kb = 0; } ================================================ FILE: Chap5/perturbation.d ================================================ #!/usr/sbin/dtrace -s /* * perturbation.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option defaultargs dtrace:::BEGIN { printf("Tracing ZFS perturbation by %s()... Ctrl-C to end.\n", $$1); } fbt::$$1:entry { self->pstart = timestamp; perturbation = 1; } fbt::$$1:return /self->pstart/ { this->ptime = (timestamp - self->pstart) / 1000000; @[probefunc, "perturbation duration (ms)"] = quantize(this->ptime); perturbation = 0; } fbt::zfs_read:entry, fbt::zfs_write:entry { self->start = timestamp; } fbt::zfs_read:return, fbt::zfs_write:return /self->start/ { this->iotime = (timestamp - self->start) / 1000000; @[probefunc, perturbation ? "during perturbation (ms)" : "normal (ms)"] = quantize(this->iotime); self->start = 0; } ================================================ FILE: Chap5/readtype.d ================================================ #!/usr/sbin/dtrace -s /* * readtype.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet inline int TOP = 20; self int trace; uint64_t lbytes; uint64_t pbytes; dtrace:::BEGIN { trace("Tracing... Output every 5 secs, or Ctrl-C.\n"); } fsinfo:::read { @io[args[0]->fi_mount, "logical"] = count(); @bytes[args[0]->fi_mount, "logical"] = sum(arg1); lbytes += arg1; } io:::start /args[0]->b_flags & B_READ/ { @io[args[2]->fi_mount, "physical"] = count(); @bytes[args[2]->fi_mount, "physical"] = sum(args[0]->b_bcount); pbytes += args[0]->b_bcount; } profile:::tick-5s, dtrace:::END { trunc(@io, TOP); trunc(@bytes, TOP); printf("\n%Y:\n", walltimestamp); printf("\n Read I/O (top %d)\n", TOP); printa(" %-32s %10s %10@d\n", @io); printf("\n Read Bytes (top %d)\n", TOP); printa(" %-32s %10s %10@d\n", @bytes); printf("\nphysical/logical bytes rate: %d%%\n", lbytes ? 100 * pbytes / lbytes : 0); trunc(@bytes); trunc(@io); lbytes = pbytes = 0; } ================================================ FILE: Chap5/sollife.d ================================================ #!/usr/sbin/dtrace -s /* * sollife.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-12s %6s %6s %-12.12s %-12s %s\n", "TIME(ms)", "UID", "PID", "PROCESS", "CALL", "PATH"); } /* see /usr/include/sys/vnode.h */ fbt::fop_create:entry, fbt::fop_remove:entry { printf("%-12d %6d %6d %-12.12s %-12s %s/%s\n", timestamp / 1000000, uid, pid, execname, probefunc, args[0]->v_path != NULL ? stringof(args[0]->v_path) : "", stringof(arg1)); } ================================================ FILE: Chap5/solvfssnoop.d ================================================ #!/usr/sbin/dtrace -s /* * solvfssnoop.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option defaultargs #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-12s %6s %6s %-12.12s %-12s %-4s %s\n", "TIME(ms)", "UID", "PID", "PROCESS", "CALL", "KB", "PATH"); } /* see /usr/include/sys/vnode.h */ fbt::fop_read:entry, fbt::fop_write:entry { self->path = args[0]->v_path; self->kb = args[1]->uio_resid / 1024; } fbt::fop_open:entry { self->path = (*args[0])->v_path; self->kb = 0; } fbt::fop_close:entry, fbt::fop_ioctl:entry, fbt::fop_getattr:entry, fbt::fop_readdir:entry { self->path = args[0]->v_path; self->kb = 0; } fbt::fop_read:entry, fbt::fop_write:entry, fbt::fop_open:entry, fbt::fop_close:entry, fbt::fop_ioctl:entry, fbt::fop_getattr:entry, fbt::fop_readdir:entry /execname != "dtrace" && ($$1 == NULL || $$1 == execname)/ { printf("%-12d %6d %6d %-12.12s %-12s %-4d %s\n", timestamp / 1000000, uid, pid, execname, probefunc, self->kb, self->path != NULL ? stringof(self->path) : ""); } fbt::fop_read:entry, fbt::fop_write:entry, fbt::fop_open:entry, fbt::fop_close:entry, fbt::fop_ioctl:entry, fbt::fop_getattr:entry, fbt::fop_readdir:entry { self->path = 0; self->kb = 0; } ================================================ FILE: Chap5/spasync.d ================================================ #!/usr/sbin/dtrace -s /* * spasync.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet inline int MIN_MS = 1; dtrace:::BEGIN { printf("Tracing ZFS spa_sync() slower than %d ms...\n", MIN_MS); @bytes = sum(0); } fbt::spa_sync:entry /!self->start/ { in_spa_sync = 1; self->start = timestamp; self->spa = args[0]; } io:::start /in_spa_sync/ { @io = count(); @bytes = sum(args[0]->b_bcount); } fbt::spa_sync:return /self->start && (this->ms = (timestamp - self->start) / 1000000) > MIN_MS/ { normalize(@bytes, 1048576); printf("%-20Y %-10s %6d ms, ", walltimestamp, stringof(self->spa->spa_name), this->ms); printa("%@d MB %@d I/O\n", @bytes, @io); } fbt::spa_sync:return { self->start = 0; self->spa = 0; in_spa_sync = 0; clear(@bytes); clear(@io); } ================================================ FILE: Chap5/sysfs.d ================================================ #!/usr/sbin/dtrace -Zs /* * sysfs.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } /* trace read() variants, but not readlink() or __pthread*() (macosx) */ syscall::read:entry, syscall::readv:entry, syscall::pread*:entry, syscall::*read*nocancel:entry, syscall::*write*:entry { @[execname, probefunc, fds[arg0].fi_mount] = count(); } dtrace:::END { printf(" %-16s %-16s %-30s %7s\n", "PROCESS", "SYSCALL", "MOUNTPOINT", "COUNT"); printa(" %-16s %-16s %-30s %@7d\n", @); } ================================================ FILE: Chap5/tmpgetpage.d ================================================ #!/usr/sbin/dtrace -s /* * tmpgetpage.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing tmpfs disk read time (us):\n"); } fbt::tmp_getpage:entry { self->vp = args[0]; self->start = timestamp; } fbt::tmp_getpage:return /self->start/ { @[execname, stringof(self->vp->v_path)] = quantize((timestamp - self->start) / 1000); self->vp = 0; self->start = 0; } ================================================ FILE: Chap5/tmpusers.d ================================================ #!/usr/sbin/dtrace -s /* * tmpusers.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("%6s %6s %-16s %s\n", "UID", "PID", "PROCESS", "FILE"); } fbt::tmp_open:entry { printf("%6d %6d %-16s %s\n", uid, pid, execname, stringof((*args[0])->v_path)); } ================================================ FILE: Chap5/ufsimiss.d ================================================ #!/usr/sbin/dtrace -s /* * ufsimiss.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%6s %-16s %s\n", "PID", "PROCESS", "INODE MISS PATH"); } fbt::ufs_lookup:entry { self->dvp = args[0]; self->name = arg1; } fbt::ufs_lookup:return { self->dvp = 0; self->name = 0; } fbt::ufs_alloc_inode:entry /self->dvp && self->name/ { printf("%6d %-16s %s/%s\n", pid, execname, stringof(self->dvp->v_path), stringof(self->name)); } ================================================ FILE: Chap5/ufsreadahead.d ================================================ #!/usr/sbin/dtrace -s /* * ufsreadahead.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ fbt::ufs_getpage:entry { @["UFS read (bytes)"] = sum(arg2); } fbt::ufs_getpage_ra:return { @["UFS read ahead (bytes)"] = sum(arg1); } ================================================ FILE: Chap5/ufssnoop.d ================================================ #!/usr/sbin/dtrace -Zs /* * ufssnoop.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-12s %6s %6s %-12.12s %-12s %-4s %s\n", "TIME(ms)", "UID", "PID", "PROCESS", "CALL", "KB", "PATH"); } /* see uts/common/fs/ufs/ufs_vnops.c */ fbt::ufs_read:entry, fbt::ufs_write:entry { self->path = args[0]->v_path; self->kb = args[1]->uio_resid / 1024; } fbt::ufs_open:entry { self->path = (*(struct vnode **)arg0)->v_path; self->kb = 0; } fbt::ufs_close:entry, fbt::ufs_ioctl:entry, fbt::ufs_getattr:entry, fbt::ufs_readdir:entry { self->path = args[0]->v_path; self->kb = 0; } fbt::ufs_read:entry, fbt::ufs_write:entry, fbt::ufs_open:entry, fbt::ufs_close:entry, fbt::ufs_ioctl:entry, fbt::ufs_getattr:entry, fbt::ufs_readdir:entry { printf("%-12d %6d %6d %-12.12s %-12s %-4d %s\n", timestamp / 1000000, uid, pid, execname, probefunc, self->kb, self->path != NULL ? stringof(self->path) : ""); self->path = 0; self->kb = 0; } ================================================ FILE: Chap5/vfslife.d ================================================ #!/usr/sbin/dtrace -s /* * vfslife.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-12s %6s %6s %-12.12s %-12s %s\n", "TIME(ms)", "UID", "PID", "PROCESS", "CALL", "DIR/FILE"); } /* see sys/bsd/sys/vnode_if.h */ vfs::vop_create:entry, vfs::vop_remove:entry { this->dir = args[0]->v_cache_dd != NULL ? stringof(args[0]->v_cache_dd->nc_name) : ""; this->name = args[1]->a_cnp->cn_nameptr != NULL ? stringof(args[1]->a_cnp->cn_nameptr) : ""; printf("%-12d %6d %6d %-12.12s %-12s %s/%s\n", timestamp / 1000000, uid, pid, execname, probefunc, this->dir, this->name); } ================================================ FILE: Chap5/vfssnoop.d ================================================ #!/usr/sbin/dtrace -s /* * vfssnoop.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option defaultargs #pragma D option switchrate=10hz #pragma D option dynvarsize=4m dtrace:::BEGIN { printf("%-12s %6s %6s %-12.12s %-12s %-4s %s\n", "TIME(ms)", "UID", "PID", "PROCESS", "CALL", "KB", "PATH/FILE"); } /* * Populate Vnode2Path from namecache hits */ vfs:namecache:lookup:hit /V2P[arg2] == NULL/ { V2P[arg2] = stringof(arg1); } /* * (Re)populate Vnode2Path from successful namei() lookups */ vfs:namei:lookup:entry { self->buf = arg1; } vfs:namei:lookup:return /self->buf != NULL && arg0 == 0/ { V2P[arg1] = stringof(self->buf); } vfs:namei:lookup:return { self->buf = 0; } /* * Trace and print VFS calls */ vfs::vop_read:entry, vfs::vop_write:entry { self->path = V2P[arg0]; self->kb = args[1]->a_uio->uio_resid / 1024; } vfs::vop_open:entry, vfs::vop_close:entry, vfs::vop_ioctl:entry, vfs::vop_getattr:entry, vfs::vop_readdir:entry { self->path = V2P[arg0]; self->kb = 0; } vfs::vop_read:entry, vfs::vop_write:entry, vfs::vop_open:entry, vfs::vop_close:entry, vfs::vop_ioctl:entry, vfs::vop_getattr:entry, vfs::vop_readdir:entry /execname != "dtrace" && ($$1 == NULL || $$1 == execname)/ { printf("%-12d %6d %6d %-12.12s %-12s %-4d %s\n", timestamp / 1000000, uid, pid, execname, probefunc, self->kb, self->path != NULL ? self->path : ""); } vfs::vop_read:entry, vfs::vop_write:entry, vfs::vop_open:entry, vfs::vop_close:entry, vfs::vop_ioctl:entry, vfs::vop_getattr:entry, vfs::vop_readdir:entry { self->path = 0; self->kb = 0; } /* * Tidy V2P, otherwise it gets too big (dynvardrops) */ vfs:namecache:purge:done, vfs::vop_close:entry { V2P[arg0] = 0; } ================================================ FILE: Chap5/writetype.d ================================================ #!/usr/sbin/dtrace -s /* * writetype.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet inline int TOP = 20; self int trace; uint64_t lbytes; uint64_t pbytes; dtrace:::BEGIN { trace("Tracing... Output every 5 secs, or Ctrl-C.\n"); } fsinfo:::write { @io[args[0]->fi_mount, "logical"] = count(); @bytes[args[0]->fi_mount, "logical"] = sum(arg1); lbytes += arg1; } io:::start /!args[0]->b_flags & B_READ/ { @io[args[2]->fi_mount, "physical"] = count(); @bytes[args[2]->fi_mount, "physical"] = sum(args[0]->b_bcount); pbytes += args[0]->b_bcount; } profile:::tick-5s, dtrace:::END { trunc(@io, TOP); trunc(@bytes, TOP); printf("\n%Y:\n", walltimestamp); printf("\n Write I/O (top %d)\n", TOP); printa(" %-32s %10s %10@d\n", @io); printf("\n Write Bytes (top %d)\n", TOP); printa(" %-32s %10s %10@d\n", @bytes); printf("\nphysical/logical bytes rate: %d%%\n", lbytes ? 100 * pbytes / lbytes : 0); trunc(@bytes); trunc(@io); lbytes = pbytes = 0; } ================================================ FILE: Chap5/zfsslower.d ================================================ #!/usr/sbin/dtrace -s /* * zfsslower.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option defaultargs #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-20s %-16s %1s %4s %6s %s\n", "TIME", "PROCESS", "D", "KB", "ms", "FILE"); min_ns = $1 * 1000000; } /* see uts/common/fs/zfs/zfs_vnops.c */ fbt::zfs_read:entry, fbt::zfs_write:entry { self->path = args[0]->v_path; self->kb = args[1]->uio_resid / 1024; self->start = timestamp; } fbt::zfs_read:return, fbt::zfs_write:return /self->start && (timestamp - self->start) >= min_ns/ { this->iotime = (timestamp - self->start) / 1000000; this->dir = probefunc == "zfs_read" ? "R" : "W"; printf("%-20Y %-16s %1s %4d %6d %s\n", walltimestamp, execname, this->dir, self->kb, this->iotime, self->path != NULL ? stringof(self->path) : ""); } fbt::zfs_read:return, fbt::zfs_write:return { self->path = 0; self->kb = 0; self->start = 0; } ================================================ FILE: Chap5/zfssnoop.d ================================================ #!/usr/sbin/dtrace -s /* * zfssnoop.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-12s %6s %6s %-12.12s %-12s %-4s %s\n", "TIME(ms)", "UID", "PID", "PROCESS", "CALL", "KB", "PATH"); } /* see uts/common/fs/zfs/zfs_vnops.c */ fbt::zfs_read:entry, fbt::zfs_write:entry { self->path = args[0]->v_path; self->kb = args[1]->uio_resid / 1024; } fbt::zfs_open:entry { self->path = (*args[0])->v_path; self->kb = 0; } fbt::zfs_close:entry, fbt::zfs_ioctl:entry, fbt::zfs_getattr:entry, fbt::zfs_readdir:entry { self->path = args[0]->v_path; self->kb = 0; } fbt::zfs_read:entry, fbt::zfs_write:entry, fbt::zfs_open:entry, fbt::zfs_close:entry, fbt::zfs_ioctl:entry, fbt::zfs_getattr:entry, fbt::zfs_readdir:entry { printf("%-12d %6d %6d %-12.12s %-12s %-4d %s\n", timestamp / 1000000, uid, pid, execname, probefunc, self->kb, self->path != NULL ? stringof(self->path) : ""); self->path = 0; self->kb = 0; } ================================================ FILE: Chap5/zioprint.d ================================================ #!/usr/sbin/dtrace -s /* * zioprint.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-16s %-3s %-22s %-6s %s\n", "TIME(us)", "CPU", "FUNC", "NAME", "ARGS"); } fbt::zio_*:entry { printf("%-16d %-3d %-22s %-6s %x %x %x %x %x\n", timestamp / 1000, cpu, probefunc, probename, arg0, arg1, arg2, arg3, arg4); } fbt::zio_*:return { printf("%-16d %-3d %-22s %-6s %x %x\n", timestamp / 1000, cpu, probefunc, probename, arg0, arg1); } ================================================ FILE: Chap5/ziosnoop.d ================================================ #!/usr/sbin/dtrace -s /* * ziosnoop.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option defaultargs #pragma D option switchrate=10hz dtrace:::BEGIN { start = timestamp; printf("%-10s %-3s %-12s %-16s %s\n", "TIME(us)", "CPU", "ZIO_EVENT", "ARG0", "INFO (see script)"); } fbt::zfs_read:entry, fbt::zfs_write:entry { self->vp = args[0]; } fbt::zfs_read:return, fbt::zfs_write:return { self->vp = 0; } fbt::zio_create:return /$1 || args[1]->io_type/ { /* INFO: pool zio_type zio_flag bytes path */ printf("%-10d %-3d %-12s %-16x %s %d %x %d %s\n", (timestamp - start) / 1000, cpu, "CREATED", arg1, stringof(args[1]->io_spa->spa_name), args[1]->io_type, args[1]->io_flags, args[1]->io_size, self->vp && self->vp->v_path ? stringof(self->vp->v_path) : ""); } fbt::zio_*:entry /$1/ { printf("%-10d %-3d %-12s %-16x\n", (timestamp - start) / 1000, cpu, probefunc, arg0); } fbt::zio_done:entry /$1 || args[0]->io_type/ { /* INFO: io_error vdev_state vdev_path */ printf("%-10d %-3d %-12s %-16x %d %d %s\n", (timestamp - start) / 1000, cpu, "DONE", arg0, args[0]->io_error, args[0]->io_vd ? args[0]->io_vd->vdev_state : 0, args[0]->io_vd && args[0]->io_vd->vdev_path ? stringof(args[0]->io_vd->vdev_path) : ""); } ================================================ FILE: Chap5/ziotype.d ================================================ #!/usr/sbin/dtrace -s /* * ziotype.d * * Example script from Chapter 5 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { /* see /usr/include/sys/fs/zfs.h */ ziotype[0] = "null"; ziotype[1] = "read"; ziotype[2] = "write"; ziotype[3] = "free"; ziotype[4] = "claim"; ziotype[5] = "ioctl"; trace("Tracing ZIO... Output interval 5 seconds, or Ctrl-C.\n"); } fbt::zio_create:return /args[1]->io_type/ /* skip null */ { @[stringof(args[1]->io_spa->spa_name), ziotype[args[1]->io_type] != NULL ? ziotype[args[1]->io_type] : "?"] = count(); } profile:::tick-5sec, dtrace:::END { printf("\n %-32s %-10s %10s\n", "POOL", "ZIO_TYPE", "CREATED"); printa(" %-32s %-10s %@10d\n", @); trunc(@); } ================================================ FILE: Chap6/icmpsnoop.d ================================================ #!/usr/sbin/dtrace -Cs /* * icmpsnoop.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz #define IPPROTO_ICMP 1 #define IPH_HDR_LENGTH(iph) (((struct ip *)(iph))->ip_hl << 2) dtrace:::BEGIN { /* See RFC792 and ip_icmp.h */ icmptype[0] = "ECHOREPLY"; icmptype[3] = "UNREACH"; icmpcode[3, 0] = "NET"; icmpcode[3, 1] = "HOST"; icmpcode[3, 2] = "PROTOCOL"; icmpcode[3, 3] = "PORT"; icmpcode[3, 4] = "NEEDFRAG"; icmpcode[3, 5] = "SRCFAIL"; icmpcode[3, 6] = "NET_UNKNOWN"; icmpcode[3, 7] = "HOST_UNKNOWN"; icmpcode[3, 8] = "ISOLATED"; icmpcode[3, 9] = "NET_PROHIB"; icmpcode[3, 10] = "HOST_PROHIB"; icmpcode[3, 11] = "TOSNET"; icmpcode[3, 12] = "TOSHOST"; icmpcode[3, 13] = "FILTER_PROHIB"; icmpcode[3, 14] = "HOST_PRECEDENCE"; icmpcode[3, 15] = "PRECEDENCE_CUTOFF"; icmptype[4] = "SOURCEQUENCH"; icmptype[5] = "REDIRECT"; icmpcode[5, 0] = "NET"; icmpcode[5, 0] = "HOST"; icmpcode[5, 0] = "TOSNET"; icmpcode[5, 0] = "TOSHOST"; icmptype[8] = "ECHO"; icmptype[9] = "ROUTERADVERT"; icmpcode[9, 0] = "COMMON"; icmpcode[9, 16] = "NOCOMMON"; icmptype[10] = "ROUTERSOLICIT"; icmptype[11] = "TIMXCEED"; icmpcode[11, 0] = "INTRANS"; icmpcode[11, 1] = "REASS"; icmptype[12] = "PARAMPROB"; icmpcode[12, 1] = "OPTABSENT"; icmpcode[12, 2] = "BADLENGTH"; icmptype[13] = "TSTAMP"; icmptype[14] = "TSTAMPREPLY"; icmptype[15] = "IREQ"; icmptype[16] = "IREQREPLY"; icmptype[17] = "MASKREQ"; icmptype[18] = "MASKREPLY"; printf("%-20s %-12s %1s %-15s %-15s %s\n", "TIME", "PROCESS", "D", "REMOTE", "TYPE", "CODE"); } fbt::icmp_inbound:entry { this->mp = args[1]; this->ipha = (ipha_t *)this->mp->b_rptr; /* stringify manually if inet_ntoa() unavailable */ this->addr = inet_ntoa(&this->ipha->ipha_src); this->dir = "<"; } fbt::ip_xmit_v4:entry /arg4 && args[4]->conn_ulp == IPPROTO_ICMP/ { this->mp = args[0]; this->ipha = (ipha_t *)this->mp->b_rptr; /* stringify manually if inet_ntoa() unavailable */ this->addr = inet_ntoa(&this->ipha->ipha_dst); this->dir = ">"; } fbt::icmp_inbound:entry, fbt::ip_xmit_v4:entry /this->dir != NULL/ { this->iph_hdr_length = IPH_HDR_LENGTH(this->ipha); this->icmph = (icmph_t *)&this->mp->b_rptr[(char)this->iph_hdr_length]; this->type = this->icmph->icmph_type; this->code = this->icmph->icmph_code; this->typestr = icmptype[this->type] != NULL ? icmptype[this->type] : lltostr(this->type); this->codestr = icmpcode[this->type, this->code] != NULL ? icmpcode[this->type, this->code] : lltostr(this->code); printf("%-20Y %-12.12s %1s %-15s %-15s %s\n", walltimestamp, execname, this->dir, this->addr, this->typestr, this->codestr); } ================================================ FILE: Chap6/icmpstat.d ================================================ #!/usr/sbin/dtrace -s /* * icmpstat.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet mib::icmp_*: { @icmp[probename] = sum(arg0); } profile:::tick-1sec { printf("\n%Y:\n\n", walltimestamp); printf(" %32s %8s\n", "STATISTIC", "VALUE"); printa(" %32s %@8d\n", @icmp); trunc(@icmp); } ================================================ FILE: Chap6/ipfbtsnoop.d ================================================ #!/usr/sbin/dtrace -Cs /* * ipfbtsnoop.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz #define ETHERTYPE_IP (0x0800) /* IP protocol */ #define ETHERTYPE_IPV6 (0x86dd) /* IPv6 */ #define IPPROTO_IP 0 #define IPPROTO_ICMP 1 #define IPPROTO_IGMP 2 #define IPPROTO_TCP 6 #define IPPROTO_UDP 17 #define DL_ETHER 0x4 #define IPH_HDR_VERSION(ipha) \ ((int)(((ipha_t *)ipha)->ipha_version_and_hdr_length) >> 4) /* stringify an IPv4 address without inet*() being available */ #define IPV4_ADDR_TO_STR(string, addr) \ this->a = (uint8_t *)&addr; \ this->addr1 = strjoin(lltostr(this->a[0] + 0ULL), strjoin(".", \ strjoin(lltostr(this->a[1] + 0ULL), "."))); \ this->addr2 = strjoin(lltostr(this->a[2] + 0ULL), strjoin(".", \ lltostr(this->a[3] + 0ULL))); \ string = strjoin(this->addr1, this->addr2); /* convert net to host byte order for little-endian systems */ #define BSWAP_16(host, net) \ host = (net & 0xFF00) >> 8; \ host |= (net & 0xFF) << 8; dtrace:::BEGIN { /* selected protocols; see /usr/include/netinet/in.h for full list */ ipproto[IPPROTO_IP] = "IP"; ipproto[IPPROTO_ICMP] = "ICMP"; ipproto[IPPROTO_IGMP] = "IGMP"; ipproto[IPPROTO_TCP] = "TCP"; ipproto[IPPROTO_UDP] = "UDP"; printf("%-15s %-8s %-8s %-15s %-15s %5s %5s\n", "TIME(us)", "ONCPU", "INT", "SOURCE", "DEST", "BYTES", "PROTO"); } fbt::ip_input:entry { this->mp = args[2]; this->ill = args[0]; this->ipha = (ipha_t *)this->mp->b_rptr; this->name = stringof(this->ill->ill_name); this->ok = 1; } /* rewrite for dls_tx() on older Solaris kernels */ fbt::mac_tx:entry { this->mc = (mac_client_impl_t *)args[0]; } /* filter out non-Ethernet calls */ fbt::mac_tx:entry /this->mc->mci_mip->mi_info.mi_nativemedia == DL_ETHER/ { this->mp = args[1]; this->eth = (struct ether_header *)this->mp->b_rptr; this->type = this->eth->ether_type; } /* filter out non-IP calls */ fbt::mac_tx:entry /this->type == ETHERTYPE_IP || this->type == ETHERTYPE_IPV6/ { this->ipha = (ipha_t *)&this->mp->b_rptr[sizeof (struct ether_header)]; this->name = this->mc->mci_name; this->ok = 1; } fbt::ip_input:entry, fbt::mac_tx:entry /this->ok && IPH_HDR_VERSION(this->ipha) == 4/ { BSWAP_16(this->pktlen, this->ipha->ipha_length); IPV4_ADDR_TO_STR(this->src, this->ipha->ipha_src); IPV4_ADDR_TO_STR(this->dst, this->ipha->ipha_dst); this->proto = ipproto[this->ipha->ipha_protocol] != NULL ? ipproto[this->ipha->ipha_protocol] : lltostr(this->ipha->ipha_protocol); printf("%-15d %-8.8s %-8.8s %-15s > %-15s %5d %5s\n", timestamp / 1000, execname, this->name, this->src, this->dst, this->pktlen, this->proto); } ================================================ FILE: Chap6/ipio.d ================================================ #!/usr/sbin/dtrace -s /* * ipio.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf(" %3s %10s %15s %15s %8s %6s\n", "CPU", "DELTA(us)", "SOURCE", "DEST", "INT", "BYTES"); last = timestamp; } ip:::send { this->delta = (timestamp - last) / 1000; printf(" %3d %10d %15s -> %15s %8s %6d\n", cpu, this->delta, args[2]->ip_saddr, args[2]->ip_daddr, args[3]->if_name, args[2]->ip_plength); last = timestamp; } ip:::receive { this->delta = (timestamp - last) / 1000; printf(" %3d %10d %15s <- %15s %8s %6d\n", cpu, this->delta, args[2]->ip_daddr, args[2]->ip_saddr, args[3]->if_name, args[2]->ip_plength); last = timestamp; } ================================================ FILE: Chap6/ipproto.d ================================================ #!/usr/sbin/dtrace -s /* * ipproto.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } ip:::send, ip:::receive { this->protostr = args[2]->ip_ver == 4 ? args[4]->ipv4_protostr : args[5]->ipv6_nextstr; @num[args[2]->ip_saddr, args[2]->ip_daddr, this->protostr] = count(); } dtrace:::END { printf(" %-28s %-28s %6s %8s\n", "SADDR", "DADDR", "PROTO", "COUNT"); printa(" %-28s %-28s %6s %@8d\n", @num); } ================================================ FILE: Chap6/ipstat.d ================================================ #!/usr/sbin/dtrace -s /* * ipstat.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { LINES = 20; line = 0; } profile:::tick-1sec /--line <= 0/ { printf(" IP IF: %12s %12s %12s %12s %12s\n", "out(bytes)", "outDiscards", "in(bytes)", "inDiscards", "inErrors"); line = LINES; } mib:::ipIfStatsHCInOctets { @in = sum(arg0); } mib:::ipIfStatsHCOutOctets { @out = sum(arg0); } mib:::ipIfStatsInDiscards { @inDis = sum(arg0); } mib:::ipIfStatsOutDiscards { @outDis = sum(arg0); } mib:::ipIfStatsIn*Errors { @inErr = sum(arg0); } profile:::tick-1sec { printa(" %@12d %@12d %@12d %@12d %@12d\n", @out, @outDis, @in, @inDis, @inErr); clear(@out); clear(@outDis); clear(@in); clear(@inDis); clear(@inErr); } ================================================ FILE: Chap6/macops.d ================================================ #!/usr/sbin/dtrace -s /* * macops.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { /* See /usr/include/sys/dlpi.h */ mediatype[0x0] = "CSMACD"; mediatype[0x1] = "TPB"; mediatype[0x2] = "TPR"; mediatype[0x3] = "METRO"; mediatype[0x4] = "ETHER"; mediatype[0x05] = "HDLC"; mediatype[0x06] = "CHAR"; mediatype[0x07] = "CTCA"; mediatype[0x08] = "FDDI"; mediatype[0x10] = "FC"; mediatype[0x11] = "ATM"; mediatype[0x12] = "IPATM"; mediatype[0x13] = "X25"; mediatype[0x14] = "ISDN"; mediatype[0x15] = "HIPPI"; mediatype[0x16] = "100VG"; mediatype[0x17] = "100VGTPR"; mediatype[0x18] = "ETH_CSMA"; mediatype[0x19] = "100BT"; mediatype[0x1a] = "IB"; mediatype[0x0a] = "FRAME"; mediatype[0x0b] = "MPFRAME"; mediatype[0x0c] = "ASYNC"; mediatype[0x0d] = "IPX25"; mediatype[0x0e] = "LOOP"; mediatype[0x09] = "OTHER"; printf("Tracing MAC calls... Hit Ctrl-C to end.\n"); } /* the following are not complete lists of mac functions; add as needed */ /* mac functions with mac_client_impl_t as the first arg */ fbt::mac_promisc_add:entry, fbt::mac_promisc_remove:entry, fbt::mac_multicast_add:entry, fbt::mac_multicast_remove:entry, fbt::mac_unicast_add:entry, fbt::mac_unicast_remove:entry, fbt::mac_tx:entry { this->macp = (mac_client_impl_t *)arg0; this->name = stringof(this->macp->mci_name); this->media = this->macp->mci_mip->mi_info.mi_media; this->type = mediatype[this->media] != NULL ? mediatype[this->media] : lltostr(this->media); this->dir = probefunc == "mac_tx" ? "->" : "."; @[this->name, this->type, probefunc, this->dir] = count(); } /* mac functions with mac_impl_t as the first arg */ fbt::mac_stop:entry, fbt::mac_start:entry, fbt::mac_stat_get:entry, fbt::mac_ioctl:entry, fbt::mac_capab_get:entry, fbt::mac_set_prop:entry, fbt::mac_get_prop:entry, fbt::mac_rx:entry { this->mip = (mac_impl_t *)arg0; this->name = stringof(this->mip->mi_name); this->media = this->mip->mi_info.mi_media; this->type = mediatype[this->media] != NULL ? mediatype[this->media] : lltostr(this->media); this->dir = probefunc == "mac_rx" ? "<-" : "."; @[this->name, this->type, probefunc, this->dir] = count(); } dtrace:::END { printf(" %-16s %-16s %-16s %-4s %14s\n", "INT", "MEDIA", "MAC", "DATA", "CALLS"); printa(" %-16s %-16s %-16s %-4s %@14d\n", @); } ================================================ FILE: Chap6/ngelink.d ================================================ #!/usr/sbin/dtrace -s /* * ngelink.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate int seen[nge_t *]; int up[nge_t *]; int speed[nge_t *]; int duplex[nge_t *]; int last[nge_t *]; dtrace:::BEGIN { printf("%-20s %-10s %6s %8s %8s %s\n", "TIME", "INT", "UP", "SPEED", "DUPLEX", "DELTA(ms)"); } fbt::nge_check_copper:entry { self->ngep = args[0]; } fbt::nge_check_copper:return /self->ngep && (!seen[self->ngep] || (up[self->ngep] != self->ngep->param_link_up || speed[self->ngep] != self->ngep->param_link_speed || duplex[self->ngep] != self->ngep->param_link_duplex))/ { this->delta = last[self->ngep] ? timestamp - last[self->ngep] : 0; this->name = stringof(self->ngep->ifname); printf("%-20Y %-10s %6d %8d %8d %d\n", walltimestamp, this->name, self->ngep->param_link_up, self->ngep->param_link_speed, self->ngep->param_link_duplex, this->delta / 1000000); seen[self->ngep] = 1; last[self->ngep] = timestamp; } fbt::nge_check_copper:return /self->ngep/ { up[self->ngep] = self->ngep->param_link_up; speed[self->ngep] = self->ngep->param_link_speed; duplex[self->ngep] = self->ngep->param_link_duplex; self->ngep = 0; } ================================================ FILE: Chap6/ngesnoop.d ================================================ #!/usr/sbin/dtrace -s /* * ngesnoop.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-15s %-8s %-2s %-17s %-17s %-5s %5s\n", "TIME(us)", "INT", "D", "SOURCE", "DEST", "PROTO", "BYTES"); } fbt::nge_recv_ring:entry { self->ngep = args[0]; } fbt::mac_rx:entry /self->ngep/ { this->mp = args[2]; this->nge = self->ngep; this->dir = "<-"; self->ngep = 0; } fbt::nge_send:entry { this->nge = (nge_t *)arg0; this->mp = args[1]; this->dir = "->"; } fbt::mac_rx:entry, fbt::nge_send:entry /this->mp/ { this->eth = (struct ether_header *)this->mp->b_rptr; this->s = (char *)&this->eth->ether_shost; this->d = (char *)&this->eth->ether_dhost; this->t = ntohs(this->eth->ether_type); printf("%-15d %-8s %2s ", timestamp / 1000, this->nge->ifname, this->dir); printf("%02x:%02x:%02x:%02x:%02x:%02x ", this->s[0], this->s[1], this->s[2], this->s[3], this->s[4], this->s[5]); printf("%02x:%02x:%02x:%02x:%02x:%02x ", this->d[0], this->d[1], this->d[2], this->d[3], this->d[4], this->d[5]); printf(" %-04x %5d\n", this->t, msgdsize(this->mp)); } ================================================ FILE: Chap6/so1stbyte.d ================================================ #!/usr/sbin/dtrace -s /* * so1stbyte.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf(" %6s %-16s %6s %14s %14s %8s\n", "PID", "PROCESS", "PORT", "CONNECT(us)", "1stBYTE(us)", "BYTES"); } syscall::connect*:entry { this->s = (struct sockaddr_in *)copyin(arg1, sizeof (struct sockaddr)); self->port = (this->s->sin_port & 0xFF00) >> 8; self->port |= (this->s->sin_port & 0xFF) << 8; self->start = timestamp; self->connected = 0; } syscall::connect*:return { self->connection = (timestamp - self->start) / 1000; self->start = 0; self->connected = timestamp; } syscall::read*:entry, syscall::recv*:entry /(fds[arg0].fi_fs == "sockfs" || fds[arg0].fi_name == "") && self->connected/ { self->socket = 1; } syscall::read*:return, syscall::recv*:return /self->socket && arg0 > 0/ { this->firstbyte = (timestamp - self->connected) / 1000; printf(" %6d %-16s %6d %14d %14d %8d\n", pid, execname, self->port, self->connection, this->firstbyte, arg0); self->connected = 0; self->socket = 0; self->port = 0; } ================================================ FILE: Chap6/soaccept.d ================================================ #!/usr/sbin/dtrace -s /* * soaccept.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz /* If AF_INET and AF_INET6 are "Unknown" to DTrace, replace with numbers: */ inline int af_inet = AF_INET; inline int af_inet6 = AF_INET6; dtrace:::BEGIN { /* Add translations as desired from /usr/include/sys/errno.h */ err[0] = "Success"; err[EINTR] = "Interrupted syscall"; err[EIO] = "I/O error"; err[EAGAIN] = "Resource temp unavail"; err[EACCES] = "Permission denied"; err[ECONNABORTED] = "Connection aborted"; err[ECONNRESET] = "Connection reset"; err[ETIMEDOUT] = "Timed out"; err[EINPROGRESS] = "In progress"; printf("%-6s %-16s %-3s %-16s %-5s %8s %s\n", "PID", "PROCESS", "FAM", "ADDRESS", "PORT", "LAT(us)", "RESULT"); } syscall::accept*:entry { self->sa = arg1; self->start = timestamp; } syscall::accept*:return /self->sa/ { this->delta = (timestamp - self->start) / 1000; /* assume this is sockaddr_in until we can examine family */ this->s = (struct sockaddr_in *)copyin(self->sa, sizeof (struct sockaddr_in)); this->f = this->s->sin_family; } syscall::accept*:return /this->f == af_inet/ { this->port = ntohs(this->s->sin_port); this->address = inet_ntoa((ipaddr_t *)&this->s->sin_addr); this->errstr = err[errno] != NULL ? err[errno] : lltostr(errno); printf("%-6d %-16s %-3d %-16s %-5d %8d %s\n", pid, execname, this->f, this->address, this->port, this->delta, this->errstr); } syscall::accept*:return /this->f == af_inet6/ { /* refetch for sockaddr_in6 */ this->s6 = (struct sockaddr_in6 *)copyin(self->sa, sizeof (struct sockaddr_in6)); this->port = ntohs(this->s6->sin6_port); this->address = inet_ntoa6((in6_addr_t *)&this->s6->sin6_addr); this->errstr = err[errno] != NULL ? err[errno] : lltostr(errno); printf("%-6d %-16s %-3d %-16s %-5d %8d %s\n", pid, execname, this->f, this->address, this->port, this->delta, this->errstr); } syscall::accept*:return /self->start/ { self->sa = 0; self->start = 0; } ================================================ FILE: Chap6/socketio.d ================================================ #!/usr/sbin/dtrace -s /* * socketio.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing Socket I/O... Hit Ctrl-C to end.\n"); } syscall::read*:entry, syscall::write*:entry, syscall::send*:entry, syscall::recv*:entry /fds[arg0].fi_fs == "sockfs" || fds[arg0].fi_name == ""/ { @[execname, pid, probefunc] = count(); } dtrace:::END { printf(" %-16s %-8s %-16s %10s\n", "PROCESS", "PID", "SYSCALL", "COUNT"); printa(" %-16s %-8d %-16s %@10d\n", @); } ================================================ FILE: Chap6/socketiosort.d ================================================ #!/usr/sbin/dtrace -s /* * socketiosort.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing Socket I/O... Hit Ctrl-C to end.\n"); } syscall::read*:entry, syscall::write*:entry, syscall::send*:entry, syscall::recv*:entry /fds[arg0].fi_fs == "sockfs" || fds[arg0].fi_name == ""/ { @num[execname, probefunc, pid] = count(); @pid[execname, probefunc, pid] = max(pid); @pid["--------------", "------", pid] = max(pid); } dtrace:::END { printf(" %-8s %-16s %-16s %10s\n", "PID", "PROCESS", "SYSCALL", "COUNT"); setopt("aggsortpos", "0"); printa(" %@-8d %-16s %-16s %@10d\n", @pid, @num); } ================================================ FILE: Chap6/soclose.d ================================================ #!/usr/sbin/dtrace -s /* * soclose.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz /* If AF_INET and AF_INET6 are "Unknown" to DTrace, replace with numbers: */ inline int af_inet = AF_INET; inline int af_inet6 = AF_INET6; dtrace:::BEGIN { printf(" %-6s %-16s %-3s %-16s %-5s %s\n", "PID", "PROCESS", "FAM", "ADDRESS", "PORT", "DURATION(sec)"); } syscall::connect*:entry { this->s = (struct sockaddr_in *)copyin(arg1, sizeof (struct sockaddr)); this->f = this->s->sin_family; } syscall::connect*:entry /this->f == af_inet || this->f == af_inet6/ { self->family[arg0] = this->f; self->port[arg0] = ntohs(this->s->sin_port); self->address[arg0] = inet_ntop(this->s->sin_family, (void *)&this->s->sin_addr); self->start[arg0] = timestamp; } syscall::close:entry /self->start[arg0]/ { this->delta = (timestamp - self->start[arg0]) / 1000; this->sec = this->delta / 1000000; this->ms = (this->delta - (this->sec * 1000000)) / 1000; printf(" %-6d %-16s %-3d %-16s %-5d %d.%03d\n", pid, execname, self->family[arg0], self->address[arg0], self->port[arg0], this->sec, this->ms); self->family[arg0] = 0; self->address[arg0] = 0; self->port[arg0] = 0; self->start[arg0] = 0; } ================================================ FILE: Chap6/soconnect.d ================================================ #!/usr/sbin/dtrace -s /* * soconnect.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz /* If AF_INET and AF_INET6 are "Unknown" to DTrace, replace with numbers: */ inline int af_inet = AF_INET; inline int af_inet6 = AF_INET6; dtrace:::BEGIN { /* Add translations as desired from /usr/include/sys/errno.h */ err[0] = "Success"; err[EINTR] = "Interrupted syscall"; err[EIO] = "I/O error"; err[EACCES] = "Permission denied"; err[ENETDOWN] = "Network is down"; err[ENETUNREACH] = "Network unreachable"; err[ECONNRESET] = "Connection reset"; err[ECONNREFUSED] = "Connection refused"; err[ETIMEDOUT] = "Timed out"; err[EHOSTDOWN] = "Host down"; err[EHOSTUNREACH] = "No route to host"; err[EINPROGRESS] = "In progress"; printf("%-6s %-16s %-3s %-16s %-5s %8s %s\n", "PID", "PROCESS", "FAM", "ADDRESS", "PORT", "LAT(us)", "RESULT"); } syscall::connect*:entry { /* assume this is sockaddr_in until we can examine family */ this->s = (struct sockaddr_in *)copyin(arg1, sizeof (struct sockaddr)); this->f = this->s->sin_family; } syscall::connect*:entry /this->f == af_inet/ { self->family = this->f; self->port = ntohs(this->s->sin_port); self->address = inet_ntop(self->family, (void *)&this->s->sin_addr); self->start = timestamp; } syscall::connect*:entry /this->f == af_inet6/ { /* refetch for sockaddr_in6 */ this->s6 = (struct sockaddr_in6 *)copyin(arg1, sizeof (struct sockaddr_in6)); self->family = this->f; self->port = ntohs(this->s6->sin6_port); self->address = inet_ntoa6((in6_addr_t *)&this->s6->sin6_addr); self->start = timestamp; } syscall::connect*:return /self->start/ { this->delta = (timestamp - self->start) / 1000; this->errstr = err[errno] != NULL ? err[errno] : lltostr(errno); printf("%-6d %-16s %-3d %-16s %-5d %8d %s\n", pid, execname, self->family, self->address, self->port, this->delta, this->errstr); self->family = 0; self->address = 0; self->port = 0; self->start = 0; } ================================================ FILE: Chap6/soconnect_mac.d ================================================ #!/usr/sbin/dtrace -s /* * soconnect_mac.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz inline int af_inet = 2; /* AF_INET defined in bsd/sys/socket.h */ inline int af_inet6 = 30; /* AF_INET6 defined in bsd/sys/socket.h */ dtrace:::BEGIN { /* Add translations as desired from /usr/include/sys/errno.h */ err[0] = "Success"; err[EINTR] = "Interrupted syscall"; err[EIO] = "I/O error"; err[EACCES] = "Permission denied"; err[ENETDOWN] = "Network is down"; err[ENETUNREACH] = "Network unreachable"; err[ECONNRESET] = "Connection reset"; err[ECONNREFUSED] = "Connection refused"; err[ETIMEDOUT] = "Timed out"; err[EHOSTDOWN] = "Host down"; err[EHOSTUNREACH] = "No route to host"; err[EINPROGRESS] = "In progress"; printf("%-6s %-16s %-3s %-16s %-5s %8s %s\n", "PID", "PROCESS", "FAM", "ADDRESS", "PORT", "LAT(us)", "RESULT"); } syscall::connect*:entry { /* assume this is sockaddr_in until we can examine family */ this->s = (struct sockaddr_in *)copyin(arg1, sizeof (struct sockaddr)); this->f = this->s->sin_family; } syscall::connect*:entry /this->f == af_inet/ { self->family = this->f; /* Convert port to host byte order without ntohs() being available. */ self->port = (this->s->sin_port & 0xFF00) >> 8; self->port |= (this->s->sin_port & 0xFF) << 8; /* * Convert an IPv4 address into a dotted quad decimal string. * Until the inet_ntoa() functions are available from DTrace, this is * converted using the existing strjoin() and lltostr(). It's done in * two parts to avoid exhausting DTrace registers in one line of code. */ this->a = (uint8_t *)&this->s->sin_addr; this->addr1 = strjoin(lltostr(this->a[0] + 0ULL), strjoin(".", strjoin(lltostr(this->a[1] + 0ULL), "."))); this->addr2 = strjoin(lltostr(this->a[2] + 0ULL), strjoin(".", lltostr(this->a[3] + 0ULL))); self->address = strjoin(this->addr1, this->addr2); self->start = timestamp; } syscall::connect*:return /self->start/ { this->delta = (timestamp - self->start) / 1000; this->errstr = err[errno] != NULL ? err[errno] : lltostr(errno); printf("%-6d %-16s %-3d %-16s %-5d %8d %s\n", pid, execname, self->family, self->address, self->port, this->delta, this->errstr); self->family = 0; self->address = 0; self->port = 0; self->start = 0; } ================================================ FILE: Chap6/soerrors.d ================================================ #!/usr/sbin/dtrace -s /* * soerrors.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { /* Add translations as desired from /usr/include/sys/errno.h */ err[0] = "Success"; err[EACCES] = "Permission denied"; err[ECONNABORTED] = "Connection abort"; err[ECONNREFUSED] = "Connection refused"; err[ECONNRESET] = "Connection reset"; err[EHOSTDOWN] = "Host down"; err[EHOSTUNREACH] = "No route to host"; err[EINPROGRESS] = "In progress"; err[EINTR] = "Interrupted syscall"; err[EINVAL] = "Invalid argument"; err[EIO] = "I/O error"; err[ENETDOWN] = "Network is down"; err[ENETUNREACH] = "Network unreachable"; err[EPROTO] = "Protocol error"; err[ETIMEDOUT] = "Timed out"; err[EWOULDBLOCK] = "Would block"; printf(" %-6s %-16s %-10s %-4s %4s %4s %s\n", "PID", "PROCESS", "SYSCALL", "FD", "RVAL", "ERR", "RESULT"); } syscall::connect*:entry, syscall::accept*:entry, syscall::getsockopt:entry, syscall::setsockopt:entry { self->fd = arg0; self->ok = 1; } syscall::read*:entry, syscall::write*:entry, syscall::send*:entry, syscall::recv*:entry /fds[arg0].fi_fs == "sockfs" || fds[arg0].fi_name == ""/ { self->fd = arg0; self->ok = 1; } syscall::so*:entry { self->ok = 1; } syscall::connect*:return, syscall::accept*:return, syscall::read*:return, syscall::write*:return, syscall::send*:return, syscall::recv*:return, syscall::getsockopt:return, syscall::setsockopt:return /errno != 0 && errno != EAGAIN && self->ok/ { this->errstr = err[errno] != NULL ? err[errno] : lltostr(errno); printf(" %-6d %-16s %-10s %-4d %4d %4d %s\n", pid, execname, probefunc, self->fd, arg0, errno, this->errstr); } syscall::so*:return /errno != 0/ { /* these syscalls (such as sockconfig) don't operate on socket fds */ this->errstr = err[errno] != NULL ? err[errno] : lltostr(errno); printf(" %-6d %-16s %-10s %-4s %4d %4d %s\n", pid, execname, probefunc, "-", arg0, errno, this->errstr); } syscall::connect*:return, syscall::accept*:return, syscall::read*:return, syscall::write*:return, syscall::send*:return, syscall::recv*:return, syscall::getsockopt:return, syscall::setsockopt:return, syscall::so*:return { self->fd = 0; self->ok = 0; } ================================================ FILE: Chap6/sotop.d ================================================ #!/usr/sbin/dtrace -s /* * sotop.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option destructive syscall::read*:entry, syscall::recv*:entry /fds[arg0].fi_fs == "sockfs" || fds[arg0].fi_name == ""/ { self->read = 1; } syscall::read*:return, syscall::recv*:return /self->read/ { this->size = (int)arg0 > 0 ? arg0 : 0; @rc[execname, pid] = count(); @rb[execname, pid] = sum(this->size); self->read = 0; } syscall::write*:entry, syscall::send*:entry /fds[arg0].fi_fs == "sockfs" || fds[arg0].fi_name == ""/ { /* this under-counts writev() size (assumes iov_len is 1) */ this->size = arg2; @wc[execname, pid] = count(); @wb[execname, pid] = sum(this->size); } profile:::profile-100hz { /* will sum %CPUs on multi-core systems */ @cpu[execname, pid] = count(); } profile:::tick-1sec { normalize(@rb, 1024); normalize(@wb, 1024); system("clear"); printf(" %-16s %-8s %8s %8s %10s %10s %8s\n", "PROCESS", "PID", "READS", "WRITES", "READ_KB", "WRITE_KB", "CPU"); setopt("aggsortpos", "4"); setopt("aggsortrev", "4"); printa(" %-16s %-8d %@8d %@8d %@10d %@10d %@8d\n", @rc, @wc, @rb, @wb, @cpu); trunc(@rc); trunc(@rb); trunc(@wc); trunc(@wb); trunc(@cpu); } ================================================ FILE: Chap6/superping.d ================================================ #!/usr/sbin/dtrace -s /* * superping.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz mib:::rawipOutDatagrams /pid == $target/ { start = timestamp; } mib:::icmpInEchoReps /start/ { this->delta = (timestamp - start) / 1000; printf("dtrace measured: %d us\n", this->delta); @a["\n ICMP packet delta average (us):"] = avg(this->delta); @q["\n ICMP packet delta distribution (us):"] = lquantize(this->delta, 0, 1000000, 100); start = 0; } ================================================ FILE: Chap6/tcp1stbyte.d ================================================ #!/usr/sbin/dtrace -s /* * tcp1stbyte.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ tcp:::connect-established { start[args[1]->cs_cid] = timestamp; } tcp:::receive /start[args[1]->cs_cid] && (args[2]->ip_plength - args[4]->tcp_offset) > 0/ { @latency["1st Byte Latency (ns)", args[2]->ip_saddr] = quantize(timestamp - start[args[1]->cs_cid]); start[args[1]->cs_cid] = 0; } ================================================ FILE: Chap6/tcp_rwndclosed.d ================================================ #!/usr/sbin/dtrace -s /* * tcp_rwndclosed.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet tcp:::send / args[4]->tcp_window == 0 && (args[4]->tcp_flags & TH_RST) == 0 / { rwndclosed[args[1]->cs_cid] = timestamp; rwndrnxt[args[1]->cs_cid] = args[3]->tcps_rnxt; @numrwndclosed[args[2]->ip_daddr, args[4]->tcp_dport] = count(); } tcp:::receive / rwndclosed[args[1]->cs_cid] && args[4]->tcp_seq >= rwndrnxt[args[1]->cs_cid] / { @meantimeclosed[args[2]->ip_saddr, args[4]->tcp_sport] = avg(timestamp - rwndclosed[args[1]->cs_cid]); @stddevtimeclosed[args[2]->ip_saddr, args[4]->tcp_sport] = stddev(timestamp - rwndclosed[args[1]->cs_cid]); rwndclosed[args[1]->cs_cid] = 0; rwndrnxt[args[1]->cs_cid] = 0; } END { printf("%-20s %-8s %-25s %-8s %-8s\n", "Remote host", "Port", "TCP Avg RwndClosed(ns)", "StdDev", "Num"); printa("%-20s %-8d %@-25d %@-8d %@-8d\n", @meantimeclosed, @stddevtimeclosed, @numrwndclosed); } ================================================ FILE: Chap6/tcpaccept.d ================================================ #!/usr/sbin/dtrace -s /* * tcpaccept.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } tcp:::accept-established { @num[args[2]->ip_saddr, args[4]->tcp_dport] = count(); } dtrace:::END { printf(" %-26s %-8s %8s\n", "HOST", "PORT", "COUNT"); printa(" %-26s %-8d %@8d\n", @num); } ================================================ FILE: Chap6/tcpacceptx.d ================================================ #!/usr/sbin/dtrace -s /* * tcpacceptx.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } tcp:::accept-established { @num[args[2]->ip_saddr, args[4]->tcp_dport] = count(); } dtrace:::END { printf(" %-26s %-8s %8s\n", "HOSTNAME", "PORT", "COUNT"); printa(" %-26I %-8P %@8d\n", @num); } ================================================ FILE: Chap6/tcpbytes.d ================================================ #!/usr/sbin/dtrace -s /* * tcpbytes.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing TCP payload bytes... Hit Ctrl-C to end.\n"); } tcp:::receive { @bytes[args[2]->ip_saddr, args[4]->tcp_dport] = sum(args[2]->ip_plength - args[4]->tcp_offset); } tcp:::send { @bytes[args[2]->ip_daddr, args[4]->tcp_sport] = sum(args[2]->ip_plength - args[4]->tcp_offset); } dtrace:::END { printf(" %-32s %-6s %16s\n", "REMOTE", "LPORT", "BYTES"); printa(" %-32s %-6d %@16d\n", @bytes); } ================================================ FILE: Chap6/tcpconnect.d ================================================ #!/usr/sbin/dtrace -s /* * tcpconnect.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } tcp:::connect-established { @num[args[2]->ip_daddr, args[4]->tcp_dport] = count(); } dtrace:::END { printf(" %-26s %-8s %8s\n", "HOST", "PORT", "COUNT"); printa(" %-26s %-8d %@8d\n", @num); } ================================================ FILE: Chap6/tcpconnlat.d ================================================ #!/usr/sbin/dtrace -s /* * tcpconnlat.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ tcp:::connect-request { start[args[1]->cs_cid] = timestamp; } tcp:::connect-established /start[args[1]->cs_cid]/ { @latency["Connect Latency (ns)", args[2]->ip_daddr] = quantize(timestamp - start[args[1]->cs_cid]); start[args[1]->cs_cid] = 0; } ================================================ FILE: Chap6/tcpfbtwatch.d ================================================ #!/usr/sbin/dtrace -Cs /* * tcpfbtwatch.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz #define IPH_HDR_VERSION(ipha) \ ((int)(((ipha_t *)ipha)->ipha_version_and_hdr_length) >> 4) #define TCPS_SYN_RCVD -1 #define conn_tcp conn_proto_priv.cp_tcp #define conn_lport u_port.tcpu_ports.tcpu_lport dtrace:::BEGIN { printf("%-20s %-24s %-24s %6s\n", "TIME", "REMOTE", "LOCAL", "LPORT"); } fbt::tcp_rput_data:entry { self->connp = (conn_t *)arg0; self->tcp = self->connp->conn_tcp; self->mp = args[1]; self->ipha = (ipha_t *)self->mp->b_rptr; self->in_tcp_rput_data = 1; } fbt::tcp_rput_data:entry /self->tcp->tcp_state == TCPS_SYN_RCVD && IPH_HDR_VERSION(self->ipha) == 4/ { this->src = inet_ntoa(&self->ipha->ipha_src); this->dst = inet_ntoa(&self->ipha->ipha_dst); this->lport = ntohs(self->connp->conn_lport); printf("%-20Y %-24s %-24s %6d\n", walltimestamp, this->src, this->dst, this->lport); } fbt::tcp_find_pktinfo:return /self->in_tcp_rput_data && self->tcp->tcp_state == TCPS_SYN_RCVD && IPH_HDR_VERSION(self->ipha) == 6/ { this->mp = args[1]; this->ip6h = (struct ip6_hdr *)this->mp->b_rptr; this->src = inet_ntoa6(&this->ip6h->ip6_src); this->dst = inet_ntoa6(&this->ip6h->ip6_dst); this->lport = ntohs(self->connp->conn_lport); printf("%-20Y %-24s %-24s %6d\n", walltimestamp, this->src, this->dst, this->lport); } fbt::tcp_rput_data:return { self->connp = 0; self->tcp = 0; self->mp = 0; self->ipha = 0; self->in_tcp_rput_data = 0; } ================================================ FILE: Chap6/tcpio.d ================================================ #!/usr/sbin/dtrace -s /* * tcpio.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-3s %15s:%-5s %15s:%-5s %6s %s\n", "CPU", "LADDR", "LPORT", "RADDR", "RPORT", "BYTES", "FLAGS"); } tcp:::send { this->length = args[2]->ip_plength - args[4]->tcp_offset; printf("%-3d %15s:%-5d -> %15s:%-5d %6d (", cpu, args[2]->ip_saddr, args[4]->tcp_sport, args[2]->ip_daddr, args[4]->tcp_dport, this->length); } tcp:::receive { this->length = args[2]->ip_plength - args[4]->tcp_offset; printf("%-3d %15s:%-5d <- %15s:%-5d %6d (", cpu, args[2]->ip_daddr, args[4]->tcp_dport, args[2]->ip_saddr, args[4]->tcp_sport, this->length); } tcp:::send, tcp:::receive { printf("%s", args[4]->tcp_flags & TH_FIN ? "FIN|" : ""); printf("%s", args[4]->tcp_flags & TH_SYN ? "SYN|" : ""); printf("%s", args[4]->tcp_flags & TH_RST ? "RST|" : ""); printf("%s", args[4]->tcp_flags & TH_PUSH ? "PUSH|" : ""); printf("%s", args[4]->tcp_flags & TH_ACK ? "ACK|" : ""); printf("%s", args[4]->tcp_flags & TH_URG ? "URG|" : ""); printf("%s", args[4]->tcp_flags & TH_ECE ? "ECE|" : ""); printf("%s", args[4]->tcp_flags & TH_CWR ? "CWR|" : ""); printf("%s", args[4]->tcp_flags == 0 ? "null " : ""); printf("\b)\n"); } ================================================ FILE: Chap6/tcpioshort.d ================================================ #!/usr/sbin/dtrace -s /* * tcpioshort.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ tcp:::send, tcp:::receive { printf("%15s:%-5d -> %15s:%-5d %d bytes", args[2]->ip_saddr, args[4]->tcp_sport, args[2]->ip_daddr, args[4]->tcp_dport, args[2]->ip_plength); } ================================================ FILE: Chap6/tcpnmap.d ================================================ #!/usr/sbin/dtrace -s /* * tcpnmap.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing for possible nmap scans... Hit Ctrl-C to end.\n"); } tcp:::accept-refused { @num["TCP_connect()_scan", args[2]->ip_daddr] = count(); } tcp:::receive /args[4]->tcp_flags == 0/ { @num["TCP_null_scan", args[2]->ip_saddr] = count(); } tcp:::receive /args[4]->tcp_flags == (TH_URG|TH_PUSH|TH_FIN)/ { @num["TCP_Xmas_scan", args[2]->ip_saddr] = count(); } dtrace:::END { printf("Possible scan events:\n\n"); printf(" %-24s %-28s %8s\n", "TYPE", "HOST", "COUNT"); printa(" %-24s %-28s %@8d\n", @num); } ================================================ FILE: Chap6/tcpsize.d ================================================ #!/usr/sbin/dtrace -s /* * tcpsize.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ tcp:::receive { @bytes[args[2]->ip_saddr, args[4]->tcp_dport] = quantize(args[2]->ip_plength - args[4]->tcp_offset); } tcp:::send { @bytes[args[2]->ip_daddr, args[4]->tcp_sport] = quantize(args[2]->ip_plength - args[4]->tcp_offset); } ================================================ FILE: Chap6/tcpsnoop.d ================================================ #!/usr/sbin/dtrace -s /* * tcpsnoop.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%6s %6s %15s:%-5s %15s:%-5s %6s %s\n", "TIME", "PID", "LADDR", "PORT", "RADDR", "PORT", "BYTES", "FLAGS"); } tcp:::send { this->length = args[2]->ip_plength - args[4]->tcp_offset; printf("%6d %6d %15s:%-5d -> %15s:%-5d %6d (", timestamp/1000, args[1]->cs_pid, args[2]->ip_saddr, args[4]->tcp_sport, args[2]->ip_daddr, args[4]->tcp_dport, this->length); } tcp:::receive { this->length = args[2]->ip_plength - args[4]->tcp_offset; printf("%6d %6d %15s:%-5d <- %15s:%-5d %6d (", timestamp/1000, args[1]->cs_pid, args[2]->ip_daddr, args[4]->tcp_dport, args[2]->ip_saddr, args[4]->tcp_sport, this->length); } tcp:::send, tcp:::receive { printf("%s", args[4]->tcp_flags & TH_FIN ? "FIN|" : ""); printf("%s", args[4]->tcp_flags & TH_SYN ? "SYN|" : ""); printf("%s", args[4]->tcp_flags & TH_RST ? "RST|" : ""); printf("%s", args[4]->tcp_flags & TH_PUSH ? "PUSH|" : ""); printf("%s", args[4]->tcp_flags & TH_ACK ? "ACK|" : ""); printf("%s", args[4]->tcp_flags & TH_URG ? "URG|" : ""); printf("%s", args[4]->tcp_flags & TH_ECE ? "ECE|" : ""); printf("%s", args[4]->tcp_flags & TH_CWR ? "CWR|" : ""); printf("%s", args[4]->tcp_flags == 0 ? "null " : ""); printf("\b)\n"); } ================================================ FILE: Chap6/tcpsnoop_snv.d ================================================ #!/usr/sbin/dtrace -Cs /* * tcpsnoop_snv.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz #include #include #include /* * Print header */ dtrace:::BEGIN { /* print main headers */ printf("%5s %6s %-15s %5s %2s %-15s %5s %5s %s\n", "UID", "PID", "LADDR", "LPORT", "DR", "RADDR", "RPORT", "SIZE", "CMD"); } /* * TCP Process inbound connections * * 0x00200000 has been hardcoded. It was SS_TCP_FAST_ACCEPT, but was * renamed to SS_DIRECT around build 31. */ fbt:sockfs:sotpi_accept:entry /(arg1 & FREAD) && (arg1 & FWRITE) && (args[0]->so_state & 0x00200000)/ { self->sop = args[0]; } fbt:sockfs:sotpi_create:return /self->sop/ { self->nsop = (struct sonode *)arg1; } fbt:sockfs:sotpi_accept:return /self->nsop/ { this->tcpp = (tcp_t *)self->nsop->so_priv; self->connp = (conn_t *)this->tcpp->tcp_connp; tname[(int)self->connp] = execname; tpid[(int)self->connp] = pid; tuid[(int)self->connp] = uid; } fbt:sockfs:sotpi_accept:return { self->nsop = 0; self->sop = 0; } /* * TCP Process outbound connections */ fbt:ip:tcp_connect:entry { this->tcpp = (tcp_t *)arg0; self->connp = (conn_t *)this->tcpp->tcp_connp; tname[(int)self->connp] = execname; tpid[(int)self->connp] = pid; tuid[(int)self->connp] = uid; } /* * TCP Data translations */ fbt:sockfs:sotpi_accept:return, fbt:ip:tcp_connect:return /self->connp/ { /* fetch ports */ #if defined(_BIG_ENDIAN) self->lport = self->connp->u_port.tcpu_ports.tcpu_lport; self->fport = self->connp->u_port.tcpu_ports.tcpu_fport; #else self->lport = BSWAP_16(self->connp->u_port.tcpu_ports.tcpu_lport); self->fport = BSWAP_16(self->connp->u_port.tcpu_ports.tcpu_fport); #endif /* fetch IPv4 addresses */ this->fad12 = (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[12]; this->fad13 = (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[13]; this->fad14 = (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[14]; this->fad15 = (int)self->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[15]; this->lad12 = (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[12]; this->lad13 = (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[13]; this->lad14 = (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[14]; this->lad15 = (int)self->connp->connua_v6addr.connua_laddr._S6_un._S6_u8[15]; /* convert type for use with lltostr() */ this->fad12 = this->fad12 < 0 ? 256 + this->fad12 : this->fad12; this->fad13 = this->fad13 < 0 ? 256 + this->fad13 : this->fad13; this->fad14 = this->fad14 < 0 ? 256 + this->fad14 : this->fad14; this->fad15 = this->fad15 < 0 ? 256 + this->fad15 : this->fad15; this->lad12 = this->lad12 < 0 ? 256 + this->lad12 : this->lad12; this->lad13 = this->lad13 < 0 ? 256 + this->lad13 : this->lad13; this->lad14 = this->lad14 < 0 ? 256 + this->lad14 : this->lad14; this->lad15 = this->lad15 < 0 ? 256 + this->lad15 : this->lad15; /* stringify addresses */ self->faddr = strjoin(lltostr(this->fad12), "."); self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad13), ".")); self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad14), ".")); self->faddr = strjoin(self->faddr, lltostr(this->fad15 + 0)); self->laddr = strjoin(lltostr(this->lad12), "."); self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad13), ".")); self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad14), ".")); self->laddr = strjoin(self->laddr, lltostr(this->lad15 + 0)); /* fix direction and save values */ tladdr[(int)self->connp] = self->laddr; tfaddr[(int)self->connp] = self->faddr; tlport[(int)self->connp] = self->lport; tfport[(int)self->connp] = self->fport; /* all systems go */ tok[(int)self->connp] = 1; } /* * TCP Clear connp */ fbt:ip:tcp_get_conn:return { /* Q_TO_CONN */ this->connp = (conn_t *)arg1; tok[(int)this->connp] = 0; tpid[(int)this->connp] = 0; tuid[(int)this->connp] = 0; tname[(int)this->connp] = 0; } /* * TCP Process "port closed" */ fbt:ip:tcp_xmit_early_reset:entry { this->queuep = args[7]->tcps_g_q; this->connp = (conn_t *)this->queuep->q_ptr; this->tcpp = (tcp_t *)this->connp->conn_tcp; /* split addresses */ this->ipha = (ipha_t *)args[1]->b_rptr; this->fad15 = (this->ipha->ipha_src & 0xff000000) >> 24; this->fad14 = (this->ipha->ipha_src & 0x00ff0000) >> 16; this->fad13 = (this->ipha->ipha_src & 0x0000ff00) >> 8; this->fad12 = (this->ipha->ipha_src & 0x000000ff); this->lad15 = (this->ipha->ipha_dst & 0xff000000) >> 24; this->lad14 = (this->ipha->ipha_dst & 0x00ff0000) >> 16; this->lad13 = (this->ipha->ipha_dst & 0x0000ff00) >> 8; this->lad12 = (this->ipha->ipha_dst & 0x000000ff); /* stringify addresses */ self->faddr = strjoin(lltostr(this->fad12), "."); self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad13), ".")); self->faddr = strjoin(self->faddr, strjoin(lltostr(this->fad14), ".")); self->faddr = strjoin(self->faddr, lltostr(this->fad15 + 0)); self->laddr = strjoin(lltostr(this->lad12), "."); self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad13), ".")); self->laddr = strjoin(self->laddr, strjoin(lltostr(this->lad14), ".")); self->laddr = strjoin(self->laddr, lltostr(this->lad15 + 0)); self->reset = 1; } /* * TCP Fetch "port closed" ports */ fbt:ip:tcp_xchg:entry /self->reset/ { #if defined(_BIG_ENDIAN) self->lport = (uint16_t)arg0; self->fport = (uint16_t)arg1; #else self->lport = BSWAP_16((uint16_t)arg0); self->fport = BSWAP_16((uint16_t)arg1); #endif self->lport = BE16_TO_U16(arg0); self->fport = BE16_TO_U16(arg1); } /* * TCP Print "port closed" */ fbt:ip:tcp_xmit_early_reset:return { self->name = ""; self->pid = 0; self->uid = 0; self->size = 54; /* should check trailers */ self->dir = "<-"; printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n", self->uid, self->pid, self->laddr, self->lport, self->dir, self->faddr, self->fport, self->size, self->name); self->dir = "->"; printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n", self->uid, self->pid, self->laddr, self->lport, self->dir, self->faddr, self->fport, self->size, self->name); self->reset = 0; self->size = 0; self->name = 0; } /* * TCP Process Write */ fbt:ip:tcp_send_data:entry { self->conn_p = (conn_t *)args[0]->tcp_connp; } fbt:ip:tcp_send_data:entry /tok[(int)self->conn_p]/ { self->dir = "->"; self->size = msgdsize(args[2]) + 14; /* should check trailers */ self->uid = tuid[(int)self->conn_p]; self->laddr = tladdr[(int)self->conn_p]; self->faddr = tfaddr[(int)self->conn_p]; self->lport = tlport[(int)self->conn_p]; self->fport = tfport[(int)self->conn_p]; self->ok = 2; /* follow inetd -> in.* transitions */ self->name = pid && (tname[(int)self->conn_p] == "inetd") ? execname : tname[(int)self->conn_p]; self->pid = pid && (tname[(int)self->conn_p] == "inetd") ? pid : tpid[(int)self->conn_p]; tname[(int)self->conn_p] = self->name; tpid[(int)self->conn_p] = self->pid; } /* * TCP Process Read */ fbt:ip:tcp_rput_data:entry { self->conn_p = (conn_t *)arg0; self->size = msgdsize(args[1]) + 14; /* should check trailers */ } fbt:ip:tcp_rput_data:entry /tok[(int)self->conn_p]/ { self->dir = "<-"; self->uid = tuid[(int)self->conn_p]; self->laddr = tladdr[(int)self->conn_p]; self->faddr = tfaddr[(int)self->conn_p]; self->lport = tlport[(int)self->conn_p]; self->fport = tfport[(int)self->conn_p]; self->ok = 2; /* follow inetd -> in.* transitions */ self->name = pid && (tname[(int)self->conn_p] == "inetd") ? execname : tname[(int)self->conn_p]; self->pid = pid && (tname[(int)self->conn_p] == "inetd") ? pid : tpid[(int)self->conn_p]; tname[(int)self->conn_p] = self->name; tpid[(int)self->conn_p] = self->pid; } /* * TCP Complete printing outbound handshake */ fbt:ip:tcp_connect:return /self->connp/ { self->name = tname[(int)self->connp]; self->pid = tpid[(int)self->connp]; self->uid = tuid[(int)self->connp]; self->size = 54; /* should check trailers */ self->dir = "->"; /* this packet occured before connp was fully established */ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n", self->uid, self->pid, self->laddr, self->lport, self->dir, self->faddr, self->fport, self->size, self->name); } /* * TCP Complete printing inbound handshake */ fbt:sockfs:sotpi_accept:return /self->connp/ { self->name = tname[(int)self->connp]; self->pid = tpid[(int)self->connp]; self->uid = tuid[(int)self->connp]; self->size = 54; /* should check trailers */ /* these packets occured before connp was fully established */ self->dir = "<-"; printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n", self->uid, self->pid, self->laddr, self->lport, self->dir, self->faddr, self->fport, self->size, self->name); self->dir = "->"; printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n", self->uid, self->pid, self->laddr, self->lport, self->dir, self->faddr, self->fport, self->size, self->name); self->dir = "<-"; printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n", self->uid, self->pid, self->laddr, self->lport, self->dir, self->faddr, self->fport, self->size, self->name); } /* * Print output */ fbt:ip:tcp_send_data:entry, fbt:ip:tcp_rput_data:entry /self->ok == 2/ { /* print output line */ printf("%5d %6d %-15s %5d %2s %-15s %5d %5d %s\n", self->uid, self->pid, self->laddr, self->lport, self->dir, self->faddr, self->fport, self->size, self->name); } /* * TCP Clear connect variables */ fbt:sockfs:sotpi_accept:return, fbt:ip:tcp_connect:return /self->connp/ { self->faddr = 0; self->laddr = 0; self->fport = 0; self->lport = 0; self->connp = 0; self->name = 0; self->pid = 0; self->uid = 0; } /* * TCP Clear r/w variables */ fbt:ip:tcp_send_data:entry, fbt:ip:tcp_rput_data:entry { self->ok = 0; self->dir = 0; self->uid = 0; self->pid = 0; self->size = 0; self->name = 0; self->lport = 0; self->fport = 0; self->laddr = 0; self->faddr = 0; self->conn_p = 0; } ================================================ FILE: Chap6/tcpstat.d ================================================ #!/usr/sbin/dtrace -s /* * tcpstat.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { LINES = 20; line = 0; } profile:::tick-1sec /--line <= 0/ { printf(" TCP bytes: %6s %12s %12s %12s %12s\n", "out", "outRetrans", "in", "inDup", "inUnorder"); line = LINES; } mib:::tcpOutDataBytes, mib:::tcpRetransBytes, mib:::tcpInDataInorderBytes, mib:::tcpInDataDupBytes, mib:::tcpInDataUnorderBytes { /* some of these probes can return -1 */ this->bytes = (int)arg0 > 0 ? arg0 : 0; } mib:::tcpOutDataBytes { @out = sum(this->bytes); } mib:::tcpRetransBytes { @outRe = sum(this->bytes); } mib:::tcpInDataInorderBytes { @in = sum(this->bytes); } mib:::tcpInDataDupBytes { @inDup = sum(this->bytes); } mib:::tcpInDataUnorderBytes { @inUn = sum(this->bytes); } profile:::tick-1sec { printa(" %@12d %@12d %@12d %@12d %@12d\n", @out, @outRe, @in, @inDup, @inUn); clear(@out); clear(@outRe); clear(@in); clear(@inDup); clear(@inUn); } ================================================ FILE: Chap6/tcpstate.d ================================================ #!/usr/sbin/dtrace -s /* * tcpstate.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10 dtrace:::BEGIN { printf(" %3s %12s %-20s %-20s\n", "CPU", "DELTA(us)", "OLD", "NEW"); last = timestamp; } tcp:::state-change { this->elapsed = (timestamp - last) / 1000; printf(" %3d %12d %-20s -> %-20s\n", cpu, this->elapsed, tcp_state_string[args[5]->tcps_state], tcp_state_string[args[3]->tcps_state]); last = timestamp; } ================================================ FILE: Chap6/tcpwatch.d ================================================ #!/usr/sbin/dtrace -s /* * tcpwatch.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-20s %-24s %-24s %6s\n", "TIME", "REMOTE", "LOCAL", "LPORT"); } tcp:::accept-established { printf("%-20Y %-24s %-24s %6d\n", walltimestamp, args[2]->ip_saddr, args[2]->ip_daddr, args[4]->tcp_dport); } ================================================ FILE: Chap6/udpio.d ================================================ #!/usr/sbin/dtrace -s /* * udpio.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-3s %15s:%-5s %15s:%-5s %6s\n", "CPU", "LADDR", "PORT", "RADDR", "PORT", "IPLEN"); } udp:::send { printf("%-3d %15s:%-5d -> %15s:%-5d %6d\n", cpu, args[2]->ip_saddr, args[4]->udp_sport, args[2]->ip_daddr, args[4]->udp_dport, args[2]->ip_plength); } udp:::receive { printf("%-3d %15s:%-5d <- %15s:%-5d %6d\n", cpu, args[2]->ip_daddr, args[4]->udp_dport, args[2]->ip_saddr, args[4]->udp_sport, args[2]->ip_plength); } ================================================ FILE: Chap6/udpstat.d ================================================ #!/usr/sbin/dtrace -s /* * udpstat.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { LINES = 20; line = 0; } profile:::tick-1sec /--line <= 0/ { printf(" UDP: %12s %12s %12s %12s %12s\n", "out(bytes)", "outErrors", "in(bytes)", "inErrors", "noPort"); line = LINES; } mib:::udp*InDatagrams { @in = sum(arg0); } mib:::udp*OutDatagrams { @out = sum(arg0); } mib:::udpInErrors { @inErr = sum(arg0); } mib:::udpInCksumErrs { @inErr = sum(arg0); } mib:::udpOutErrors { @outErr = sum(arg0); } mib:::udpNoPorts { @noPort = sum(arg0); } profile:::tick-1sec { printa(" %@12d %@12d %@12d %@12d %@12d\n", @out, @outErr, @in, @inErr, @noPort); clear(@out); clear(@outErr); clear(@in); clear(@inErr); clear(@noPort); } ================================================ FILE: Chap6/xdrshow.d ================================================ #!/usr/sbin/dtrace -s /* * xdrshow.d * * Example script from Chapter 6 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing XDR calls... Hit Ctrl-C to end.\n"); } fbt::xdr_*:entry { @num[execname, func(caller), probefunc] = count(); } dtrace:::END { printf(" %-12s %-28s %-25s %9s\n", "PROCESS", "CALLER", "XDR_FUNCTION", "COUNT"); printa(" %-12.12s %-28a %-25s %@9d\n", @num); } ================================================ FILE: Chap7/cifserrors.d ================================================ #!/usr/sbin/dtrace -s /* * cifserrors.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { /* * These are some of over 500 NT_STATES_* error codes defined in * uts/common/smbsrv/ntstatus.h. For more detail see MSDN and * ntstatus.h in the MS DDK. */ ntstatus[0] = "SUCCESS"; ntstatus[1] = "UNSUCCESSFUL"; ntstatus[2] = "NOT_IMPLEMENTED"; ntstatus[5] = "ACCESS_VIOLATION"; ntstatus[15] = "NO_SUCH_FILE"; ntstatus[17] = "END_OF_FILE"; ntstatus[23] = "NO_MEMORY"; ntstatus[29] = "ILLEGAL_INSTRUCTION"; ntstatus[34] = "ACCESS_DENIED"; ntstatus[50] = "DISK_CORRUPT_ERROR"; ntstatus[61] = "DATA_ERROR"; ntstatus[62] = "CRC_ERROR"; ntstatus[68] = "QUOTA_EXCEEDED"; ntstatus[127] = "DISK_FULL"; ntstatus[152] = "FILE_INVALID"; ntstatus[186] = "FILE_IS_A_DIRECTORY"; ntstatus[258] = "FILE_CORRUPT_ERROR"; ntstatus[259] = "NOT_A_DIRECTORY"; ntstatus[291] = "FILE_DELETED"; /* ...etc... */ printf(" %-24s %3s %-19s %-16s %s\n", "CIFS EVENT", "ERR", "CODE", "CLIENT", "PATHNAME"); } smb:::op-*-start, smb:::op-*-done /(this->sr = (struct smb_request *)arg0) && this->sr->smb_error.status != 0/ { this->err = this->sr->smb_error.status; this->str = ntstatus[this->err] != NULL ? ntstatus[this->err] : "?"; printf(" %-24s %3d %-19s %-16s %s\n", probename, this->err, this->str, args[0]->ci_remote, args[1]->soi_curpath); } ================================================ FILE: Chap7/cifsfbtnofile.d ================================================ #!/usr/sbin/dtrace -s /* * cifsfbtnofile.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { /* a few likely codes are included from ntstatus.h */ ntstatus[0] = "SUCCESS"; ntstatus[1] = "UNSUCCESSFUL"; ntstatus[15] = "NO_SUCH_FILE"; ntstatus[186] = "FILE_IS_A_DIR"; printf(" %-16s %3s %-13s %s\n", "CLIENT", "ERR", "ERROR", "PATHNAME"); } fbt::smb*find_first*:entry { self->in_find_first = 1; } fbt::smb*find_first*:return { self->in_find_first = 0; } /* assume smb_odir_open() checks relevant path during find_entries */ fbt::smb_odir_open:entry /self->in_find_first/ { self->sr = args[0]; self->path = args[1]; } /* assume smbsr_set_error() will set relevant error during find_entries */ fbt::smbsr_set_error:entry /self->in_find_first/ { self->err = args[1]->status; } /* if an error was previously seen during find_entries, print cached details */ fbt::smb*find_entries:return /self->sr && self->err/ { this->str = ntstatus[self->err] != NULL ? ntstatus[self->err] : "?"; this->remote = self->sr->session->ipaddr.a_family == AF_INET ? inet_ntoa(&self->sr->session->ipaddr.au_addr.au_ipv4) : inet_ntoa6(&self->sr->session->ipaddr.au_addr.au_ipv6); printf(" %-16s %3d %-13s %s%s\n", this->remote, self->err, this->str, self->sr->tid_tree->t_sharename, stringof(self->path)); } fbt::smb*find_entries:return /self->sr/ { self->sr = 0; self->path = 0; self->err = 0; } ================================================ FILE: Chap7/cifsfileio.d ================================================ #!/usr/sbin/dtrace -s /* * cifsfileio.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing... Hit Ctrl-C to end.\n"); } smb:::op-Read-done, smb:::op-ReadX-done { @readbytes[args[1]->soi_curpath] = sum(args[2]->soa_count); } smb:::op-Write-done, smb:::op-WriteX-done { @writebytes[args[1]->soi_curpath] = sum(args[2]->soa_count); } dtrace:::END { printf("\n%12s %12s %s\n", "Rbytes", "Wbytes", "Pathname"); printa("%@12d %@12d %s\n", @readbytes, @writebytes); } ================================================ FILE: Chap7/cifsops.d ================================================ #!/usr/sbin/dtrace -s /* * cifsops.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing CIFS operations... Interval 5 secs.\n"); } smb:::op-* { @ops[args[0]->ci_remote, probename] = count(); } profile:::tick-5sec, dtrace:::END { printf("\n %-32s %-30s %8s\n", "Client", "Operation", "Count"); printa(" %-32s %-30s %@8d\n", @ops); trunc(@ops); } ================================================ FILE: Chap7/cifsrwsnoop.d ================================================ #!/usr/sbin/dtrace -s /* * cifsrwsnoop.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-16s %-18s %2s %-10s %6s %s\n", "TIME(us)", "CLIENT", "OP", "OFFSET(KB)", "BYTES", "PATHNAME"); } smb:::op-Read-done, smb:::op-ReadX-done { this->dir = "R"; } smb:::op-Write-done, smb:::op-WriteX-done { this->dir = "W"; } smb:::op-Read-done, smb:::op-ReadX-done, smb:::op-Write-done, smb:::op-WriteX-done { printf("%-16d %-18s %2s %-10d %6d %s\n", timestamp / 1000, args[0]->ci_remote, this->dir, args[2]->soa_offset / 1024, args[2]->soa_count, args[1]->soi_curpath); } ================================================ FILE: Chap7/cifsrwtime.d ================================================ #!/usr/sbin/dtrace -s /* * cifsrwtime.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet inline int TOP_FILES = 10; dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } smb:::op-Read-start, smb:::op-ReadX-start, smb:::op-Write-start, smb:::op-WriteX-start { /* currently the done event fires in the same thread as start */ self->start = timestamp; } smb:::op-Read-done, smb:::op-ReadX-done { this->dir = "read"; } smb:::op-Write-done, smb:::op-WriteX-done { this->dir = "write"; } smb:::op-Read-done, smb:::op-ReadX-done, smb:::op-Write-done, smb:::op-WriteX-done /self->start/ { this->elapsed = timestamp - self->start; @rw[this->dir] = quantize(this->elapsed / 1000); @host[args[0]->ci_remote] = sum(this->elapsed); @file[args[1]->soi_curpath] = sum(this->elapsed); self->start = 0; } dtrace:::END { printf("CIFS read/write distributions (us):\n"); printa(@rw); printf("\nCIFS read/write by host (total us):\n"); normalize(@host, 1000); printa(@host); printf("\nCIFS read/write top %d files (total us):\n", TOP_FILES); normalize(@file, 1000); trunc(@file, TOP_FILES); printa(@file); } ================================================ FILE: Chap7/dnsgetname.d ================================================ #!/usr/sbin/dtrace -Cs /* * dnsgetname.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz typedef struct dns_name { unsigned int magic; unsigned char * ndata; /* truncated */ } dns_name_t; pid$target::getname:entry { self->arg0 = arg0; } pid$target::getname:return /self->arg0/ { this->name = (dns_name_t *)copyin(self->arg0, sizeof (dns_name_t)); printf("%s\n", copyinstr((uintptr_t)this->name->ndata)); self->arg0 = 0; } ================================================ FILE: Chap7/fcerror.d ================================================ #!/usr/sbin/dtrace -s /* * fcerror.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-20s %-12s %-12s %-12s %-12s\n", "TIME", "STATE", "REASON", "ACTION", "EXPLANATION"); } fbt::fctl_pkt_error:entry { self->state = args[1]; self->reason = args[2]; self->action = args[3]; self->expln = args[4]; } fbt::fctl_pkt_error:entry /self->state/ { printf("%-20Y %-12s %-12s %-12s %-12s\n", walltimestamp, stringof(*self->state), stringof(*self->reason), stringof(*self->action), stringof(*self->expln)); self->state = 0; self->reason = 0; self->action = 0; self->expln = 0; } ================================================ FILE: Chap7/fcwho.d ================================================ #!/usr/sbin/dtrace -s /* * fcwho.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing FC... Hit Ctrl-C to end.\n"); } fc::: { @events[args[0]->ci_remote, probename] = count(); } dtrace:::END { printf(" %-26s %14s %8s\n", "REMOTE IP", "FC EVENT", "COUNT"); printa(" %-26s %14s %@8d\n", @events); } ================================================ FILE: Chap7/ftpdfileio.d ================================================ #!/usr/sbin/dtrace -Zs /* * ftpdfileio.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } ftp*:::transfer-done { @[args[1]->fti_cmd, args[1]->fti_pathname] = sum(args[1]->fti_nbytes); } dtrace:::END { printf("\n%8s %12s %s\n", "DIR", "BYTES", "PATHNAME"); printa("%8s %@12d %s\n", @); } ================================================ FILE: Chap7/ftpdxfer.d ================================================ #!/usr/sbin/dtrace -Zs /* * ftpdxfer.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-20s %-8s %9s %-5s %-6s %s\n", "CLIENT", "USER", "LAT(us)", "DIR", "BYTES", "PATH"); } ftp*:::transfer-start { self->start = timestamp; } ftp*:::transfer-done /self->start/ { this->delta = (timestamp - self->start) / 1000; printf("%-20s %-8s %9d %-5s %-6d %s\n", args[0]->ci_remote, args[1]->fti_user, this->delta, args[1]->fti_cmd, args[1]->fti_nbytes, args[1]->fti_pathname); self->start = 0; } ================================================ FILE: Chap7/getaddrinfo.d ================================================ #!/usr/sbin/dtrace -s /* * getaddrinfo.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("%-20s %-12s %s\n", "TIME", "LATENCY(ms)", "HOST"); } pid$target::getaddrinfo:entry { self->host = copyinstr(arg0); self->start = timestamp; } pid$target::getaddrinfo:return /self->start/ { this->delta = (timestamp - self->start) / 1000000; printf("%-20Y %-12d %s\n", walltimestamp, this->delta, self->host); self->host = 0; self->start = 0; } ================================================ FILE: Chap7/httpclients.d ================================================ #!/usr/sbin/dtrace -s /* * httpclients.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing... output every 10 seconds, or Ctrl-C.\n"); } http*:::request-done { @rbytes[args[0]->ci_remote] = sum(args[1]->hri_bytesread); @wbytes[args[0]->ci_remote] = sum(args[1]->hri_byteswritten); } profile:::tick-10sec, dtrace:::END { normalize(@rbytes, 1024); normalize(@wbytes, 1024); printf("\n %-32s %10s %10s\n", "HTTP CLIENT", "FROM(KB)", "TO(KB)"); printa(" %-32s %@10d %@10d\n", @rbytes, @wbytes); trunc(@rbytes); trunc(@wbytes); } ================================================ FILE: Chap7/httpdurls.d ================================================ #!/usr/sbin/dtrace -s /* * httpdurls.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet inline string WEB_SERVER_PROCESS_NAME = "httpd"; dtrace:::BEGIN { printf("Tracing GET from %s processes... Hit Ctrl-C to end.\n", WEB_SERVER_PROCESS_NAME); } syscall::read:entry /execname == WEB_SERVER_PROCESS_NAME/ { self->buf = arg1; } syscall::read:return /self->buf && arg1 > 10/ { this->req = (char *)copyin(self->buf, arg1); this->get = strstr(this->req, "GET") != NULL; } syscall::read:return /self->buf && this->get/ { this->line = strtok(this->req, "\r"); this->word0 = this->line != NULL ? strtok(this->line, " ") : ""; this->word1 = this->line != NULL ? strtok(NULL, " ") : ""; this->word2 = this->line != NULL ? strtok(NULL, " ") : ""; } syscall::read:return /this->word0 != NULL && this->word1 != NULL && this->word2 != NULL && this->word0 == "GET"/ { @[stringof(this->word2), stringof(this->word1)] = count(); } syscall::read:return { self->buf = 0; } dtrace:::END { printf(" %-10s %-54s %10s\n", "PROTOCOL", "URL", "COUNT"); printa(" %-10s %-54s %@10d\n", @); } ================================================ FILE: Chap7/httperrors.d ================================================ #!/usr/sbin/dtrace -s /* * httperrors.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing HTTP errors... Hit Ctrl-C for report.\n"); } http*:::request-done /args[1]->hri_respcode >= 400 && args[1]->hri_respcode < 600/ { @[args[0]->ci_remote, args[1]->hri_respcode, args[1]->hri_method, args[1]->hri_uri] = count(); } dtrace:::END { printf("%8s %-16s %-4s %-6s %s\n", "COUNT", "CLIENT", "CODE", "METHOD", "URI"); printa("%@8d %-16s %-4d %-6s %s\n", @); } ================================================ FILE: Chap7/httpio.d ================================================ #!/usr/sbin/dtrace -s /* * httpio.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing HTTP... Hit Ctrl-C for report.\n"); } http*:::request-done { @["received bytes"] = quantize(args[1]->hri_bytesread); @["sent bytes"] = quantize(args[1]->hri_byteswritten); } ================================================ FILE: Chap7/iscsicmds.d ================================================ #!/usr/sbin/dtrace -s /* * iscsicmds.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet string scsi_cmd[uchar_t]; dtrace:::BEGIN { /* * The following was generated from the SCSI_CMDS_KEY_STRINGS * definitions in /usr/include/sys/scsi/generic/commands.h using sed. */ scsi_cmd[0x00] = "test_unit_ready"; scsi_cmd[0x01] = "rezero/rewind"; scsi_cmd[0x03] = "request_sense"; scsi_cmd[0x04] = "format"; scsi_cmd[0x05] = "read_block_limits"; scsi_cmd[0x07] = "reassign"; scsi_cmd[0x08] = "read"; scsi_cmd[0x0a] = "write"; scsi_cmd[0x0b] = "seek"; scsi_cmd[0x0f] = "read_reverse"; scsi_cmd[0x10] = "write_file_mark"; scsi_cmd[0x11] = "space"; scsi_cmd[0x12] = "inquiry"; scsi_cmd[0x13] = "verify"; scsi_cmd[0x14] = "recover_buffer_data"; scsi_cmd[0x15] = "mode_select"; scsi_cmd[0x16] = "reserve"; scsi_cmd[0x17] = "release"; scsi_cmd[0x18] = "copy"; scsi_cmd[0x19] = "erase_tape"; scsi_cmd[0x1a] = "mode_sense"; scsi_cmd[0x1b] = "load/start/stop"; scsi_cmd[0x1c] = "get_diagnostic_results"; scsi_cmd[0x1d] = "send_diagnostic_command"; scsi_cmd[0x1e] = "door_lock"; scsi_cmd[0x23] = "read_format_capacity"; scsi_cmd[0x25] = "read_capacity"; scsi_cmd[0x28] = "read(10)"; scsi_cmd[0x2a] = "write(10)"; scsi_cmd[0x2b] = "seek(10)"; scsi_cmd[0x2e] = "write_verify"; scsi_cmd[0x2f] = "verify(10)"; scsi_cmd[0x30] = "search_data_high"; scsi_cmd[0x31] = "search_data_equal"; scsi_cmd[0x32] = "search_data_low"; scsi_cmd[0x33] = "set_limits"; scsi_cmd[0x34] = "read_position"; scsi_cmd[0x35] = "synchronize_cache"; scsi_cmd[0x37] = "read_defect_data"; scsi_cmd[0x39] = "compare"; scsi_cmd[0x3a] = "copy_verify"; scsi_cmd[0x3b] = "write_buffer"; scsi_cmd[0x3c] = "read_buffer"; scsi_cmd[0x3e] = "read_long"; scsi_cmd[0x3f] = "write_long"; scsi_cmd[0x44] = "report_densities/read_header"; scsi_cmd[0x4c] = "log_select"; scsi_cmd[0x4d] = "log_sense"; scsi_cmd[0x55] = "mode_select(10)"; scsi_cmd[0x56] = "reserve(10)"; scsi_cmd[0x57] = "release(10)"; scsi_cmd[0x5a] = "mode_sense(10)"; scsi_cmd[0x5e] = "persistent_reserve_in"; scsi_cmd[0x5f] = "persistent_reserve_out"; scsi_cmd[0x80] = "write_file_mark(16)"; scsi_cmd[0x81] = "read_reverse(16)"; scsi_cmd[0x83] = "extended_copy"; scsi_cmd[0x88] = "read(16)"; scsi_cmd[0x8a] = "write(16)"; scsi_cmd[0x8c] = "read_attribute"; scsi_cmd[0x8d] = "write_attribute"; scsi_cmd[0x8f] = "verify(16)"; scsi_cmd[0x91] = "space(16)"; scsi_cmd[0x92] = "locate(16)"; scsi_cmd[0x9e] = "service_action_in(16)"; scsi_cmd[0x9f] = "service_action_out(16)"; scsi_cmd[0xa0] = "report_luns"; scsi_cmd[0xa2] = "security_protocol_in"; scsi_cmd[0xa3] = "maintenance_in"; scsi_cmd[0xa4] = "maintenance_out"; scsi_cmd[0xa8] = "read(12)"; scsi_cmd[0xa9] = "service_action_out(12)"; scsi_cmd[0xaa] = "write(12)"; scsi_cmd[0xab] = "service_action_in(12)"; scsi_cmd[0xac] = "get_performance"; scsi_cmd[0xAF] = "verify(12)"; scsi_cmd[0xb5] = "security_protocol_out"; printf("Tracing... Hit Ctrl-C to end.\n"); } iscsi:::scsi-command { this->code = *args[2]->ic_cdb; this->cmd = scsi_cmd[this->code] != NULL ? scsi_cmd[this->code] : lltostr(this->code); @[args[0]->ci_remote, this->cmd] = count(); } dtrace:::END { printf(" %-24s %-36s %s\n", "iSCSI CLIENT", "SCSI COMMAND", "COUNT"); printa(" %-24s %-36s %@d\n", @); } ================================================ FILE: Chap7/iscsirwsnoop.d ================================================ #!/usr/sbin/dtrace -s /* * iscsirwsnoop.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-16s %-18s %2s %-8s %6s\n", "TIME(us)", "CLIENT", "OP", "BYTES", "LUN"); } iscsi*:::data-send { printf("%-16d %-18s %2s %-8d %6d\n", timestamp / 1000, args[0]->ci_remote, "R", args[1]->ii_datalen, args[1]->ii_lun); } iscsi*:::data-receive { printf("%-16d %-18s %2s %-8d %6d\n", timestamp / 1000, args[0]->ci_remote, "W", args[1]->ii_datalen, args[1]->ii_lun); } ================================================ FILE: Chap7/iscsirwsnoopsdt.d ================================================ #!/usr/sbin/dtrace -s /* * iscsirwsnoopsdt.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-16s %-18s %2s %-8s %6s\n", "TIME(us)", "CLIENT", "OP", "BYTES", "LUN"); } iscsi:::xfer-start { printf("%-16d %-18s %2s %-8d %6d\n", timestamp / 1000, args[0]->ci_remote, arg8 ? "R" : "W", args[2]->xfer_len, args[1]->ii_lun); } ================================================ FILE: Chap7/iscsirwtime.d ================================================ #!/usr/sbin/dtrace -s /* * iscsirwtime.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet inline int TOP_TARGETS = 10; dtrace:::BEGIN { printf("Tracing iSCSI target... Hit Ctrl-C to end.\n"); } iscsi:::xfer-start { start[arg1] = timestamp; } iscsi:::xfer-done /start[arg1] != 0/ { this->elapsed = timestamp - start[arg1]; @rw[arg8 ? "read" : "write"] = quantize(this->elapsed / 1000); @host[args[0]->ci_remote] = sum(this->elapsed); @targ[args[1]->ii_target] = sum(this->elapsed); start[arg1] = 0; } dtrace:::END { printf("iSCSI read/write distributions (us):\n"); printa(@rw); printf("\niSCSI read/write by client (total us):\n"); normalize(@host, 1000); printa(@host); printf("\niSCSI read/write top %d targets (total us):\n", TOP_TARGETS); normalize(@targ, 1000); trunc(@targ, TOP_TARGETS); printa(@targ); } ================================================ FILE: Chap7/iscsiterr.d ================================================ #!/usr/sbin/dtrace -Cs /* * iscsiterr.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz typedef enum idm_status { IDM_STATUS_SUCCESS = 0, IDM_STATUS_FAIL, IDM_STATUS_NORESOURCES, IDM_STATUS_REJECT, IDM_STATUS_IO, IDM_STATUS_ABORTED, IDM_STATUS_SUSPENDED, IDM_STATUS_HEADER_DIGEST, IDM_STATUS_DATA_DIGEST, IDM_STATUS_PROTOCOL_ERROR, IDM_STATUS_LOGIN_FAIL } idm_status_t; dtrace:::BEGIN { status[IDM_STATUS_FAIL] = "FAIL"; status[IDM_STATUS_NORESOURCES] = "NORESOURCES"; status[IDM_STATUS_REJECT] = "REJECT"; status[IDM_STATUS_IO] = "IO"; status[IDM_STATUS_ABORTED] = "ABORTED"; status[IDM_STATUS_SUSPENDED] = "SUSPENDED"; status[IDM_STATUS_HEADER_DIGEST] = "HEADER_DIGEST"; status[IDM_STATUS_DATA_DIGEST] = "DATA_DIGEST"; status[IDM_STATUS_PROTOCOL_ERROR] = "PROTOCOL_ERROR"; status[IDM_STATUS_LOGIN_FAIL] = "LOGIN_FAIL"; printf("%-20s %-20s %s\n", "TIME", "CLIENT", "ERROR"); } fbt::idm_pdu_complete:entry /arg1 != IDM_STATUS_SUCCESS/ { this->ic = args[0]->isp_ic; this->remote = (this->ic->ic_raddr.ss_family == AF_INET) ? inet_ntoa((ipaddr_t *)&((struct sockaddr_in *)& this->ic->ic_raddr)->sin_addr) : inet_ntoa6(&((struct sockaddr_in6 *)& this->ic->ic_raddr)->sin6_addr); this->err = status[arg1] != NULL ? status[arg1] : lltostr(arg1); printf("%-20Y %-20s %s\n", walltimestamp, this->remote, this->err); } ================================================ FILE: Chap7/iscsiwho.d ================================================ #!/usr/sbin/dtrace -s /* * iscsiwho.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing iSCSI... Hit Ctrl-C to end.\n"); } iscsi*::: { @events[args[0]->ci_remote, probename] = count(); } dtrace:::END { printf(" %-26s %14s %8s\n", "REMOTE IP", "iSCSI EVENT", "COUNT"); printa(" %-26s %14s %@8d\n", @events); } ================================================ FILE: Chap7/ldapsyslog.d ================================================ #!/usr/sbin/dtrace -s /* * ldapsyslog.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing PID %d...\n", $target); } pid$target::syslog:entry { self->in_syslog = 1; } pid$target::strlen:entry /self->in_syslog/ { self->buf = arg0; } pid$target::syslog:return /self->buf/ { trace(copyinstr(self->buf)); self->in_syslog = 0; self->buf = 0; } ================================================ FILE: Chap7/nfsv3commit.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv3commit.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet /* From /usr/include/nfs/nfs.h */ inline int UNSTABLE = 0; int last[string]; dtrace:::BEGIN { printf("Tracing NFSv3 writes and commits... Hit Ctrl-C to end.\n"); } nfsv3:::op-write-start /args[2]->stable == UNSTABLE/ { @write[args[1]->noi_curpath] = sum(args[2]->count); } nfsv3:::op-write-start /args[2]->stable != UNSTABLE/ { @syncwrite[args[1]->noi_curpath] = sum(args[2]->count); } nfsv3:::op-commit-start /(this->last = last[args[1]->noi_curpath])/ { this->delta = (timestamp - this->last) / 1000; @time[args[1]->noi_curpath] = quantize(this->delta); } nfsv3:::op-commit-start { @committed[args[1]->noi_curpath] = sum(args[2]->count); @commit[args[1]->noi_curpath] = quantize(args[2]->count / 1024); last[args[1]->noi_curpath] = timestamp; } dtrace:::END { normalize(@write, 1024); normalize(@syncwrite, 1024); normalize(@committed, 1024); printf("\nCommited vs uncommited written Kbytes by path:\n\n"); printf(" %-10s %-10s %-10s %s\n", "WRITE", "SYNCWRITE", "COMMITTED", "PATH"); printa(" %@-10d %@-10d %@-10d %s\n", @write, @syncwrite, @committed); printf("\n\nCommit Kbytes by path:\n"); printa(@commit); printf("\nTime between commits (us) by path:\n"); printa(@time); } ================================================ FILE: Chap7/nfsv3disk.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv3disk.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { interval = 5; printf("Tracing... Interval %d secs.\n", interval); tick = interval; } /* NFSv3 read/write */ nfsv3:::op-read-done { @nfsrb = sum(args[2]->res_u.ok.data.data_len); } nfsv3:::op-write-done { @nfswb = sum(args[2]->res_u.ok.count); } /* Disk read/write */ io:::done /args[0]->b_flags & B_READ/ { @diskrb = sum(args[0]->b_bcount); } io:::done /args[0]->b_flags & B_WRITE/ { @diskwb = sum(args[0]->b_bcount); } /* Filesystem hit rate: ZFS */ sdt:zfs::arc-hit { @fshit = count(); } sdt:zfs::arc-miss { @fsmiss = count(); } profile:::tick-1sec /--tick == 0/ { normalize(@nfsrb, 1024 * interval); normalize(@nfswb, 1024 * interval); normalize(@diskrb, 1024 * interval); normalize(@diskwb, 1024 * interval); normalize(@fshit, interval); normalize(@fsmiss, interval); printf("\n %10s %10s %10s %10s %10s %10s\n", "NFS kr/s", "ZFS hit/s", "ZFS miss/s", "Disk kr/s", "NFS kw/s", "Disk kw/s"); printa(" %@10d %@10d %@10d %@10d %@10d %@10d\n", @nfsrb, @fshit, @fsmiss, @diskrb, @nfswb, @diskwb); trunc(@nfsrb); trunc(@nfswb); trunc(@diskrb); trunc(@diskwb); trunc(@fshit); trunc(@fsmiss); tick = interval; } ================================================ FILE: Chap7/nfsv3errors.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv3errors.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { /* See NFS3ERR_* in /usr/include/nfs/nfs.h */ nfs3err[0] = "NFS3_OK"; nfs3err[1] = "PERM"; nfs3err[2] = "NOENT"; nfs3err[5] = "IO"; nfs3err[6] = "NXIO"; nfs3err[13] = "ACCES"; nfs3err[17] = "EXIST"; nfs3err[18] = "XDEV"; nfs3err[19] = "NODEV"; nfs3err[20] = "NOTDIR"; nfs3err[21] = "ISDIR"; nfs3err[22] = "INVAL"; nfs3err[27] = "FBIG"; nfs3err[28] = "NOSPC"; nfs3err[30] = "ROFS"; nfs3err[31] = "MLINK"; nfs3err[63] = "NAMETOOLONG"; nfs3err[66] = "NOTEMPTY"; nfs3err[69] = "DQUOT"; nfs3err[70] = "STALE"; nfs3err[71] = "REMOTE"; nfs3err[10001] = "BADHANDLE"; nfs3err[10002] = "NOT_SYNC"; nfs3err[10003] = "BAD_COOKIE"; nfs3err[10004] = "NOTSUPP"; nfs3err[10005] = "TOOSMALL"; nfs3err[10006] = "SERVERFAULT"; nfs3err[10007] = "BADTYPE"; nfs3err[10008] = "JUKEBOX"; printf(" %-18s %5s %-12s %-16s %s\n", "NFSv3 EVENT", "ERR", "CODE", "CLIENT", "PATHNAME"); } nfsv3:::op-*-done /args[2]->status != 0/ { this->err = args[2]->status; this->str = nfs3err[this->err] != NULL ? nfs3err[this->err] : "?"; printf(" %-18s %5d %-12s %-16s %s\n", probename, this->err, this->str, args[0]->ci_remote, args[1]->noi_curpath); } ================================================ FILE: Chap7/nfsv3fbtrws.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv3fbtrws.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-16s %-18s %2s %-10s %6s %s\n", "TIME(us)", "CLIENT", "OP", "OFFSET(KB)", "BYTES", "PATHNAME"); } fbt::rfs3_read:entry { self->in_rfs3 = 1; /* args[0] is READ3args */ self->offset = args[0]->offset / 1024; self->count = args[0]->count; self->req = args[3]; self->dir = "R"; } fbt::rfs3_write:entry { self->in_rfs3 = 1; /* args[0] is WRITE3args */ self->offset = args[0]->offset / 1024; self->count = args[0]->count; self->req = args[3]; self->dir = "W"; } /* trace nfs3_fhtovp() to retrieve the vnode_t */ fbt::nfs3_fhtovp:return /self->in_rfs3/ { this->vp = args[1]; this->socket = (struct sockaddr_in *)self->req->rq_xprt->xp_xpc.xpc_rtaddr.buf; /* DTrace 1.0: no inet functions, no this->strings */ this->a = (uint8_t *)&this->socket->sin_addr.S_un.S_addr; self->addr1 = strjoin(lltostr(this->a[0] + 0ULL), strjoin(".", strjoin(lltostr(this->a[1] + 0ULL), "."))); self->addr2 = strjoin(lltostr(this->a[2] + 0ULL), strjoin(".", lltostr(this->a[3] + 0ULL))); self->address = strjoin(self->addr1, self->addr2); printf("%-16d %-18s %2s %-10d %6d %s\n", timestamp / 1000, self->address, self->dir, self->offset, self->count, this->vp->v_path != NULL ? stringof(this->vp->v_path) : ""); self->addr1 = 0; self->addr2 = 0; self->address = 0; self->dir = 0; self->req = 0; self->offset = 0; self->count = 0; self->in_rfs3 = 0; } ================================================ FILE: Chap7/nfsv3fileio.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv3fileio.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing... Hit Ctrl-C to end.\n"); } nfsv3:::op-read-done { @readbytes[args[1]->noi_curpath] = sum(args[2]->res_u.ok.data.data_len); } nfsv3:::op-write-done { @writebytes[args[1]->noi_curpath] = sum(args[2]->res_u.ok.count); } dtrace:::END { printf("\n%12s %12s %s\n", "Rbytes", "Wbytes", "Pathname"); printa("%@12d %@12d %s\n", @readbytes, @writebytes); } ================================================ FILE: Chap7/nfsv3ops.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv3ops.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing NFSv3 operations... Interval 5 secs.\n"); } nfsv3:::op-*-start { @ops[args[0]->ci_remote, probename] = count(); } profile:::tick-5sec, dtrace:::END { printf("\n %-32s %-28s %8s\n", "Client", "Operation", "Count"); printa(" %-32s %-28s %@8d\n", @ops); trunc(@ops); } ================================================ FILE: Chap7/nfsv3rwsnoop.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv3rwsnoop.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-16s %-18s %2s %-10s %6s %s\n", "TIME(us)", "CLIENT", "OP", "OFFSET(KB)", "BYTES", "PATHNAME"); } nfsv3:::op-read-start { printf("%-16d %-18s %2s %-10d %6d %s\n", timestamp / 1000, args[0]->ci_remote, "R", args[2]->offset / 1024, args[2]->count, args[1]->noi_curpath); } nfsv3:::op-write-start { printf("%-16d %-18s %2s %-10d %6d %s\n", timestamp / 1000, args[0]->ci_remote, "W", args[2]->offset / 1024, args[2]->data.data_len, args[1]->noi_curpath); } ================================================ FILE: Chap7/nfsv3rwtime.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv3rwtime.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet inline int TOP_FILES = 10; dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } nfsv3:::op-read-start, nfsv3:::op-write-start { start[args[1]->noi_xid] = timestamp; } nfsv3:::op-read-done, nfsv3:::op-write-done /start[args[1]->noi_xid] != 0/ { this->elapsed = timestamp - start[args[1]->noi_xid]; @rw[probename == "op-read-done" ? "read" : "write"] = quantize(this->elapsed / 1000); @host[args[0]->ci_remote] = sum(this->elapsed); @file[args[1]->noi_curpath] = sum(this->elapsed); start[args[1]->noi_xid] = 0; } dtrace:::END { printf("NFSv3 read/write distributions (us):\n"); printa(@rw); printf("\nNFSv3 read/write by host (total us):\n"); normalize(@host, 1000); printa(@host); printf("\nNFSv3 read/write top %d files (total us):\n", TOP_FILES); normalize(@file, 1000); trunc(@file, TOP_FILES); printa(@file); } ================================================ FILE: Chap7/nfsv3syncwrite.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv3syncwrite.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { /* See /usr/include/nfs/nfs.h */ stable_how[0] = "Unstable"; stable_how[1] = "Data_Sync"; stable_how[2] = "File_Sync"; printf("Tracing NFSv3 writes and commits... Hit Ctrl-C to end.\n"); } nfsv3:::op-write-start { @["write", stable_how[args[2]->stable], args[1]->noi_curpath] = count(); } nfsv3:::op-commit-start { @["commit", "-", args[1]->noi_curpath] = count(); } dtrace:::END { printf(" %-7s %-10s %-10s %s\n", "OP", "TYPE", "COUNT", "PATH"); printa(" %-7s %-10s %@-10d %s\n", @); } ================================================ FILE: Chap7/nfsv4commit.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv4commit.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet /* From /usr/include/nfs/nfs4_kprot.h */ inline int UNSTABLE = 0; int last[string]; dtrace:::BEGIN { printf("Tracing NFSv4 writes and commits... Hit Ctrl-C to end.\n"); } nfsv4:::op-write-start /args[2]->stable == UNSTABLE/ { @write[args[1]->noi_curpath] = sum(args[2]->data_len); } nfsv4:::op-write-start /args[2]->stable != UNSTABLE/ { @syncwrite[args[1]->noi_curpath] = sum(args[2]->data_len); } nfsv4:::op-commit-start /(this->last = last[args[1]->noi_curpath])/ { this->delta = (timestamp - this->last) / 1000; @time[args[1]->noi_curpath] = quantize(this->delta); } nfsv4:::op-commit-start { @committed[args[1]->noi_curpath] = sum(args[2]->count); @commit[args[1]->noi_curpath] = quantize(args[2]->count / 1024); last[args[1]->noi_curpath] = timestamp; } dtrace:::END { normalize(@write, 1024); normalize(@syncwrite, 1024); normalize(@committed, 1024); printf("\nCommited vs uncommited written Kbytes by path:\n\n"); printf(" %-10s %-10s %-10s %s\n", "WRITE", "SYNCWRITE", "COMMITTED", "PATH"); printa(" %@-10d %@-10d %@-10d %s\n", @write, @syncwrite, @committed); printf("\n\nCommit Kbytes by path:\n"); printa(@commit); printf("\nTime between commits (us) by path:\n"); printa(@time); } ================================================ FILE: Chap7/nfsv4deleg.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv4deleg.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { deleg[0] = "none"; deleg[1] = "read"; deleg[2] = "write"; deleg[-1] = "any"; printf("Tracing NFSv4 delegation events...\n"); printf("%-21s %-20s %s\n", "TIME", "EVENT", "DETAILS"); } fbt::rfs4_grant_delegation:entry { this->path = stringof(args[1]->rs_finfo->rf_vp->v_path); this->client = args[1]->rs_owner->ro_client->rc_clientid; this->type = deleg[arg0] != NULL ? deleg[arg0] : ""; printf("%-21Y %-20s %-8s %s\n", walltimestamp, "Grant Delegation", this->type, this->path); } fbt::rfs4_recall_deleg:entry { this->path = stringof(args[0]->rf_vp->v_path); printf("%-21Y %-20s %-8s %s\n", walltimestamp, "Recall Delegation", ".", this->path); } fbt::rfs4_deleg_state_expiry:entry { this->dsp = (rfs4_deleg_state_t *)arg0; this->path = stringof(this->dsp->rds_finfo->rf_vp->v_path); printf("%-21Y %-20s %-8s %s\n", walltimestamp, "Delegation Expiry", ".", this->path); } ================================================ FILE: Chap7/nfsv4errors.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv4errors.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { /* See NFS4ERR_* in /usr/include/nfs/nfs4_kprot.h */ nfs4err[0] = "NFS4_OK"; nfs4err[1] = "PERM"; nfs4err[2] = "NOENT"; nfs4err[5] = "IO"; nfs4err[6] = "NXIO"; nfs4err[13] = "ACCESS"; nfs4err[17] = "EXIST"; nfs4err[18] = "XDEV"; nfs4err[20] = "NOTDIR"; nfs4err[21] = "ISDIR"; nfs4err[22] = "INVAL"; nfs4err[27] = "FBIG"; nfs4err[28] = "NOSPC"; nfs4err[30] = "ROFS"; nfs4err[31] = "MLINK"; nfs4err[63] = "NAMETOOLONG"; nfs4err[66] = "NOTEMPTY"; nfs4err[69] = "DQUOT"; nfs4err[70] = "STALE"; nfs4err[10001] = "BADHANDLE"; nfs4err[10003] = "BAD_COOKIE"; nfs4err[10004] = "NOTSUPP"; nfs4err[10005] = "TOOSMALL"; nfs4err[10006] = "SERVERFAULT"; nfs4err[10007] = "BADTYPE"; nfs4err[10008] = "DELAY"; nfs4err[10009] = "SAME"; nfs4err[10010] = "DENIED"; nfs4err[10011] = "EXPIRED"; nfs4err[10012] = "LOCKED"; nfs4err[10013] = "GRACE"; nfs4err[10014] = "FHEXPIRED"; nfs4err[10015] = "SHARE_DENIED"; nfs4err[10016] = "WRONGSEC"; nfs4err[10017] = "CLID_INUSE"; nfs4err[10018] = "RESOURCE"; nfs4err[10019] = "MOVED"; nfs4err[10020] = "NOFILEHANDLE"; nfs4err[10021] = "MINOR_VERS_MISMATCH"; nfs4err[10022] = "STALE_CLIENTID"; nfs4err[10023] = "STALE_STATEID"; nfs4err[10024] = "OLD_STATEID"; nfs4err[10025] = "BAD_STATEID"; nfs4err[10026] = "BAD_SEQID"; nfs4err[10027] = "NOT_SAME"; nfs4err[10028] = "LOCK_RANGE"; nfs4err[10029] = "SYMLINK"; nfs4err[10030] = "RESTOREFH"; nfs4err[10031] = "LEASE_MOVED"; nfs4err[10032] = "ATTRNOTSUPP"; nfs4err[10033] = "NO_GRACE"; nfs4err[10034] = "RECLAIM_BAD"; nfs4err[10035] = "RECLAIM_CONFLICT"; nfs4err[10036] = "BADXDR"; nfs4err[10037] = "LOCKS_HELD"; nfs4err[10038] = "OPENMODE"; nfs4err[10039] = "BADOWNER"; nfs4err[10040] = "BADCHAR"; nfs4err[10041] = "BADNAME"; nfs4err[10042] = "BAD_RANGE"; nfs4err[10043] = "LOCK_NOTSUPP"; nfs4err[10044] = "OP_ILLEGAL"; nfs4err[10045] = "DEADLOCK"; nfs4err[10046] = "FILE_OPEN"; nfs4err[10047] = "ADMIN_REVOKED"; nfs4err[10048] = "CB_PATH_DOWN"; printf(" %-18s %5s %-12s %-16s %s\n", "NFSv4 EVENT", "ERR", "CODE", "CLIENT", "PATHNAME"); } nfsv4:::op-*-done /args[2]->status != 0 && args[2]->status != 10009/ { this->err = args[2]->status; this->str = nfs4err[this->err] != NULL ? nfs4err[this->err] : "?"; printf(" %-18s %5d %-12s %-16s %s\n", probename, this->err, this->str, args[0]->ci_remote, args[1]->noi_curpath); } ================================================ FILE: Chap7/nfsv4fileio.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv4fileio.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing... Hit Ctrl-C to end.\n"); } nfsv4:::op-read-done { @readbytes[args[1]->noi_curpath] = sum(args[2]->data_len); } nfsv4:::op-write-done { @writebytes[args[1]->noi_curpath] = sum(args[2]->count); } dtrace:::END { printf("\n%12s %12s %s\n", "Rbytes", "Wbytes", "Pathname"); printa("%@12d %@12d %s\n", @readbytes, @writebytes); } ================================================ FILE: Chap7/nfsv4ops.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv4ops.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing NFSv4 operations... Interval 5 secs.\n"); } nfsv4:::op-*-start { @ops[args[0]->ci_remote, probename] = count(); } profile:::tick-5sec, dtrace:::END { printf("\n %-32s %-28s %8s\n", "Client", "Operation", "Count"); printa(" %-32s %-28s %@8d\n", @ops); trunc(@ops); } ================================================ FILE: Chap7/nfsv4rwsnoop.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv4rwsnoop.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-16s %-18s %2s %-10s %6s %s\n", "TIME(us)", "CLIENT", "OP", "OFFSET(KB)", "BYTES", "PATHNAME"); } nfsv4:::op-read-start { printf("%-16d %-18s %2s %-10d %6d %s\n", timestamp / 1000, args[0]->ci_remote, "R", args[2]->offset / 1024, args[2]->count, args[1]->noi_curpath); } nfsv4:::op-write-start { printf("%-16d %-18s %2s %-10d %6d %s\n", timestamp / 1000, args[0]->ci_remote, "W", args[2]->offset / 1024, args[2]->data_len, args[1]->noi_curpath); } ================================================ FILE: Chap7/nfsv4rwtime.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv4rwtime.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet inline int TOP_FILES = 10; dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } nfsv4:::op-read-start, nfsv4:::op-write-start { start[args[1]->noi_xid] = timestamp; } nfsv4:::op-read-done, nfsv4:::op-write-done /start[args[1]->noi_xid] != 0/ { this->elapsed = timestamp - start[args[1]->noi_xid]; @rw[probename == "op-read-done" ? "read" : "write"] = quantize(this->elapsed / 1000); @host[args[0]->ci_remote] = sum(this->elapsed); @file[args[1]->noi_curpath] = sum(this->elapsed); start[args[1]->noi_xid] = 0; } dtrace:::END { printf("NFSv4 read/write distributions (us):\n"); printa(@rw); printf("\nNFSv4 read/write by host (total us):\n"); normalize(@host, 1000); printa(@host); printf("\nNFSv4 read/write top %d files (total us):\n", TOP_FILES); normalize(@file, 1000); trunc(@file, TOP_FILES); printa(@file); } ================================================ FILE: Chap7/nfsv4syncwrite.d ================================================ #!/usr/sbin/dtrace -s /* * nfsv4syncwrite.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { /* See /usr/include/nfs/nfs4_kprot.h */ stable_how[0] = "Unstable"; stable_how[1] = "Data_Sync"; stable_how[2] = "File_Sync"; printf("Tracing NFSv4 writes and commits... Hit Ctrl-C to end.\n"); } nfsv4:::op-write-start { @["write", stable_how[args[2]->stable], args[1]->noi_curpath] = count(); } nfsv4:::op-commit-start { @["commit", "-", args[1]->noi_curpath] = count(); } dtrace:::END { printf(" %-7s %-10s %-10s %s\n", "OP", "TYPE", "COUNT", "PATH"); printa(" %-7s %-10s %@-10d %s\n", @); } ================================================ FILE: Chap7/nismatch.d ================================================ #!/usr/sbin/dtrace -s /* * nismatch.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("%-20s %-16s %-16s %s\n", "TIME", "DOMAIN", "MAP", "KEY"); } pid$target::ypset_current_map:entry { self->map = copyinstr(arg0); self->domain = copyinstr(arg1); } pid$target::finddatum:entry /self->map != NULL/ { printf("%-20Y %-16s %-16s %S\n", walltimestamp, self->domain, self->map, copyinstr(arg1)); } ================================================ FILE: Chap7/proftpdcmd.d ================================================ #!/usr/sbin/dtrace -s /* * proftpdcmd.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-20s %10s %s\n", "TIME", "LAT(us)", "FTP CMD"); } /* on this proftpd version, pr_netio_telnet_gets() returns the FTP cmd */ pid$target:proftpd:pr_netio_telnet_gets:return { self->cmd = copyinstr(arg1); self->start = timestamp; } pid$target:proftpd:pr_netio_telnet_gets:entry /self->start/ { this->delta = (timestamp - self->start) / 1000; /* self->cmd already contains "\r\n" */ printf("%-20Y %10d %s", walltimestamp, this->delta, self->cmd); self->start = 0; self->cmd = 0; } ================================================ FILE: Chap7/proftpdio.d ================================================ #!/usr/sbin/dtrace -s /* * proftpdio.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { interval = 5; printf("Tracing... Output every %d seconds.\n", interval); printf(" FTPD %4s %8s %8s %8s %8s %10s\n", "r/s", "w/s", "kr/s", "kw/s", "cmd/s", "cmd_t(ms)"); tick = interval; @readb = sum(0); /* trigger output */ } pid$target:proftpd:pr_netio_read:return /arg1 > 0/ { @writes = count(); @writeb = sum(arg1); } pid$target:proftpd:pr_netio_write:entry /arg2 > 0/ { @reads = count(); @readb = sum(arg2); } pid$target:proftpd:pr_netio_telnet_gets:return { @cmds = count(); self->start = timestamp; } pid$target:proftpd:pr_netio_telnet_gets:entry { this->delta = (timestamp - self->start) / 1000000; @svct = avg(this->delta); } profile:::tick-1sec /--tick == 0/ { normalize(@reads, interval); normalize(@readb, interval * 1024); normalize(@writes, interval); normalize(@writeb, interval * 1024); normalize(@cmds, interval); printa(" %@8d %@8d %@8d %@8d %@8d %@10d\n", @reads, @writes, @readb, @writeb, @cmds, @svct); clear(@reads); clear(@readb); clear(@writes); clear(@writeb); clear(@cmds); clear(@svct); tick = interval; } ================================================ FILE: Chap7/proftpdtime.d ================================================ #!/usr/sbin/dtrace -s /* * proftpdtime.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } /* on this proftpd version, pr_netio_telnet_gets() returns the FTP cmd */ pid$target:proftpd:pr_netio_telnet_gets:return { self->cmd = copyinstr(arg1); self->start = timestamp; } pid$target:proftpd:pr_netio_telnet_gets:entry /self->start/ { this->delta = (timestamp - self->start) / 1000000; @[self->cmd] = lquantize(this->delta, 0, 1000, 10); self->start = 0; self->cmd = 0; } dtrace:::END { printf("FTP command times (ms):\n"); printa(@); } ================================================ FILE: Chap7/scpwatcher.d ================================================ #!/usr/sbin/dtrace -qs /* * scpwatcher.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ inline int stdout = 1; syscall::write:entry /execname == "scp" && arg0 == stdout/ { printf("%s\n", copyinstr(arg1)); } ================================================ FILE: Chap7/scsicmds.d ================================================ scsi_cmd[0x00] = "test_unit_ready"; /* * scsicmds.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ scsi_cmd[0x01] = "rezero/rewind"; scsi_cmd[0x03] = "request_sense"; scsi_cmd[0x04] = "format"; scsi_cmd[0x05] = "read_block_limits"; scsi_cmd[0x07] = "reassign"; scsi_cmd[0x08] = "read"; scsi_cmd[0x0a] = "write"; scsi_cmd[0x0b] = "seek"; scsi_cmd[0x0f] = "read_reverse"; scsi_cmd[0x10] = "write_file_mark"; scsi_cmd[0x11] = "space"; scsi_cmd[0x12] = "inquiry"; scsi_cmd[0x13] = "verify"; scsi_cmd[0x14] = "recover_buffer_data"; scsi_cmd[0x15] = "mode_select"; scsi_cmd[0x16] = "reserve"; scsi_cmd[0x17] = "release"; scsi_cmd[0x18] = "copy"; scsi_cmd[0x19] = "erase_tape"; scsi_cmd[0x1a] = "mode_sense"; scsi_cmd[0x1b] = "load/start/stop"; scsi_cmd[0x1c] = "get_diagnostic_results"; scsi_cmd[0x1d] = "send_diagnostic_command"; scsi_cmd[0x1e] = "door_lock"; scsi_cmd[0x23] = "read_format_capacity"; scsi_cmd[0x25] = "read_capacity"; scsi_cmd[0x28] = "read(10)"; scsi_cmd[0x2a] = "write(10)"; scsi_cmd[0x2b] = "seek(10)"; scsi_cmd[0x2e] = "write_verify"; scsi_cmd[0x2f] = "verify(10)"; scsi_cmd[0x30] = "search_data_high"; scsi_cmd[0x31] = "search_data_equal"; scsi_cmd[0x32] = "search_data_low"; scsi_cmd[0x33] = "set_limits"; scsi_cmd[0x34] = "read_position"; scsi_cmd[0x35] = "synchronize_cache"; scsi_cmd[0x37] = "read_defect_data"; scsi_cmd[0x39] = "compare"; scsi_cmd[0x3a] = "copy_verify"; scsi_cmd[0x3b] = "write_buffer"; scsi_cmd[0x3c] = "read_buffer"; scsi_cmd[0x3e] = "read_long"; scsi_cmd[0x3f] = "write_long"; scsi_cmd[0x44] = "report_densities/read_header"; scsi_cmd[0x4c] = "log_select"; scsi_cmd[0x4d] = "log_sense"; scsi_cmd[0x55] = "mode_select(10)"; scsi_cmd[0x56] = "reserve(10)"; scsi_cmd[0x57] = "release(10)"; scsi_cmd[0x5a] = "mode_sense(10)"; scsi_cmd[0x5e] = "persistent_reserve_in"; scsi_cmd[0x5f] = "persistent_reserve_out"; scsi_cmd[0x80] = "write_file_mark(16)"; scsi_cmd[0x81] = "read_reverse(16)"; scsi_cmd[0x83] = "extended_copy"; scsi_cmd[0x88] = "read(16)"; scsi_cmd[0x8a] = "write(16)"; scsi_cmd[0x8c] = "read_attribute"; scsi_cmd[0x8d] = "write_attribute"; scsi_cmd[0x8f] = "verify(16)"; scsi_cmd[0x91] = "space(16)"; scsi_cmd[0x92] = "locate(16)"; scsi_cmd[0x9e] = "service_action_in(16)"; scsi_cmd[0x9f] = "service_action_out(16)"; scsi_cmd[0xa0] = "report_luns"; scsi_cmd[0xa2] = "security_protocol_in"; scsi_cmd[0xa3] = "maintenance_in"; scsi_cmd[0xa4] = "maintenance_out"; scsi_cmd[0xa8] = "read(12)"; scsi_cmd[0xa9] = "service_action_out(12)"; scsi_cmd[0xaa] = "write(12)"; scsi_cmd[0xab] = "service_action_in(12)"; scsi_cmd[0xac] = "get_performance"; scsi_cmd[0xAF] = "verify(12)"; scsi_cmd[0xb5] = "security_protocol_out"; ================================================ FILE: Chap7/sshcipher.d ================================================ #!/usr/sbin/dtrace -s /* * sshcipher.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing PID %d ... Hit Ctrl-C for report.\n", $target); } pid$target:libcrypto*:*crypt*:entry { self->crypt_start[probefunc] = vtimestamp; } pid$target:libcrypto*:*crypt*:return /self->crypt_start[probefunc]/ { this->oncpu = vtimestamp - self->crypt_start[probefunc]; @cpu[probefunc, "CPU (ns):"] = quantize(this->oncpu); @totals["encryption (ns)"] = sum(this->oncpu); self->crypt_start[probefunc] = 0; } dtrace:::END { printa(@cpu); printa(@totals); } ================================================ FILE: Chap7/sshcipher2.d ================================================ #!/usr/sbin/dtrace -s /* * sshcipher2.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing PID %d ... Hit Ctrl-C for report.\n", $target); } pid$target:libcrypto*:*crypt*:entry { self->crypt_start[probefunc] = vtimestamp; } pid$target:libcrypto*:*crypt*:return /self->crypt_start[probefunc]/ { this->oncpu = vtimestamp - self->crypt_start[probefunc]; @cpu[probefunc, "CPU (ns):"] = quantize(this->oncpu); @totals["encryption (ns)"] = sum(this->oncpu); self->crypt_start[probefunc] = 0; } pid$target:libz*:inflate:entry, pid$target:libz*:deflate:entry { self->compress_start = vtimestamp; } pid$target:libz*:inflate:return, pid$target:libz*:deflate:return /self->compress_start/ { this->oncpu = vtimestamp - self->compress_start; @cpu[probefunc, "CPU (ns):"] = quantize(this->oncpu); @totals["compression (ns)"] = sum(this->oncpu); self->compress_start = 0; } dtrace:::END { printa(@cpu); printa(@totals); } ================================================ FILE: Chap7/sshcipher3.d ================================================ #!/usr/sbin/dtrace -s /* * sshcipher3.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing PID %d ... Hit Ctrl-C for report.\n", $target); } pid$target:libcrypto*:*crypt*:entry { self->crypt_start[probefunc] = vtimestamp; } pid$target:libcrypto*:*crypt*:return /self->crypt_start[probefunc]/ { this->oncpu = vtimestamp - self->crypt_start[probefunc]; @cpu[probefunc, "CPU (ns):"] = quantize(this->oncpu); @totals["encryption (ns)"] = sum(this->oncpu); self->crypt_start[probefunc] = 0; } pid$target:libz*:inflate:entry, pid$target:libz*:deflate:entry { self->compress_start = vtimestamp; } pid$target:libz*:inflate:return, pid$target:libz*:deflate:return /self->compress_start/ { this->oncpu = vtimestamp - self->compress_start; @cpu[probefunc, "CPU (ns):"] = quantize(this->oncpu); @totals["compression (ns)"] = sum(this->oncpu); self->compress_start = 0; } pid$target:ssh:cipher_crypt:entry { @bytes["cipher average buffer size (bytes)"] = avg(arg3); @totals["cipher total (bytes)"] = sum(arg3); } dtrace:::END { printa(@cpu); printa(@bytes); printa(@totals); } ================================================ FILE: Chap7/sshconnect.d ================================================ #!/usr/sbin/dtrace -Zs /* * sshconnect.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { trace("Tracing next ssh connect...\n"); } /* * Tracing begins here: ssh process executed */ proc:::exec-success /execname == "ssh"/ { self->start = timestamp; self->vstart = vtimestamp; } syscall:::entry /self->start/ { self->syscall = timestamp; self->arg = ""; } /* * Include syscall argument details when potentially interesting */ syscall::read*:entry, syscall::ioctl*:entry, syscall::door*:entry, syscall::recv*:entry /self->start/ { self->arg = fds[arg0].fi_pathname; } /* * Measure network I/O as pollsys/select->read() time after connect() */ syscall::connect:entry /self->start && !self->socket/ { self->socket = arg0; self->connect = 1; self->vconnect = vtimestamp; } syscall::pollsys:entry, syscall::select:entry /self->connect/ { self->wait = timestamp; } syscall::read*:return /self->wait/ { @network = sum(timestamp - self->wait); self->wait = 0; } syscall:::return /self->syscall/ { @time[probefunc, self->arg] = sum(timestamp - self->syscall); self->syscall = 0; self->network = 0; self->arg = 0; } /* * Tracing ends here: writing of the "Password:" prompt (10 chars) */ syscall::write*:entry /self->connect && arg0 != self->socket && arg2 == 10 && stringof(copyin(arg1, 10)) == "Password: "/ { trunc(@time, 5); normalize(@time, 1000000); normalize(@network, 1000000); this->oncpu1 = (self->vconnect - self->vstart) / 1000000; this->oncpu2 = (vtimestamp - self->vconnect) / 1000000; this->elapsed = (timestamp - self->start) / 1000000; printf("\nProcess : %s\n", curpsinfo->pr_psargs); printf("Elapsed : %d ms\n", this->elapsed); printf("on-CPU pre : %d ms\n", this->oncpu1); printf("on-CPU post : %d ms\n", this->oncpu2); printa("Network I/O : %@d ms\n", @network); printf("\nTop 5 syscall times\n"); printa("%@8d ms : %s %s\n", @time); exit(0); } proc:::exit /self->start/ { printf("\nssh process aborted: %s\n", curpsinfo->pr_psargs); trunc(@time); trunc(@network); exit(0); } ================================================ FILE: Chap7/sshdactivity.d ================================================ #!/usr/sbin/dtrace -s /* * sshdactivity.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option defaultargs #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-20s %-8s %-8s %-8.8s %s\n", "TIME", "UID", "PID", "ACTION", "ARGS"); my_sshd = $1; } syscall::write*:entry /execname == "sshd" && fds[arg0].fi_fs == "sockfs" && pid != my_sshd/ { printf("%-20Y %-8d %-8d %-8.8s %d bytes\n", walltimestamp, uid, pid, probefunc, arg2); } syscall::accept*:return /execname == "sshd"/ { printf("%-20Y %-8d %-8d %-8.8s %s\n", walltimestamp, uid, pid, probefunc, "CONNECTION STARTED"); } ================================================ FILE: Chap7/tnftpdcmd.d ================================================ #!/usr/sbin/dtrace -s /* * tnftpdcmd.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-20s %10s %s\n", "TIME", "LAT(us)", "FTP CMD"); } pid$target:ftpd:getline:return /arg1 && arg1 != 1/ { self->line = copyinstr(arg1); self->start = timestamp; } pid$target:ftpd:getline:entry /self->start/ { this->delta = (timestamp - self->start) / 1000; /* self->line already contains "\r\n" */ printf("%-20Y %10d %s", walltimestamp, this->delta, self->line); self->start = 0; self->line = 0; } ================================================ FILE: Chap7/weblatency.d ================================================ #!/usr/sbin/dtrace -s /* * weblatency.d * * Example script from Chapter 7 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet /* browser's execname */ inline string BROWSER = "mozilla-bin"; /* maximum expected hostname length + "GET http://" */ inline int MAX_REQ = 64; dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } /* * Trace brower request * * This is achieved by matching writes for the browser's execname that * start with "GET", and then timing from the return of the write to * the return of the next read in the same thread. Various stateful flags * are used: self->fd, self->read. * * For performance reasons, I'd like to only process writes that follow a * connect(), however this approach fails to process keepalives. */ syscall::write:entry /execname == BROWSER/ { self->buf = arg1; self->fd = arg0 + 1; self->nam = ""; } syscall::write:return /self->fd/ { this->str = (char *)copyin(self->buf, MAX_REQ); this->str[4] = '\0'; self->fd = stringof(this->str) == "GET " ? self->fd : 0; } syscall::write:return /self->fd/ { /* fetch browser request */ this->str = (char *)copyin(self->buf, MAX_REQ); this->str[MAX_REQ] = '\0'; /* * This unrolled loop strips down a URL to it's hostname. * We ought to use strtok(), but it's not available on Sol 10 3/05, * so instead I used dirname(). It's not pretty - it's done so that * this works on all Sol 10 versions. */ self->req = stringof(this->str); self->nam = strlen(self->req) > 15 ? self->req : self->nam; self->req = dirname(self->req); self->nam = strlen(self->req) > 15 ? self->req : self->nam; self->req = dirname(self->req); self->nam = strlen(self->req) > 15 ? self->req : self->nam; self->req = dirname(self->req); self->nam = strlen(self->req) > 15 ? self->req : self->nam; self->req = dirname(self->req); self->nam = strlen(self->req) > 15 ? self->req : self->nam; self->req = dirname(self->req); self->nam = strlen(self->req) > 15 ? self->req : self->nam; self->req = dirname(self->req); self->nam = strlen(self->req) > 15 ? self->req : self->nam; self->req = dirname(self->req); self->nam = strlen(self->req) > 15 ? self->req : self->nam; self->req = dirname(self->req); self->nam = strlen(self->req) > 15 ? self->req : self->nam; self->nam = basename(self->nam); /* start the timer */ start[pid, self->fd - 1] = timestamp; host[pid, self->fd - 1] = self->nam; self->buf = 0; self->fd = 0; self->req = 0; self->nam = 0; } /* this one wasn't a GET */ syscall::write:return /self->buf/ { self->buf = 0; self->fd = 0; } syscall::read:entry /execname == BROWSER && start[pid, arg0]/ { self->fd = arg0 + 1; } /* * Record host details */ syscall::read:return /self->fd/ { /* fetch details */ self->host = stringof(host[pid, self->fd - 1]); this->start = start[pid, self->fd - 1]; /* save details */ @Avg[self->host] = avg((timestamp - this->start)/1000000); @Max[self->host] = max((timestamp - this->start)/1000000); @Num[self->host] = count(); /* clear vars */ start[pid, self->fd - 1] = 0; host[pid, self->fd - 1] = 0; self->host = 0; self->fd = 0; } /* * Output report */ dtrace:::END { printf("%-32s %11s\n", "HOST", "NUM"); printa("%-32s %@11d\n", @Num); printf("\n%-32s %11s\n", "HOST", "AVGTIME(ms)"); printa("%-32s %@11d\n", @Avg); printf("\n%-32s %11s\n", "HOST", "MAXTIME(ms)"); printa("%-32s %@11d\n", @Max); } ================================================ FILE: Chap8/j_calls.d ================================================ #!/usr/sbin/dtrace -Zs /* * j_calls.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } hotspot*:::method-entry { this->class = (char *)copyin(arg1, arg2 + 1); this->class[arg2] = '\0'; this->method = (char *)copyin(arg3, arg4 + 1); this->method[arg4] = '\0'; this->name = strjoin(strjoin(stringof(this->class), "."), stringof(this->method)); @calls[pid, "method", this->name] = count(); } hotspot*:::object-alloc { this->class = (char *)copyin(arg1, arg2 + 1); this->class[arg2] = '\0'; @calls[pid, "oalloc", stringof(this->class)] = count(); } hotspot*:::class-loaded { this->class = (char *)copyin(arg0, arg1 + 1); this->class[arg1] = '\0'; @calls[pid, "cload", stringof(this->class)] = count(); } hotspot*:::thread-start { this->thread = (char *)copyin(arg0, arg1 + 1); this->thread[arg1] = '\0'; @calls[pid, "thread", stringof(this->thread)] = count(); } hotspot*:::method-compile-begin { this->class = (char *)copyin(arg0, arg1 + 1); this->class[arg1] = '\0'; this->method = (char *)copyin(arg2, arg3 + 1); this->method[arg3] = '\0'; this->name = strjoin(strjoin(stringof(this->class), "."), stringof(this->method)); @calls[pid, "mcompile", this->name] = count(); } hotspot*:::compiled-method-load { this->class = (char *)copyin(arg0, arg1 + 1); this->class[arg1] = '\0'; this->method = (char *)copyin(arg2, arg3 + 1); this->method[arg3] = '\0'; this->name = strjoin(strjoin(stringof(this->class), "."), stringof(this->method)); @calls[pid, "mload", this->name] = count(); } dtrace:::END { printf(" %6s %-8s %-52s %8s\n", "PID", "TYPE", "NAME", "COUNT"); printa(" %6d %-8s %-52s %@8d\n", @calls); } ================================================ FILE: Chap8/j_calltime.d ================================================ #!/usr/sbin/dtrace -CZs /* * j_calltime.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #define TOP 10 /* default output truncation */ #define B_FALSE 0 #pragma D option quiet #pragma D option defaultargs dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); top = $1 != 0 ? $1 : TOP; } hotspot*:::method-entry { self->depth[arg0]++; self->exclude[arg0, self->depth[arg0]] = 0; self->method[arg0, self->depth[arg0]] = timestamp; } hotspot*:::method-return /self->method[arg0, self->depth[arg0]]/ { this->elapsed_incl = timestamp - self->method[arg0, self->depth[arg0]]; this->elapsed_excl = this->elapsed_incl - self->exclude[arg0, self->depth[arg0]]; self->method[arg0, self->depth[arg0]] = 0; self->exclude[arg0, self->depth[arg0]] = 0; this->class = (char *)copyin(arg1, arg2 + 1); this->class[arg2] = '\0'; this->method = (char *)copyin(arg3, arg4 + 1); this->method[arg4] = '\0'; this->name = strjoin(strjoin(stringof(this->class), "."), stringof(this->method)); @num[pid, "method", this->name] = count(); @num[0, "total", "-"] = count(); @types_incl[pid, "method", this->name] = sum(this->elapsed_incl); @types_excl[pid, "method", this->name] = sum(this->elapsed_excl); @types_excl[0, "total", "-"] = sum(this->elapsed_excl); self->depth[arg0]--; self->exclude[arg0, self->depth[arg0]] += this->elapsed_incl; } hotspot*:::gc-begin { self->gc = timestamp; self->full = (boolean_t)arg0; } hotspot*:::gc-end /self->gc/ { this->elapsed = timestamp - self->gc; self->gc = 0; @num[pid, "gc", self->full == B_FALSE ? "GC" : "Full GC"] = count(); @types[pid, "gc", self->full == B_FALSE ? "GC" : "Full GC"] = sum(this->elapsed); self->full = 0; } dtrace:::END { trunc(@num, top); printf("\nTop %d counts,\n", top); printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "COUNT"); printa(" %6d %-10s %-48s %@8d\n", @num); trunc(@types, top); normalize(@types, 1000); printf("\nTop %d elapsed times (us),\n", top); printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "TOTAL"); printa(" %6d %-10s %-48s %@8d\n", @types); trunc(@types_excl, top); normalize(@types_excl, 1000); printf("\nTop %d exclusive method elapsed times (us),\n", top); printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "TOTAL"); printa(" %6d %-10s %-48s %@8d\n", @types_excl); trunc(@types_incl, top); normalize(@types_incl, 1000); printf("\nTop %d inclusive method elapsed times (us),\n", top); printf(" %6s %-10s %-48s %8s\n", "PID", "TYPE", "NAME", "TOTAL"); printa(" %6d %-10s %-48s %@8d\n", @types_incl); } ================================================ FILE: Chap8/j_flow.d ================================================ #!/usr/sbin/dtrace -Zs /* * j_flow.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ /* increasing bufsize can reduce drops */ #pragma D option bufsize=16m #pragma D option quiet #pragma D option switchrate=10 self int depth[int]; dtrace:::BEGIN { printf("%3s %6s %-16s -- %s\n", "C", "PID", "TIME(us)", "CLASS.METHOD"); } hotspot*:::method-entry { this->class = (char *)copyin(arg1, arg2 + 1); this->class[arg2] = '\0'; this->method = (char *)copyin(arg3, arg4 + 1); this->method[arg4] = '\0'; printf("%3d %6d %-16d %*s-> %s.%s\n", cpu, pid, timestamp / 1000, self->depth[arg0] * 2, "", stringof(this->class), stringof(this->method)); self->depth[arg0]++; } hotspot*:::method-return { this->class = (char *)copyin(arg1, arg2 + 1); this->class[arg2] = '\0'; this->method = (char *)copyin(arg3, arg4 + 1); this->method[arg4] = '\0'; self->depth[arg0] -= self->depth[arg0] > 0 ? 1 : 0; printf("%3d %6d %-16d %*s<- %s.%s\n", cpu, pid, timestamp / 1000, self->depth[arg0] * 2, "", stringof(this->class), stringof(this->method)); } ================================================ FILE: Chap8/j_thread.d ================================================ #!/usr/sbin/dtrace -Zs /* * j_thread.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10 dtrace:::BEGIN { printf("%-20s %6s/%-5s -- %s\n", "TIME", "PID", "TID", "THREAD"); } hotspot*:::thread-start { this->thread = (char *)copyin(arg0, arg1 + 1); this->thread[arg1] = '\0'; printf("%-20Y %6d/%-5d => %s\n", walltimestamp, pid, tid, stringof(this->thread)); } hotspot*:::thread-stop { this->thread = (char *)copyin(arg0, arg1 + 1); this->thread[arg1] = '\0'; printf("%-20Y %6d/%-5d <= %s\n", walltimestamp, pid, tid, stringof(this->thread)); } ================================================ FILE: Chap8/js_calls.d ================================================ #!/usr/sbin/dtrace -Zs /* * js_calls.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing JavaScript... Hit Ctrl-C to end.\n"); } javascript*:::function-entry { this->name = copyinstr(arg2); @calls[basename(copyinstr(arg0)), "func", this->name] = count(); } javascript*:::execute-start { this->filename = basename(copyinstr(arg0)); @calls[this->filename, "exec", "."] = count(); } javascript*:::object-create-start { this->name = copyinstr(arg1); this->filename = basename(copyinstr(arg0)); @calls[this->filename, "obj-new", this->name] = count(); } javascript*:::object-finalize { this->name = copyinstr(arg1); @calls["", "obj-free", this->name] = count(); } dtrace:::END { printf(" %-24s %-10s %-30s %8s\n", "FILE", "TYPE", "NAME", "CALLS"); printa(" %-24s %-10s %-30s %@8d\n", @calls); } ================================================ FILE: Chap8/js_calltime.d ================================================ #!/usr/sbin/dtrace -Zs /* * js_calltime.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } javascript*:::function-entry { self->depth++; self->exclude[self->depth] = 0; self->function[self->depth] = timestamp; } javascript*:::function-return /self->function[self->depth]/ { this->elapsed_incl = timestamp - self->function[self->depth]; this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth]; self->function[self->depth] = 0; self->exclude[self->depth] = 0; this->file = basename(copyinstr(arg0)); this->name = copyinstr(arg2); @num[this->file, "func", this->name] = count(); @num["-", "total", "-"] = count(); @types_incl[this->file, "func", this->name] = sum(this->elapsed_incl); @types_excl[this->file, "func", this->name] = sum(this->elapsed_excl); @types_excl["-", "total", "-"] = sum(this->elapsed_excl); self->depth--; self->exclude[self->depth] += this->elapsed_incl; } javascript*:::object-create-start { self->object = timestamp; } javascript*:::object-create-done /self->object/ { this->elapsed = timestamp - self->object; self->object = 0; this->file = basename(copyinstr(arg0)); this->name = copyinstr(arg1); @num[this->file, "obj-new", this->name] = count(); @num["-", "total", "-"] = count(); @types[this->file, "obj-new", this->name] = sum(this->elapsed); @types["-", "total", "-"] = sum(this->elapsed); self->exclude[self->depth] += this->elapsed; } dtrace:::END { printf("\nCount,\n"); printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT"); printa(" %-20.20s %-10s %-32s %@8d\n", @num); normalize(@types, 1000); printf("\nElapsed times (us),\n"); printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL"); printa(" %-20.20s %-10s %-32s %@8d\n", @types); normalize(@types_excl, 1000); printf("\nExclusive function elapsed times (us),\n"); printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL"); printa(" %-20.20s %-10s %-32s %@8d\n", @types_excl); normalize(@types_incl, 1000); printf("\nInclusive function elapsed times (us),\n"); printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL"); printa(" %-20.20s %-10s %-32s %@8d\n", @types_incl); } ================================================ FILE: Chap8/js_flowinfo.d ================================================ #!/usr/sbin/dtrace -Zs /* * js_flowinfo.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10 self int depth; dtrace:::BEGIN { printf("%3s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)", "FILE", "LINE", "TYPE", "FUNC"); } javascript*:::function-info, javascript*:::function-return /self->last == 0/ { self->last = timestamp; } javascript*:::function-info { this->delta = (timestamp - self->last) / 1000; printf("%3d %6d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid, this->delta, basename(copyinstr(arg4)), arg5, "func", self->depth * 2, "", copyinstr(arg2)); self->depth++; self->last = timestamp; } javascript*:::function-return { this->delta = (timestamp - self->last) / 1000; self->depth -= self->depth > 0 ? 1 : 0; printf("%3d %6d %10d %16s:- %-8s %*s<- %s\n", cpu, pid, this->delta, basename(copyinstr(arg0)), "func", self->depth * 2, "", copyinstr(arg2)); self->last = timestamp; } ================================================ FILE: Chap8/php_calls.d ================================================ #!/usr/sbin/dtrace -Zs /* * php_calls.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing PHP... Hit Ctrl-C to end.\n"); } php*:::function-entry { @funcs[basename(copyinstr(arg1)), copyinstr(arg0)] = count(); } dtrace:::END { printf(" %-32s %-32s %8s\n", "FILE", "FUNC", "CALLS"); printa(" %-32s %-32s %@8d\n", @funcs); } ================================================ FILE: Chap8/php_flowinfo.d ================================================ #!/usr/sbin/dtrace -Zs /* * php_flowinfo.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10 self int depth; dtrace:::BEGIN { printf("%s %6s/%-4s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "TID", "DELTA(us)", "FILE", "LINE", "TYPE", "FUNC"); } php*:::function-entry, php*:::function-return /self->last == 0/ { self->last = timestamp; } php*:::function-entry /arg0/ { this->delta = (timestamp - self->last) / 1000; printf("%d %6d/%-4d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid, tid, this->delta, basename(copyinstr(arg1)), arg2, "func", self->depth * 2, "", copyinstr(arg0)); self->depth++; self->last = timestamp; } php*:::function-return /arg0/ { this->delta = (timestamp - self->last) / 1000; self->depth -= self->depth > 0 ? 1 : 0; printf("%d %6d/%-4d %10d %16s:%-4d %-8s %*s<- %s\n", cpu, pid, tid, this->delta, basename(copyinstr(arg1)), arg2, "func", self->depth * 2, "", copyinstr(arg0)); self->last = timestamp; } ================================================ FILE: Chap8/pl_calls.d ================================================ #!/usr/sbin/dtrace -Zs /* * pl_calls.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing Perl... Hit Ctrl-C to end.\n"); } perl*:::sub-entry { @subs[pid, basename(copyinstr(arg1)), copyinstr(arg0)] = count(); } dtrace:::END { printf("%-6s %-30s %-30s %8s\n", "PID", "FILE", "SUB", "CALLS"); printa("%-6d %-30s %-30s %@8d\n", @subs); } ================================================ FILE: Chap8/pl_calltime.d ================================================ #!/usr/sbin/dtrace -Zs /* * pl_calltime.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } perl*:::sub-entry { self->depth++; self->exclude[self->depth] = 0; self->sub[self->depth] = timestamp; } perl*:::sub-return /self->sub[self->depth]/ { this->elapsed_incl = timestamp - self->sub[self->depth]; this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth]; self->sub[self->depth] = 0; self->exclude[self->depth] = 0; this->file = basename(copyinstr(arg1)); this->name = copyinstr(arg0); @num[this->file, "sub", this->name] = count(); @num["-", "total", "-"] = count(); @types_incl[this->file, "sub", this->name] = sum(this->elapsed_incl); @types_excl[this->file, "sub", this->name] = sum(this->elapsed_excl); @types_excl["-", "total", "-"] = sum(this->elapsed_excl); self->depth--; self->exclude[self->depth] += this->elapsed_incl; } dtrace:::END { printf("\nCount,\n"); printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT"); printa(" %-20s %-10s %-32s %@8d\n", @num); normalize(@types_excl, 1000); printf("\nExclusive subroutine elapsed times (us),\n"); printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL"); printa(" %-20s %-10s %-32s %@8d\n", @types_excl); normalize(@types_incl, 1000); printf("\nInclusive subroutine elapsed times (us),\n"); printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL"); printa(" %-20s %-10s %-32s %@8d\n", @types_incl); } ================================================ FILE: Chap8/pl_flowinfo.d ================================================ #!/usr/sbin/dtrace -Zs /* * pl_flowinfo.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10 self int depth; dtrace:::BEGIN { printf("%s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)", "FILE", "LINE", "TYPE", "SUB"); } perl*:::sub-entry, perl*:::sub-return /self->last == 0/ { self->last = timestamp; } perl*:::sub-entry { this->delta = (timestamp - self->last) / 1000; printf("%d %6d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid, this->delta, basename(copyinstr(arg1)), arg2, "sub", self->depth * 2, "", copyinstr(arg0)); self->depth++; self->last = timestamp; } perl*:::sub-return { this->delta = (timestamp - self->last) / 1000; self->depth -= self->depth > 0 ? 1 : 0; printf("%d %6d %10d %16s:%-4d %-8s %*s<- %s\n", cpu, pid, this->delta, basename(copyinstr(arg1)), arg2, "sub", self->depth * 2, "", copyinstr(arg0)); self->last = timestamp; } ================================================ FILE: Chap8/pl_who.d ================================================ #!/usr/sbin/dtrace -Zs /* * pl_who.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } perl*:::sub-entry { @lines[pid, uid, copyinstr(arg1)] = count(); } dtrace:::END { printf(" %6s %6s %6s %s\n", "PID", "UID", "SUBS", "FILE"); printa(" %6d %6d %@6d %s\n", @lines); } ================================================ FILE: Chap8/py_calls.d ================================================ #!/usr/sbin/dtrace -Zs /* * py_calls.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing Python... Hit Ctrl-C to end.\n"); } python*:::function-entry { @funcs[pid, basename(copyinstr(arg0)), copyinstr(arg1)] = count(); } dtrace:::END { printf("%-6s %-30s %-30s %8s\n", "PID", "FILE", "FUNC", "CALLS"); printa("%-6d %-30s %-30s %@8d\n", @funcs); } ================================================ FILE: Chap8/py_calltime.d ================================================ #!/usr/sbin/dtrace -Zs /* * py_calltime.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } python*:::function-entry { self->depth++; self->exclude[self->depth] = 0; self->function[self->depth] = timestamp; } python*:::function-return /self->function[self->depth]/ { this->elapsed_incl = timestamp - self->function[self->depth]; this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth]; self->function[self->depth] = 0; self->exclude[self->depth] = 0; this->file = basename(copyinstr(arg0)); this->name = copyinstr(arg1); @num[this->file, "func", this->name] = count(); @num["-", "total", "-"] = count(); @types_incl[this->file, "func", this->name] = sum(this->elapsed_incl); @types_excl[this->file, "func", this->name] = sum(this->elapsed_excl); @types_excl["-", "total", "-"] = sum(this->elapsed_excl); self->depth--; self->exclude[self->depth] += this->elapsed_incl; } dtrace:::END { printf("\nCount,\n"); printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT"); printa(" %-20s %-10s %-32s %@8d\n", @num); normalize(@types_excl, 1000); printf("\nExclusive function elapsed times (us),\n"); printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL"); printa(" %-20s %-10s %-32s %@8d\n", @types_excl); normalize(@types_incl, 1000); printf("\nInclusive function elapsed times (us),\n"); printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL"); printa(" %-20s %-10s %-32s %@8d\n", @types_incl); } ================================================ FILE: Chap8/py_flowinfo.d ================================================ #!/usr/sbin/dtrace -Zs /* * py_flowinfo.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10 self int depth; dtrace:::BEGIN { printf("%s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)", "FILE", "LINE", "TYPE", "FUNC"); } python*:::function-entry, python*:::function-return /self->last == 0/ { self->last = timestamp; } python*:::function-entry { this->delta = (timestamp - self->last) / 1000; printf("%d %6d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "func", self->depth * 2, "", copyinstr(arg1)); self->depth++; self->last = timestamp; } python*:::function-return { this->delta = (timestamp - self->last) / 1000; self->depth -= self->depth > 0 ? 1 : 0; printf("%d %6d %10d %16s:%-4d %-8s %*s<- %s\n", cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "func", self->depth * 2, "", copyinstr(arg1)); self->last = timestamp; } ================================================ FILE: Chap8/py_who.d ================================================ #!/usr/sbin/dtrace -Zs /* * py_who.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } python*:::function-entry { @lines[pid, uid, copyinstr(arg0)] = count(); } dtrace:::END { printf(" %6s %6s %6s %s\n", "PID", "UID", "FUNCS", "FILE"); printa(" %6d %6d %@6d %s\n", @lines); } ================================================ FILE: Chap8/rb_calls.d ================================================ #!/usr/sbin/dtrace -Zs /* * rb_calls.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing Ruby... Hit Ctrl-C to end.\n"); } ruby*:::function-entry { @funcs[pid, basename(copyinstr(arg2)), copyinstr(arg0), copyinstr(arg1)] = count(); } dtrace:::END { printf("%-6s %-28.28s %-16s %-16s %8s\n", "PID", "FILE", "CLASS", "METHOD", "CALLS"); printa("%-6d %-28.28s %-16s %-16s %@8d\n", @funcs); } ================================================ FILE: Chap8/rb_calltime.d ================================================ #!/usr/sbin/dtrace -Zs /* * rb_calltime.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } ruby*:::function-entry { self->depth++; self->exclude[self->depth] = 0; self->function[self->depth] = timestamp; } ruby*:::function-return /self->function[self->depth]/ { this->elapsed_incl = timestamp - self->function[self->depth]; this->elapsed_excl = this->elapsed_incl - self->exclude[self->depth]; self->function[self->depth] = 0; self->exclude[self->depth] = 0; this->file = basename(copyinstr(arg2)); this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1)); @num[this->file, "func", this->name] = count(); @num["-", "total", "-"] = count(); @types_incl[this->file, "func", this->name] = sum(this->elapsed_incl); @types_excl[this->file, "func", this->name] = sum(this->elapsed_excl); @types_excl["-", "total", "-"] = sum(this->elapsed_excl); self->depth--; self->exclude[self->depth] += this->elapsed_incl; } ruby*:::object-create-start { self->object = timestamp; } ruby*:::object-create-done /self->object/ { this->elapsed = timestamp - self->object; self->object = 0; this->file = basename(copyinstr(arg1)); this->file = this->file != NULL ? this->file : "."; this->name = copyinstr(arg0); @num[this->file, "obj-new", this->name] = count(); @types[this->file, "obj-new", this->name] = sum(this->elapsed); self->exclude[self->depth] += this->elapsed; } ruby*:::gc-begin { self->gc = timestamp; } ruby*:::gc-end /self->gc/ { this->elapsed = timestamp - self->gc; self->gc = 0; @num[".", "gc", "-"] = count(); @types[".", "gc", "-"] = sum(this->elapsed); self->exclude[self->depth] += this->elapsed; } dtrace:::END { printf("\nCount,\n"); printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT"); printa(" %-20s %-10s %-32s %@8d\n", @num); normalize(@types, 1000); printf("\nElapsed times (us),\n"); printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL"); printa(" %-20s %-10s %-32s %@8d\n", @types); normalize(@types_excl, 1000); printf("\nExclusive function elapsed times (us),\n"); printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL"); printa(" %-20s %-10s %-32s %@8d\n", @types_excl); normalize(@types_incl, 1000); printf("\nInclusive function elapsed times (us),\n"); printf(" %-20s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "TOTAL"); printa(" %-20s %-10s %-32s %@8d\n", @types_incl); } ================================================ FILE: Chap8/rb_flowinfo.d ================================================ #!/usr/sbin/dtrace -Zs /* * rb_flowinfo.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10 self int depth; dtrace:::BEGIN { printf("%s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)", "FILE", "LINE", "TYPE", "NAME"); } ruby*:::function-entry, ruby*:::function-return /self->last == 0/ { self->last = timestamp; } ruby*:::function-entry { this->delta = (timestamp - self->last) / 1000; this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1)); printf("%d %6d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid, this->delta, basename(copyinstr(arg2)), arg3, "method", self->depth * 2, "", this->name); self->depth++; self->last = timestamp; } ruby*:::function-return { this->delta = (timestamp - self->last) / 1000; self->depth -= self->depth > 0 ? 1 : 0; this->name = strjoin(strjoin(copyinstr(arg0), "::"), copyinstr(arg1)); printf("%d %6d %10d %16s:%-4d %-8s %*s<- %s\n", cpu, pid, this->delta, basename(copyinstr(arg2)), arg3, "method", self->depth * 2, "", this->name); self->last = timestamp; } ================================================ FILE: Chap8/rb_who.d ================================================ #!/usr/sbin/dtrace -Zs /* * rb_who.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } ruby*:::line { @lines[pid, uid, copyinstr(arg0)] = count(); } dtrace:::END { printf(" %6s %6s %10s %s\n", "PID", "UID", "LINES", "FILE"); printa(" %6d %6d %@10d %s\n", @lines); } ================================================ FILE: Chap8/sh_calls.d ================================================ #!/usr/sbin/dtrace -Zs /* * sh_calls.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } sh*:::function-entry { @calls[basename(copyinstr(arg0)), "func", copyinstr(arg1)] = count(); } sh*:::builtin-entry { @calls[basename(copyinstr(arg0)), "builtin", copyinstr(arg1)] = count(); } sh*:::command-entry { @calls[basename(copyinstr(arg0)), "cmd", copyinstr(arg1)] = count(); } sh*:::subshell-entry /arg1 != 0/ { @calls[basename(copyinstr(arg0)), "subsh", "-"] = count(); } dtrace:::END { printf(" %-22s %-10s %-32s %8s\n", "FILE", "TYPE", "NAME", "COUNT"); printa(" %-22s %-10s %-32s %@8d\n", @calls); } ================================================ FILE: Chap8/sh_flowinfo.d ================================================ #!/usr/sbin/dtrace -Zs /* * sh_flowinfo.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10 self int depth; dtrace:::BEGIN { self->depth = 0; printf("%3s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)", "FILE", "LINE", "TYPE", "NAME"); } sh*:::function-entry, sh*:::function-return, sh*:::builtin-entry, sh*:::builtin-return, sh*:::command-entry, sh*:::command-return, sh*:::subshell-entry, sh*:::subshell-return /self->last == 0/ { self->last = timestamp; } sh*:::function-entry { this->delta = (timestamp - self->last) / 1000; printf("%3d %6d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "func", self->depth * 2, "", copyinstr(arg1)); self->depth++; self->last = timestamp; } sh*:::function-return { this->delta = (timestamp - self->last) / 1000; self->depth -= self->depth > 0 ? 1 : 0; printf("%3d %6d %10d %16s:- %-8s %*s<- %s\n", cpu, pid, this->delta, basename(copyinstr(arg0)), "func", self->depth * 2, "", copyinstr(arg1)); self->last = timestamp; } sh*:::builtin-entry { this->delta = (timestamp - self->last) / 1000; printf("%3d %6d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "builtin", self->depth * 2, "", copyinstr(arg1)); self->depth++; self->last = timestamp; } sh*:::builtin-return { this->delta = (timestamp - self->last) / 1000; self->depth -= self->depth > 0 ? 1 : 0; printf("%3d %6d %10d %16s:- %-8s %*s<- %s\n", cpu, pid, this->delta, basename(copyinstr(arg0)), "builtin", self->depth * 2, "", copyinstr(arg1)); self->last = timestamp; } sh*:::command-entry { this->delta = (timestamp - self->last) / 1000; printf("%3d %6d %10d %16s:%-4d %-8s %*s-> %s\n", cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "cmd", self->depth * 2, "", copyinstr(arg1)); self->depth++; self->last = timestamp; } sh*:::command-return { this->delta = (timestamp - self->last) / 1000; self->depth -= self->depth > 0 ? 1 : 0; printf("%3d %6d %10d %16s:- %-8s %*s<- %s\n", cpu, pid, this->delta, basename(copyinstr(arg0)), "cmd", self->depth * 2, "", copyinstr(arg1)); self->last = timestamp; } sh*:::subshell-entry /arg1 != 0/ { this->delta = (timestamp - self->last) / 1000; printf("%3d %6d %10d %16s:- %-8s %*s-> pid %d\n", cpu, pid, this->delta, basename(copyinstr(arg0)), "subsh", self->depth * 2, "", arg1); self->depth++; self->last = timestamp; } sh*:::subshell-return /self->last/ { this->delta = (timestamp - self->last) / 1000; self->depth -= self->depth > 0 ? 1 : 0; printf("%3d %6d %10d %16s:- %-8s %*s<- = %d\n", cpu, pid, this->delta, basename(copyinstr(arg0)), "subsh", self->depth * 2, "", arg1); self->last = timestamp; } ================================================ FILE: Chap8/sh_who.d ================================================ #!/usr/sbin/dtrace -Zs /* * sh_who.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } sh*:::line { @lines[pid, uid, copyinstr(arg0)] = count(); } dtrace:::END { printf(" %6s %6s %6s %s\n", "PID", "UID", "LINES", "FILE"); printa(" %6d %6d %@6d %s\n", @lines); } ================================================ FILE: Chap8/tcl_calls.d ================================================ #!/usr/sbin/dtrace -Zs /* * tcl_calls.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing Tcl... Hit Ctrl-C to end.\n"); } tcl*:::proc-entry { @calls[pid, "proc", copyinstr(arg0)] = count(); } tcl*:::cmd-entry { @calls[pid, "cmd", copyinstr(arg0)] = count(); } dtrace:::END { printf(" %6s %-8s %-52s %8s\n", "PID", "TYPE", "NAME", "COUNT"); printa(" %6d %-8s %-52s %@8d\n", @calls); } ================================================ FILE: Chap8/tcl_procflow.d ================================================ #!/usr/sbin/dtrace -Zs /* * tcl_procflow.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10 self int depth; dtrace:::BEGIN { printf("%3s %6s %-16s -- %s\n", "C", "PID", "TIME(us)", "PROCEDURE"); } tcl*:::proc-entry { printf("%3d %6d %-16d %*s-> %s\n", cpu, pid, timestamp / 1000, self->depth * 2, "", copyinstr(arg0)); self->depth++; } tcl*:::proc-return { self->depth -= self->depth > 0 ? 1 : 0; printf("%3d %6d %-16d %*s<- %s\n", cpu, pid, timestamp / 1000, self->depth * 2, "", copyinstr(arg0)); } ================================================ FILE: Chap8/tcl_who.d ================================================ #!/usr/sbin/dtrace -Zs /* * tcl_who.d * * Example script from Chapter 8 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing Tcl... Hit Ctrl-C to end.\n"); } tcl*:::cmd-entry { @calls[pid, uid, curpsinfo->pr_psargs] = count(); } dtrace:::END { printf(" %6s %6s %6s %-55s\n", "PID", "UID", "CMDS", "ARGS"); printa(" %6d %6d %@6d %-55.55s\n", @calls); } ================================================ FILE: Chap9/kill.d ================================================ #!/usr/sbin/dtrace -s /* * kill.d * * Example script from Chapter 9 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("%-6s %12s %6s %-8s %s\n", "FROM", "COMMAND", "SIG", "TO", "RESULT"); } syscall::kill:entry { self->target = (int)arg0; self->signal = arg1; } syscall::kill:return { printf("%-6d %12s %6d %-8d %d\n", pid, execname, self->signal, self->target, (int)arg0); self->target = 0; self->signal = 0; } ================================================ FILE: Chap9/procsnoop.d ================================================ #!/usr/sbin/dtrace -s /* * procsnoop.d * * Example script from Chapter 9 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet #pragma D option switchrate=10hz dtrace:::BEGIN { printf("%-8s %5s %6s %6s %s\n", "TIME(ms)", "UID", "PID", "PPID", "COMMAND"); start = timestamp; } proc:::exec-success { printf("%-8d %5d %6d %6d %s\n", (timestamp - start) / 1000000, uid, pid, ppid, curpsinfo->pr_psargs); } ================================================ FILE: Chap9/sigdist.d ================================================ #!/usr/sbin/dtrace -s /* * sigdist.d * * Example script from Chapter 9 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } proc:::signal-send { @Count[execname, stringof(args[1]->pr_fname), args[2]] = count(); } dtrace:::END { printf("%16s %16s %6s %6s\n", "SENDER", "RECIPIENT", "SIG", "COUNT"); printa("%16s %16s %6d %6@d\n", @Count); } ================================================ FILE: Chap9/threaded.d ================================================ #!/usr/sbin/dtrace -s /* * threaded.d * * Example script from Chapter 9 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ #pragma D option quiet profile:::profile-101 /pid != 0/ { @sample[pid, execname] = lquantize(tid, 0, 128, 1); } profile:::tick-1sec { printf("%Y,\n", walltimestamp); printa("\n @101hz PID: %-8d CMD: %s\n%@d", @sample); printf("\n"); trunc(@sample); } ================================================ FILE: Chap9/uoffcpu.d ================================================ #!/usr/sbin/dtrace -s /* * uoffcpu.d * * Example script from Chapter 9 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ sched:::off-cpu /execname == $$1/ { self->start = timestamp; } sched:::on-cpu /self->start/ { this->delta = (timestamp - self->start) / 1000; @["off-cpu (us):", ustack()] = quantize(this->delta); self->start = 0; } ================================================ FILE: Chap9/uoncpu.d ================================================ #!/usr/sbin/dtrace -s /* * uoncpu.d * * Example script from Chapter 9 of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. * * See the book for the script description and warnings. Many of these are * provided as example solutions, and will need changes to work on your OS. */ profile:::profile-1001 /execname == $$1/ { @["\n on-cpu (count @1001hz):", ustack()] = count(); } ================================================ FILE: README.md ================================================ DTrace book scripts =================== Scripts from "DTrace: Dynamic Tracing in Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, Prentice Hall, 2011. ISBN-10: 0132091518, ISBN-13: 978-0132091510 This is a copy of the scripts published on http://dtracebook.com, and is a static collection to support the book. See the book for descriptions of these scripts, examples, and any related warnings. WARNING: These scripts are not tools that are expected to work. They are examples of solving problems, but are often tied to the kernel version they were written for. You can treat them as starting points: they embody an idea, approach, and presentation for an observability problem. Their implementation details will likely need adjusting to work correctly on your OS. This is explained, in detail, in the book, which should help you use and update the scripts as needed. The hardest part of using DTrace is knowing what to do with it. That is what these scripts provide -- proven usage ideas. Even if they don't work on your current kernel version, they still help with the hardest problem faced by new users of DTrace, showing by example what can be done. The nature of dynamic tracing (the DTrace fbt and pid providers) means that writing tools that work across every OS, now, and in the future, is not possible. If you repurpose a script (in the same way that a reader of a textbook might reuse an example), I'd ask that you please identify the origin in the script; eg, in the header: ``` * Based on a script from Chapter X of the book: DTrace: Dynamic Tracing in * Oracle Solaris, Mac OS X, and FreeBSD", by Brendan Gregg and Jim Mauro, * Prentice Hall, 2011. ISBN-10: 0132091518. http://dtracebook.com. ``` Thanks to [Mike Harsch](https://github.com/mharsch) for transcribing and testing these scripts.