diff options
author | gnn <gnn@FreeBSD.org> | 2012-05-12 20:38:18 +0000 |
---|---|---|
committer | gnn <gnn@FreeBSD.org> | 2012-05-12 20:38:18 +0000 |
commit | 4297c1b2d07fec7f50b70e26e3adb4d062b19e15 (patch) | |
tree | aec2772e8855e6dbaea6d8136ed0c47bcb825dee /Proc | |
parent | 111c75a23278cd9317f0a13867c22ee0f6c95b26 (diff) | |
download | FreeBSD-src-4297c1b2d07fec7f50b70e26e3adb4d062b19e15.zip FreeBSD-src-4297c1b2d07fec7f50b70e26e3adb4d062b19e15.tar.gz |
Add the remaining scripts from the DTraceToolkit, version 0.99, to the
vendor tree.
http://www.brendangregg.com/dtrace.html#DTraceToolkit
Diffstat (limited to 'Proc')
-rw-r--r-- | Proc/Readme | 3 | ||||
-rwxr-xr-x | Proc/crash.d | 181 | ||||
-rwxr-xr-x | Proc/creatbyproc.d | 10 | ||||
-rwxr-xr-x | Proc/dappprof | 239 | ||||
-rwxr-xr-x | Proc/dapptrace | 259 | ||||
-rwxr-xr-x | Proc/fddist | 116 | ||||
-rwxr-xr-x | Proc/filebyproc.d | 10 | ||||
-rwxr-xr-x | Proc/kill.d | 63 | ||||
-rwxr-xr-x | Proc/lastwords | 90 | ||||
-rwxr-xr-x | Proc/mmapfiles.d | 62 | ||||
-rwxr-xr-x | Proc/newproc.d | 10 | ||||
-rwxr-xr-x | Proc/pathopens.d | 100 | ||||
-rwxr-xr-x | Proc/pfilestat | 282 | ||||
-rwxr-xr-x | Proc/pidpersec.d | 57 | ||||
-rwxr-xr-x | Proc/readbytes.d | 10 | ||||
-rwxr-xr-x | Proc/readdist.d | 10 | ||||
-rwxr-xr-x | Proc/rwbbypid.d | 61 | ||||
-rwxr-xr-x | Proc/rwbypid.d | 61 | ||||
-rwxr-xr-x | Proc/rwbytype.d | 101 | ||||
-rwxr-xr-x | Proc/sampleproc | 105 | ||||
-rwxr-xr-x | Proc/shortlived.d | 118 | ||||
-rwxr-xr-x | Proc/sigdist.d | 61 | ||||
-rwxr-xr-x | Proc/stacksize.d | 95 | ||||
-rwxr-xr-x | Proc/sysbypid.d | 53 | ||||
-rwxr-xr-x | Proc/syscallbypid.d | 54 | ||||
-rwxr-xr-x | Proc/syscallbyproc.d | 10 | ||||
-rwxr-xr-x | Proc/threaded.d | 66 | ||||
-rwxr-xr-x | Proc/topsysproc | 121 | ||||
-rwxr-xr-x | Proc/writebytes.d | 10 | ||||
-rwxr-xr-x | Proc/writedist.d | 10 |
30 files changed, 2428 insertions, 0 deletions
diff --git a/Proc/Readme b/Proc/Readme new file mode 100644 index 0000000..acc3634 --- /dev/null +++ b/Proc/Readme @@ -0,0 +1,3 @@ +Proc - Process based analysis + + This would include activity by PID, and syscall analysis. diff --git a/Proc/crash.d b/Proc/crash.d new file mode 100755 index 0000000..c1ed397 --- /dev/null +++ b/Proc/crash.d @@ -0,0 +1,181 @@ +#!/usr/sbin/dtrace -Cs +/* + * crash.d - Crashed Application info. + * Written in DTrace (Solaris 10 3/05). + * + * $Id: crash.d 3 2007-08-01 10:50:08Z brendan $ + * + * When applications crash via a SIGSEGV or SIGBUS, a report of the + * process state is printed out. + * + * USAGE: crash.d + * + * FIELDS: + * Type Signal type + * Program Execname of process + * Agrs Argument listing of process + * PID Process ID + * TID Thread ID + * LWPs Number of Light Weight Processes + * PPID Parent Process ID + * UID User ID + * GID Group ID + * TaskID Task ID + * ProjID Project ID + * PoolID Pool ID + * ZoneID Zone ID + * zone Zone name + * CWD Current working directory + * errno Error number of last syscall + * + * SEE ALSO: mdb, pstack, coreadm + * app_crash.d - Greg Nakhimovsky & Morgan Herrington + * + * COPYRIGHT: Copyright (c) 2005 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 29-May-2005 Brendan Gregg Created this. + * 24-Apr-2006 " " Last update. + */ + +#pragma D option quiet +#pragma D option destructive + +dtrace:::BEGIN +{ + printf("Waiting for crashing applications...\n"); +} + +/* + * Print Report Header + */ +proc:::signal-send +/(args[2] == SIGBUS || args[2] == SIGSEGV) && pid == args[1]->pr_pid/ +{ + stop(); + self->elapsed = timestamp - curthread->t_procp->p_mstart; + self->crash = 1; + + printf("\n-----------------------------------------------------\n"); + printf("CRASH DETECTED at %Y\n", walltimestamp); + printf("-----------------------------------------------------\n"); + printf("Type: %s\n", args[2] == SIGBUS ? "SIGBUS" : "SIGSEGV"); + printf("Program: %s\n", execname); + printf("Args: %S\n", curpsinfo->pr_psargs); + printf("PID: %d\n", pid); + printf("TID: %d\n", tid); + printf("LWPs: %d\n", curthread->t_procp->p_lwpcnt); + printf("PPID: %d\n", ppid); + printf("UID: %d\n", uid); + printf("GID: %d\n", gid); + printf("TaskID: %d\n", curpsinfo->pr_taskid); + printf("ProjID: %d\n", curpsinfo->pr_projid); + printf("PoolID: %d\n", curpsinfo->pr_poolid); + printf("ZoneID: %d\n", curpsinfo->pr_zoneid); + printf("zone: %s\n", zonename); + printf("CWD: %s\n", cwd); + printf("errno: %d\n", errno); + + printf("\nUser Stack Backtrace,"); + ustack(); + + printf("\nKernel Stack Backtrace,"); + stack(); +} + +/* + * Print Java Details + */ +proc:::signal-send +/self->crash && execname == "java"/ +{ + printf("\nJava Stack Backtrace,"); + jstack(); +} + +/* + * Print Ancestors + */ +proc:::signal-send +/self->crash/ +{ + printf("\nAnsestors,\n"); + self->level = 1; + self->procp = curthread->t_procp; + self->ptr = self->procp; +} + +/* ancestory un-rolled loop, reverse order, 6 deep */ +proc:::signal-send /self->crash && self->ptr != 0/ +{ + printf("%*s %d %S\n", self->level += 2, "", + self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs); + self->ptr = self->ptr->p_parent; +} +proc:::signal-send /self->crash && self->ptr != 0/ +{ + printf("%*s %d %S\n", self->level += 2, "", + self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs); + self->ptr = self->ptr->p_parent; +} +proc:::signal-send /self->crash && self->ptr != 0/ +{ + printf("%*s %d %S\n", self->level += 2, "", + self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs); + self->ptr = self->ptr->p_parent; +} +proc:::signal-send /self->crash && self->ptr != 0/ +{ + printf("%*s %d %S\n", self->level += 2, "", + self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs); + self->ptr = self->ptr->p_parent; +} +proc:::signal-send /self->crash && self->ptr != 0/ +{ + printf("%*s %d %S\n", self->level += 2, "", + self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs); + self->ptr = self->ptr->p_parent; +} +proc:::signal-send /self->crash && self->ptr != 0/ +{ + printf("%*s %d %S\n", self->level += 2, "", + self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs); + self->ptr = self->ptr->p_parent; +} + +/* + * Print Report Footer + */ +proc:::signal-send +/self->crash/ +{ + + printf("\nTimes,\n"); + printf(" User: %d ticks\n", self->procp->p_utime); + printf(" Sys: %d ticks\n", self->procp->p_stime); + printf(" Elapsed: %d ms\n", self->elapsed/1000000); + + printf("\nSizes,\n"); + printf(" Heap: %d bytes\n", self->procp->p_brksize); + printf(" Stack: %d bytes\n", self->procp->p_stksize); + + self->ptr = 0; + self->procp = 0; + self->crash = 0; + self->level = 0; + self->elapsed = 0; + system("/usr/bin/prun %d", pid); +} diff --git a/Proc/creatbyproc.d b/Proc/creatbyproc.d new file mode 100755 index 0000000..23e1f54 --- /dev/null +++ b/Proc/creatbyproc.d @@ -0,0 +1,10 @@ +#!/usr/sbin/dtrace -s +/* + * creatbyproc.d - file creat()s by process name. DTrace OneLiner. + * + * This is a DTrace OneLiner from the DTraceToolkit. + * + * $Id: creatbyproc.d 3 2007-08-01 10:50:08Z brendan $ + */ + +syscall::creat*:entry { printf("%s %s", execname, copyinstr(arg0)); } diff --git a/Proc/dappprof b/Proc/dappprof new file mode 100755 index 0000000..5aed3cb --- /dev/null +++ b/Proc/dappprof @@ -0,0 +1,239 @@ +#!/usr/bin/sh +# +# dappprof - profile user and library function usage. +# Written using DTrace (Solaris 10 3/05). +# +# The default output traces user functions as they are called. Options +# can be used to examine libraries and timestamps. +# +# $Id: dappprof 65 2007-10-04 11:09:40Z brendan $ +# +# USAGE: dappprof [-acehoTU] [-u lib] { -p PID | command } +# +# -p PID # examine this PID +# -a # print all details +# -c # print call counts +# -e # print elapsed times (us) +# -o # print on cpu times (us) +# -T # print totals +# -u lib # trace this library instead +# -U # trace all libraries + user functions +# -b bufsize # dynamic variable buf size (default is "4m") +# eg, +# dappprof df -h # run and examine the "df -h" command +# dappprof -p 1871 # examine PID 1871 +# +# The elapsed times are interesting, to help identify calls that take +# some time to complete (during which the process may have context +# switched off the CPU). +# +# SEE ALSO: dapptrace # DTraceToolkit +# dtruss # DTraceToolkit +# apptrace +# +# COPYRIGHT: Copyright (c) 2005 Brendan Gregg. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at Docs/cddl1.txt +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# CDDL HEADER END +# +# Author: Brendan Gregg [Sydney, Australia] +# +# 16-May-2005 Brendan Gregg Created this. +# 17-Jul-2005 " " Last update. +# + + +############################## +# --- Process Arguments --- +# + +### Default variables +opt_totals=0; opt_pid=0; pid=0; opt_lib=0; lib="" +opt_elapsed=0; opt_cpu=0; opt_counts=0; opt_liball=0 +opt_command=0; command=""; opt_buf=0; buf="4m" + +### Process options +while getopts ab:cehop:Tu:U name +do + case $name in + a) opt_liball=1; opt_counts=1; opt_elapsed=1; opt_cpu=1 + opt_totals=1 ;; + b) opt_buf=1; buf=$OPTARG ;; + p) opt_pid=1; pid=$OPTARG ;; + u) opt_lib=1; lib=$OPTARG ;; + U) opt_liball=1 ;; + c) opt_counts=1 ;; + e) opt_elapsed=1 ;; + o) opt_cpu=1 ;; + T) opt_totals=1 ;; + h|?) cat <<-END >&2 + USAGE: dappprof [-cehoTU] [-u lib] { -p PID | command } + + -p PID # examine this PID + -a # print all details + -c # print syscall counts + -e # print elapsed times (us) + -o # print on cpu times + -T # print totals + -u lib # trace this library instead + -U # trace all libraries + user funcs + -b bufsize # dynamic variable buf size + eg, + dappprof df -h # run and examine "df -h" + dappprof -p 1871 # examine PID 1871 + dappprof -ap 1871 # print all data + END + exit 1 + esac +done +shift `expr $OPTIND - 1` + +### Option logic +if [ $opt_pid -eq 0 ]; then + opt_command=1 + if [ "$*" = "" ]; then + $0 -h + exit + fi + command="$*" +fi +if [ $opt_elapsed -eq 0 -a $opt_cpu -eq 0 -a $opt_counts -eq 0 ]; then + opt_elapsed=1; +fi + + +### Probe logic +if [ $opt_liball -eq 1 ]; then + probe_entry='pid$target:::entry' + probe_return='pid$target:::return' +elif [ $opt_lib -eq 1 ]; then + probe_entry='pid$target:'$lib'::entry' + probe_return='pid$target:'$lib'::return' +else + probe_entry='pid$target:a.out::entry' + probe_return='pid$target:a.out::return' +fi + +################################# +# --- Main Program, DTrace --- +# + +### Define D Script +dtrace=' + #pragma D option quiet + + /* + * Command line arguments + */ + inline int OPT_command = '$opt_command'; + inline int OPT_liball = '$opt_liball'; + inline int OPT_elapsed = '$opt_elapsed'; + inline int OPT_cpu = '$opt_cpu'; + inline int OPT_counts = '$opt_counts'; + inline int OPT_totals = '$opt_totals'; + inline int OPT_pid = '$opt_pid'; + inline int PID = '$pid'; + inline string NAME = "'$pname'"; + + dtrace:::BEGIN + /! OPT_command/ + { + printf("Tracing... Hit Ctrl-C to end...\n"); + } + + /* + * Save syscall entry info + */ + '$probe_entry' + { + /* set function depth */ + this->fdepth = ++fdepth[probefunc]; + + /* set start details */ + self->start[probefunc,this->fdepth] = timestamp; + self->vstart[probefunc,this->fdepth] = vtimestamp; + + /* count occurances */ + OPT_counts && OPT_liball ? @Counts[probemod,probefunc] = count() : 1; + OPT_counts && ! OPT_liball ? @Counts[probefunc] = count() : 1; + OPT_counts && OPT_totals && OPT_liball ? + @Counts["TOTAL:",""] = count() : 1; + OPT_counts && OPT_totals && ! OPT_liball ? + @Counts["TOTAL:"] = count() : 1; + } + + /* + * Print return data + */ + /* print 3 arg output - default */ + '$probe_return' + /self->start[probefunc,fdepth[probefunc]]/ + { + /* fetch function depth */ + this->fdepth = fdepth[probefunc]; + + /* calculate elapsed time */ + this->elapsed = timestamp - self->start[probefunc,this->fdepth]; + self->start[probefunc,this->fdepth] = 0; + this->cpu = vtimestamp - self->vstart[probefunc,this->fdepth]; + self->vstart[probefunc,this->fdepth] = 0; + + /* save elapsed times */ + OPT_elapsed && OPT_liball ? + @Elapsed[probemod,probefunc] = sum(this->elapsed) : 1; + OPT_elapsed && ! OPT_liball ? + @Elapsed[probefunc] = sum(this->elapsed) : 1; + OPT_elapsed && OPT_totals && OPT_liball ? + @Elapsed["TOTAL:",""] = sum(this->elapsed) : 1; + OPT_elapsed && OPT_totals && ! OPT_liball ? + @Elapsed["TOTAL:"] = sum(this->elapsed) : 1; + + /* save cpu times */ + OPT_cpu && OPT_liball ? @CPU[probemod,probefunc] = sum(this->cpu) : 1; + OPT_cpu && ! OPT_liball ? @CPU[probefunc] = sum(this->cpu) : 1; + OPT_cpu && OPT_totals && OPT_liball ? + @CPU["TOTAL:",""] = sum(this->cpu) : 1; + OPT_cpu && OPT_totals && ! OPT_liball ? + @CPU["TOTAL:"] = sum(this->cpu) : 1; + + } + + /* print counts */ + dtrace:::END + { + /* print counts */ + OPT_counts ? printf("\n%-49s %16s\n","CALL","COUNT") : 1; + OPT_counts && OPT_liball ? printa("%-16s %-32s %@16d\n",@Counts) : 1; + OPT_counts && ! OPT_liball ? printa("%-49s %@16d\n",@Counts) : 1; + + /* print elapsed times */ + OPT_elapsed ? printf("\n%-49s %16s\n","CALL","ELAPSED") : 1; + OPT_elapsed && OPT_liball ? printa("%-16s %-32s %@16d\n",@Elapsed) : 1; + OPT_elapsed && ! OPT_liball ? printa("%-49s %@16d\n",@Elapsed) : 1; + + /* print cpu times */ + OPT_cpu ? printf("\n%-49s %16s\n","CALL","CPU") : 1; + OPT_cpu && OPT_liball ? printa("%-16s %-32s %@16d\n",@CPU) : 1; + OPT_cpu && ! OPT_liball ? printa("%-49s %@16d\n",@CPU) : 1; + } +' + +### Run DTrace +if [ $opt_command -eq 1 ]; then + /usr/sbin/dtrace -x dynvarsize=$buf -x evaltime=exec -n "$dtrace" \ + -c "$command" >&2 +else + /usr/sbin/dtrace -x dynvarsize=$buf -n "$dtrace" -p "$pid" >&2 +fi + diff --git a/Proc/dapptrace b/Proc/dapptrace new file mode 100755 index 0000000..7dece4e --- /dev/null +++ b/Proc/dapptrace @@ -0,0 +1,259 @@ +#!/usr/bin/sh +# +# dapptrace - trace user and library function usage. +# Written using DTrace (Solaris 10 3/05). +# +# The default output traces user functions as they are called. Options +# can be used to examine libraries and timestamps. +# +# $Id: dapptrace 65 2007-10-04 11:09:40Z brendan $ +# +# USAGE: dapptrace [-acdeFlhoU] [-u lib] { -p PID | command } +# +# -p PID # examine this PID +# -a # print all details +# -c # print call counts +# -d # print relative timestamps (us) +# -e # print elapsed times (us) +# -F # print flow indentation +# -l # print pid/lwpid per line +# -o # print on cpu times (us) +# -u lib # trace this library instead +# -U # trace all libraries + user functions +# -b bufsize # dynamic variable buf size (default is "4m") +# eg, +# dapptrace df -h # run and examine the "df -h" command +# dapptrace -p 1871 # examine PID 1871 +# dapptrace -Fp 1871 # print using flow indents +# dapptrace -eop 1871 # print elapsed and CPU times +# +# The elapsed times are interesting, to help identify calls that take +# some time to complete (during which the process may have context +# switched off the CPU). +# +# SEE ALSO: dappprof # DTraceToolkit +# dtruss # DTraceToolkit +# apptrace +# +# COPYRIGHT: Copyright (c) 2005 Brendan Gregg. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at Docs/cddl1.txt +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# CDDL HEADER END +# +# Author: Brendan Gregg [Sydney, Australia] +# +# 16-May-2005 Brendan Gregg Created this. +# 17-Jul-2005 " " Last update. +# + + +############################## +# --- Process Arguments --- +# + +### Default variables +opt_pid=0; pid=0; opt_indent=0; opt_lib=0; lib="" +opt_elapsed=0; opt_cpu=0; opt_counts=0; +opt_relative=0; opt_printid=0; opt_liball=0 +opt_command=0; command=""; opt_buf=0; buf="4m" + +### Process options +while getopts ab:cdeFhlop:u:U name +do + case $name in + a) opt_liball=1; opt_counts=1; opt_relative=1; opt_elapsed=1 + opt_indent=1; opt_printid=1; opt_cpu=1 ;; + b) opt_buf=1; buf=$OPTARG ;; + p) opt_pid=1; pid=$OPTARG ;; + u) opt_lib=1; lib=$OPTARG ;; + U) opt_liball=1 ;; + c) opt_counts=1 ;; + d) opt_relative=1 ;; + e) opt_elapsed=1 ;; + F) opt_indent=1 ;; + l) opt_printid=1 ;; + o) opt_cpu=1 ;; + h|?) cat <<-END >&2 + USAGE: dapptrace [-acdeholFLU] [-u lib] { -p PID | command } + + -p PID # examine this PID + -a # print all details + -c # print syscall counts + -d # print relative times (us) + -e # print elapsed times (us) + -F # print flow indentation + -l # print pid/lwpid + -o # print CPU on cpu times + -u lib # trace this library instead + -U # trace all libraries + user funcs + -b bufsize # dynamic variable buf size + eg, + dapptrace df -h # run and examine "df -h" + dapptrace -p 1871 # examine PID 1871 + dapptrace -Fp 1871 # print using flow indents + dapptrace -eop 1871 # print elapsed and CPU times + END + exit 1 + esac +done +shift `expr $OPTIND - 1` + +### Option logic +if [ $opt_pid -eq 0 ]; then + opt_command=1 + if [ "$*" = "" ]; then + $0 -h + exit + fi + command="$*" +fi + +### Probe logic +if [ $opt_liball -eq 1 ]; then + probe_entry='pid$target:::entry' + probe_return='pid$target:::return' +elif [ $opt_lib -eq 1 ]; then + probe_entry='pid$target:'$lib'::entry' + probe_return='pid$target:'$lib'::return' +else + probe_entry='pid$target:a.out::entry' + probe_return='pid$target:a.out::return' +fi + +################################# +# --- Main Program, DTrace --- +# + +### Define D Script +dtrace=' + #pragma D option quiet + + /* + * Command line arguments + */ + inline int OPT_command = '$opt_command'; + inline int OPT_liball = '$opt_liball'; + inline int OPT_indent = '$opt_indent'; + inline int OPT_printid = '$opt_printid'; + inline int OPT_relative = '$opt_relative'; + inline int OPT_elapsed = '$opt_elapsed'; + inline int OPT_cpu = '$opt_cpu'; + inline int OPT_counts = '$opt_counts'; + inline int OPT_pid = '$opt_pid'; + inline int PID = '$pid'; + inline string NAME = "'$pname'"; + + dtrace:::BEGIN + { + /* print header */ + OPT_printid ? printf("%-8s ","PID/LWP") : 1; + OPT_relative ? printf("%8s ","RELATIVE") : 1; + OPT_elapsed ? printf("%7s ","ELAPSD") : 1; + OPT_cpu ? printf("%6s ","CPU") : 1; + printf("CALL(args) \t\t = return\n"); + + /* indent depth */ + depth = 0; + } + + /* + * Save syscall entry info + */ + '$probe_entry' + { + /* set function depth */ + this->fdepth = ++fdepth[probefunc]; + depth += 2; + + /* set start details */ + self->start[probefunc,this->fdepth] = timestamp; + self->vstart[probefunc,this->fdepth] = vtimestamp; + + /* count occurances */ + OPT_counts && OPT_liball ? @Counts[probemod,probefunc] = count() : 1; + OPT_counts && ! OPT_liball ? @Counts[probefunc] = count() : 1; + + /* print optional fields */ + OPT_printid ? printf("%5d/%d: ",pid,tid) : 1; + OPT_relative ? printf("%8d ",vtimestamp/1000) : 1; + OPT_elapsed ? printf(" . ") : 1; + OPT_cpu ? printf(" . ") : 1; + OPT_indent ? printf("%*s",depth,"") : 1; + + /* print main data */ + printf("-> "); + OPT_liball ? printf("%s:",probemod) : 1; + printf("%s(0x%X, 0x%X, 0x%X)\t\t\n",probefunc,arg0,arg1,arg2); + + } + + /* + * Print return data + */ + /* print 3 arg output - default */ + '$probe_return' + /self->start[probefunc,fdepth[probefunc]]/ + { + /* fetch function depth */ + this->fdepth = fdepth[probefunc]; + + /* calculate elapsed time */ + this->elapsed = timestamp - self->start[probefunc,this->fdepth]; + self->start[probefunc,this->fdepth] = 0; + this->cpu = vtimestamp - self->vstart[probefunc,this->fdepth]; + self->vstart[probefunc,this->fdepth] = 0; + + /* print optional fields */ + OPT_printid ? printf("%5d/%d: ",pid,tid) : 1; + OPT_relative ? printf("%8d ",vtimestamp/1000) : 1; + OPT_elapsed ? printf("%7d ",this->elapsed/1000) : 1; + OPT_cpu ? printf("%6d ",this->cpu/1000) : 1; + OPT_indent ? printf("%*s",depth,"") : 1; + + /* print main data */ + printf("<- "); + OPT_liball ? printf("%s:",probemod) : 1; + printf("%s = %d\n",probefunc,(int)arg0); + depth -= 2; + fdepth[probefunc]--; + } + + /* reset indent depth */ + profile:::tick-1sec + { + /* + * some probes generated by the pid provider have entries + * but not returns. this is a klude to fix that problem. this + * also explains fdepth[probefunc] rather than a single depth. + */ + depth = 0; + } + + /* print counts */ + dtrace:::END + { + OPT_counts ? printf("\n%-49s %16s\n","CALL","COUNT") : 1; + OPT_counts && OPT_liball ? printa("%-16s %-32s %@16d\n",@Counts) : 1; + OPT_counts && ! OPT_liball ? printa("%-49s %@16d\n",@Counts) : 1; + } +' + +### Run DTrace +if [ $opt_command -eq 1 ]; then + /usr/sbin/dtrace -x dynvarsize=$buf -x evaltime=exec -n "$dtrace" \ + -c "$command" >&2 +else + /usr/sbin/dtrace -x dynvarsize=$buf -n "$dtrace" -p "$pid" >&2 +fi + diff --git a/Proc/fddist b/Proc/fddist new file mode 100755 index 0000000..b1fe17a --- /dev/null +++ b/Proc/fddist @@ -0,0 +1,116 @@ +#!/usr/bin/sh +# +# fddist - file descriptor usage distributions. +# Written using DTrace (Solaris 10 3/05). +# +# This prints distributions for read and write events by file descriptor, +# by process. This can be used to determine which file descriptor a +# process is doing the most I/O with. +# +# $Id: fddist 3 2007-08-01 10:50:08Z brendan $ +# +# USAGE: fddist [-r|-w] # hit Ctrl-C to end sample +# +# FIELDS: +# EXEC process name +# PID process ID +# value file descriptor +# count number of events +# +# BASED ON: /usr/demo/dtrace/lquantize.d +# +# SEE ALSO: +# DTrace Guide "Aggregations" chapter (docs.sun.com) +# +# PORTIONS: Copyright (c) 2005, 2006 Brendan Gregg. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at Docs/cddl1.txt +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# CDDL HEADER END +# +# 09-Jun-2005 Brendan Gregg Created this. +# 20-Apr-2006 " " Last update. + + +############################## +# --- Process Arguments --- +# + +### Default variables +opt_read=0; opt_write=0 + +### Process options +while getopts hrw name +do + case $name in + r) opt_read=1 ;; + w) opt_write=1 ;; + h|?) cat <<-END >&2 + USAGE: fddist [-r|-w] + -r # reads only + -w # writes only + eg, + fddist # default, r+w counts + fddist -r # read count only + END + exit 1 + esac +done +shift `expr $OPTIND - 1` + +### Option logic +if [ $opt_read -eq 0 -a $opt_write -eq 0 ]; then + opt_read=1; opt_write=1 +fi + + +################################# +# --- Main Program, DTrace --- +# +/usr/sbin/dtrace -n ' + #pragma D option quiet + + inline int OPT_read = '$opt_read'; + inline int OPT_write = '$opt_write'; + inline int FDMAX = 255; + + /* print header */ + dtrace:::BEGIN + { + printf("Tracing "); + OPT_read && OPT_write ? printf("reads and writes") : 1; + OPT_read && ! OPT_write ? printf("reads") : 1; + ! OPT_read && OPT_write ? printf("writes") : 1; + printf("... Hit Ctrl-C to end.\n"); + } + + /* sample reads */ + syscall::*read*:entry + /OPT_read/ + { + @Count[execname, pid] = lquantize(arg0, 0, FDMAX, 1); + } + + /* sample writes */ + syscall::*write*:entry + /OPT_write/ + { + @Count[execname, pid] = lquantize(arg0, 0, FDMAX, 1); + } + + /* print report */ + dtrace:::END + { + printa("EXEC: %-16s PID: %d\n%@d\n",@Count); + } +' diff --git a/Proc/filebyproc.d b/Proc/filebyproc.d new file mode 100755 index 0000000..d1f7589 --- /dev/null +++ b/Proc/filebyproc.d @@ -0,0 +1,10 @@ +#!/usr/sbin/dtrace -s +/* + * filebyproc.d - snoop files opened by process name. DTrace OneLiner. + * + * This is a DTrace OneLiner from the DTraceToolkit. + * + * $Id: filebyproc.d 3 2007-08-01 10:50:08Z brendan $ + */ + +syscall::open*:entry { printf("%s %s", execname, copyinstr(arg0)); } diff --git a/Proc/kill.d b/Proc/kill.d new file mode 100755 index 0000000..215625f --- /dev/null +++ b/Proc/kill.d @@ -0,0 +1,63 @@ +#!/usr/sbin/dtrace -qs +/* + * kill.d - watch process signals as they are sent (eg, kill -9). + * Written in DTrace (Solaris 10 3/05). + * + * $Id: kill.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: kill.d + * + * FIELDS: + * FROM source PID + * COMMAND source command name + * TO destination PID + * SIG destination signal ("9" for a kill -9) + * RESULT result of signal (-1 is for failure) + * + * SEE ALSO: Chapter 25, Solaris Dynamic Tracing Guide, docs.sun.com, + * for a solution using proc:::signal-send. + * + * COPYRIGHT: Copyright (c) 2005 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 09-May-2004 Brendan Gregg Created this. + * 28-Jun-2005 " " Last update. + */ + +dtrace:::BEGIN +{ + /* Print header */ + printf("%5s %12s %5s %-6s %s\n", + "FROM", "COMMAND", "SIG", "TO", "RESULT"); +} + +syscall::kill:entry +{ + /* Record target PID and signal */ + self->target = arg0; + self->signal = arg1; +} + +syscall::kill:return +{ + /* Print source, target, and result */ + printf("%5d %12s %5d %-6d %d\n", + pid, execname, self->signal, self->target, (int)arg0); + + /* Cleanup memory */ + self->target = 0; + self->signal = 0; +} diff --git a/Proc/lastwords b/Proc/lastwords new file mode 100755 index 0000000..1258cc9 --- /dev/null +++ b/Proc/lastwords @@ -0,0 +1,90 @@ +#!/usr/bin/ksh +# +# lastwords - print last few syscalls for dying processes. +# Written using DTrace (Solaris 10 3/05). +# +# $Id: lastwords 3 2007-08-01 10:50:08Z brendan $ +# +# This prints the last few system calls for processes matching +# the given name, when they exit. This makes use of a ring buffer +# so that the impact on the system is minimised. +# +# USAGE: lastwords command +# eg, +# lastwords netscape +# +# FIELDS: +# TIME Time of syscall return, ns +# PID Process ID +# EXEC Process name (execname) +# SYSCALL System call +# RETURN Return value for system call +# ERR errno for system call +# +# BASED ON: /usr/demo/dtrace/ring.d +# +# SEE ALSO: DTrace Guide "Buffers and Buffering" chapter (docs.sun.com) +# dtruss (DTraceToolkit) +# +# PORTIONS: Copyright (c) 2005, 2006 Brendan Gregg. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at Docs/cddl1.txt +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# CDDL HEADER END +# +# 09-Jun-2005 Brendan Gregg Created this. +# 20-Apr-2006 " " Last update. +# + +### Usage +function usage +{ + cat <<-END >&2 + USAGE: lastwords command + eg, + lastwords netscape + END + exit 1 +} + +### Process arguments +if (( $# != 1 )); then + usage +fi +command=$1 + +print "Tracing... Waiting for $command to exit..." + +### Run DTrace +/usr/sbin/dtrace -n ' + #pragma D option quiet + #pragma D option bufpolicy=ring + #pragma D option bufsize=16k + + syscall:::return + /execname == $$1/ + { + /* buffer syscall details */ + printf("%-18d %5d %12s %12s %10x %3d\n", + timestamp,pid,execname,probefunc,(int)arg0,errno); + } + + proc::proc_exit:exit + /execname == $$1/ + { + /* print, erm, footer */ + printf("%-18s %5s %12s %12s %10s %3s\n", + "TIME","PID","EXEC","SYSCALL","RETURN","ERR"); + exit(0); + } +' "$command" diff --git a/Proc/mmapfiles.d b/Proc/mmapfiles.d new file mode 100755 index 0000000..7690f50 --- /dev/null +++ b/Proc/mmapfiles.d @@ -0,0 +1,62 @@ +#!/usr/sbin/dtrace -s +/* + * mmapfiles.d - mmap'd files by process. + * Written using DTrace (Solaris 10 3/05). + * + * $Id: mmapfiles.d 14 2007-09-11 08:03:35Z brendan $ + * + * USAGE: mmapfiles.d # hit Ctrl-C to end sample + * + * FIELDS: + * MMAPS number of mmaps + * CMD process name + * PATHNAME pathname of mmap'd file + * + * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 18-Oct-2005 Brendan Gregg Created this. + * 20-Apr-2006 " " Last update. + */ + +#pragma D option quiet + +dtrace:::BEGIN +{ + printf("Tracing... Hit Ctrl-C to end.\n"); +} + +syscall::mmap:entry +/(int)arg4 > 0/ +{ + /* + * Fetch filename + */ + this->filep = curthread->t_procp->p_user.u_finfo.fi_list[arg4].uf_file; + this->vnodep = this->filep != 0 ? this->filep->f_vnode : 0; + self->vpath = this->vnodep ? (this->vnodep->v_path != 0 ? + cleanpath(this->vnodep->v_path) : "<unknown>") : "<unknown>"; + + /* Store Details */ + @hits[execname, self->vpath] = count(); +} + +dtrace:::END +{ + /* Print Details */ + printf("%5s %-16s %s\n", "MMAPS", "CMD", "PATHNAME"); + printa("%@5d %-16s %s\n", @hits); +} diff --git a/Proc/newproc.d b/Proc/newproc.d new file mode 100755 index 0000000..6b6fad2 --- /dev/null +++ b/Proc/newproc.d @@ -0,0 +1,10 @@ +#!/usr/sbin/dtrace -s +/* + * newproc.d - snoop new processes as they are executed. DTrace OneLiner. + * + * This is a DTrace OneLiner from the DTraceToolkit. + * + * $Id: newproc.d 3 2007-08-01 10:50:08Z brendan $ + */ + +proc:::exec-success { trace(curpsinfo->pr_psargs); } diff --git a/Proc/pathopens.d b/Proc/pathopens.d new file mode 100755 index 0000000..10cd0c8 --- /dev/null +++ b/Proc/pathopens.d @@ -0,0 +1,100 @@ +#!/usr/sbin/dtrace -s +/* + * pathopens.d - full pathnames opened successfully count. + * Written using DTrace (Solaris 10 3/05) + * + * This program prints a count of the number of times files have been + * successfully opened. This is somewhat special in that the full pathname + * is calculated, even if the file open referred to a relative pathname. + * + * $Id: pathopens.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: fileopens.d + * + * FIELDS: + * PATHNAME full pathname + * COUNT number of successful opens + * + * Similar to a script from DExplorer. + * + * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 28-Jun-2005 Brendan Gregg Created this. + * 12-Jan-2006 " " Fixed known error. + * 20-Apr-2006 " " Last update. + */ + +#pragma D option quiet + +dtrace:::BEGIN +{ + printf("Tracing... Hit Ctrl-C to end.\n"); +} + +syscall::open*:entry +{ + self->pathp = arg0; + self->ok = 1; +} + +syscall::open*:return +/self->ok && arg0 != -1/ +{ + self->file = copyinstr(self->pathp); + self->char0 = copyin(self->pathp, 1); + + /* fetch current working directory */ + this->path = curthread->t_procp->p_user.u_cdir->v_path; + + /* + * Make the full pathname + * + * This routine takes the cwd and the filename, and generates a + * full pathname. Sometimes the filename is absolute, so we must + * ignore the cwd. This also checks if the cwd ends in an + * unnecessary '/'. + */ + this->len = strlen(this->path); + self->join = *(char *)(this->path + this->len - 1) == '/' ? "" : "/"; + self->dir = strjoin(cwd, self->join); + self->dir = *(char *)self->char0 == '/' ? "" : self->dir; + self->full = strjoin(self->dir, self->file); + + /* save to aggregation */ + @num[self->full] = count(); + + /* cleanup */ + self->join = 0; + self->full = 0; + self->dir = 0; + self->file = 0; + self->char0 = 0; +} + +syscall::open*:return +/self->ok/ +{ + /* cleanup */ + self->ok = 0; + self->pathp = 0; +} + +dtrace:::END +{ + printf("%6s %s\n", "COUNT", "PATHNAME"); + printa("%@6d %s\n", @num); +} diff --git a/Proc/pfilestat b/Proc/pfilestat new file mode 100755 index 0000000..c6aaba3 --- /dev/null +++ b/Proc/pfilestat @@ -0,0 +1,282 @@ +#!/usr/bin/sh +# +# pfilestat +# +# This prints I/O statistics for each file descriptor within a process. +# In particular, the time break down during read() and write() events is +# measured. +# +# $Id: pfilestat 4 2007-08-01 11:01:38Z brendan $ +# +# USAGE: pfilestat [-r|-w] pid +# +# FIELDS: +# STATE microstate: running, sleeping, waitcpu, read, write +# FDUM File Descriptor ID +# Time Percentage of wallclock time in each STATE +# File Name of file, if known +# +# COPYRIGHT: Copyright (c) 2006 Richard McDougall. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at Docs/cddl1.txt +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# CDDL HEADER END +# +# ToDo: +# Trace readv() and writev(). +# +# 20-Feb-2006 Richard McDougall created this. +# 24-Feb-2006 Brendan Gregg tweaked code. +# 20-Mar-2006 " " tweaked code. +# 20-Mar-2006 " " last update. + + +############################## +# --- Process Arguments --- +# + +### Default variables +opt_read=0; opt_write=0 + +### Process options +while getopts hrw name +do + case $name in + r) opt_read=1 ;; + w) opt_write=1 ;; + h|?) cat <<-END >&2 + USAGE: pfilestat [-r|-w] pid + -r # reads only + -w # writes only + eg, + pfilestat pid # default, r+w counts + pfilestat -r pid # read count only + END + exit 1 + esac +done +shift `expr $OPTIND - 1` + +PID=$1 +clearstr=`clear` + +if [ -z "$PID" ] +then + echo "Must supply pid" + exit 1 +fi + +### Option logic +if [ $opt_read -eq 0 -a $opt_write -eq 0 ]; then + opt_read=1; opt_write=1 +fi + + +################################# +# --- Main Program, DTrace --- +# +/usr/sbin/dtrace -n ' + #pragma D option quiet + + inline string CLEAR = "'$clearstr'"; + inline int OPT_read = '$opt_read'; + inline int OPT_write = '$opt_write'; + inline int PID = '$PID'; + + unsigned long long totaltime; + unsigned long long totalbytes; + + enum runstate { + READ, + WRITE, + OTHER + }; + + /* print header */ + dtrace:::BEGIN + { + printf("Tracing "); + OPT_read && OPT_write ? printf("reads and writes") : 1; + OPT_read && ! OPT_write ? printf("reads") : 1; + ! OPT_read && OPT_write ? printf("writes") : 1; + printf("..."); + totaltime = 0; + totalbytes = 0; + last = timestamp; + stamp = timestamp; + } + + /* sample reads */ + syscall::read:entry, + syscall::pread*:entry + /pid == PID && OPT_read/ + { + runstate = READ; + @logical["running", (uint64_t)0, ""] = sum(timestamp - last); + totaltime += timestamp - last; + last = timestamp; + + self->fd = arg0 + 1; + } + + fbt::fop_read:entry, + fbt::fop_write:entry + /self->fd/ + { + self->path = args[0]->v_path == 0 ? "<none>" : + cleanpath(args[0]->v_path); + } + + syscall::read:return, + syscall::pread*:return + /pid == PID && OPT_read/ + { + runstate = OTHER; + this->bytes = (int)arg0 > 0 ? (int)arg0 : 0; + @logical["read", self->fd - 1, self->path] = sum(timestamp - last); + @bytes["read", self->fd - 1, self->path] = sum(this->bytes); + totalbytes += this->bytes; + totaltime += timestamp - last; + last = timestamp; + self->path = 0; + self->fd = 0; + } + + + /* sample writes */ + syscall::write:entry, + syscall::pwrite*:entry + /pid == PID && OPT_write/ + { + runstate = WRITE; + @logical["running", (uint64_t)0, ""] = sum(timestamp - last); + totaltime += timestamp - last; + last = timestamp; + + self->fd = (int)arg0 + 1; + } + + syscall::write:return, + syscall::pwrite*:return + /pid == PID && OPT_write/ + { + runstate = OTHER; + this->bytes = (int)arg0 > 0 ? (int)arg0 : 0; + @logical["write", self->fd - 1, self->path] = sum(timestamp - last); + @bytes["write", self->fd - 1, self->path] = sum(this->bytes); + totalbytes += this->bytes; + totaltime += timestamp - last; + last = timestamp; + self->path = 0; + self->fd = 0; + } + + sched:::on-cpu + /pid == PID/ + { + @logical["waitcpu", (uint64_t)0, ""] = sum(timestamp - last); + totaltime += timestamp - last; + last = timestamp; + } + + + sched:::off-cpu + /pid == PID/ + { + @logical["running", (uint64_t)0, ""] = sum(timestamp - last); + totaltime += timestamp - last; + last = timestamp; + } + + sched:::sleep + /pid == PID/ + { + @logical["running", (uint64_t)0, ""] = sum(timestamp - last); + totaltime += timestamp - last; + last = timestamp; + } + + sched:::wakeup + /args[1]->pr_pid == PID && runstate == OTHER/ + { + @logical["sleep", (uint64_t)0, ""] = sum(timestamp - last); + totaltime += timestamp - last; + last = timestamp; + } + + sched:::wakeup + /args[1]->pr_pid == PID && runstate == READ/ + { + @logical["sleep-r", (uint64_t)0, ""] = sum(timestamp - last); + totaltime += timestamp - last; + last = timestamp; + } + + sched:::wakeup + /args[1]->pr_pid == PID && runstate == WRITE/ + { + @logical["sleep-w", (uint64_t)0, ""] = sum(timestamp - last); + totaltime += timestamp - last; + last = timestamp; + } + + sched:::enqueue + /args[1]->pr_pid == PID/ + { + @logical["waitcpu", (uint64_t)0, ""] = sum(timestamp - last); + totaltime += timestamp - last; + last = timestamp; + } + + sched:::dequeue + /args[1]->pr_pid == PID/ + { + @logical["waitcpu", (uint64_t)0, ""] = sum(timestamp - last); + totaltime += timestamp - last; + last = timestamp; + } + + /* print report */ + profile:::tick-5s + { + printf("%s", CLEAR); + normalize(@logical, totaltime / 100); + trunc(@logical, 10); + printf("%10s %7s %9s %-44s\n", "STATE", "FDNUM", "Time", "Filename"); + printa("%10s %7d %@8d%% %-44.44s\n", @logical); + trunc(@logical); + + delta = timestamp - stamp; + stamp = timestamp; + normalize(@bytes, (1024 * delta) / 1000000000); + trunc(@bytes, 10); + printf("\n%10s %7s %9s %-44s\n", "STATE", "FDNUM", "KB/s", + "Filename"); + printa("%10s %7d %@9d %-44.44s\n", @bytes); + trunc(@bytes); + + printf("\nTotal event time (ms): %d Total Mbytes/sec: %d\n", + totaltime / 1000000, + (totalbytes * 1000000000) / (delta * 1048576)); + + totaltime = 0; + totalbytes = 0; + last = timestamp; + } + + dtrace:::END + { + trunc(@logical); + trunc(@bytes); + } +' diff --git a/Proc/pidpersec.d b/Proc/pidpersec.d new file mode 100755 index 0000000..71080b9 --- /dev/null +++ b/Proc/pidpersec.d @@ -0,0 +1,57 @@ +#!/usr/sbin/dtrace -s +/* + * pidpersec.d - print new PIDs per sec. + * Written using DTrace (Solaris 10 3/05) + * + * This script prints the number of new processes created per second. + * + * $Id: pidpersec.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: pidpersec.d + * + * FIELDS: + * + * TIME Time, as a string + * LASTPID Last PID created + * PID/s Number of processes created per second + * + * SEE ALSO: execsnoop + * + * COPYRIGHT: Copyright (c) 2005 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 09-Jun-2005 Brendan Gregg Created this. + * 09-Jun-2005 " " Last update. + */ + +#pragma D option quiet + +dtrace:::BEGIN +{ + printf("%-22s %8s %6s\n", "TIME", "LASTPID", "PID/s"); + pids = 0; +} + +proc:::exec-success +{ + pids++; +} + +profile:::tick-1sec +{ + printf("%-22Y %8d %6d\n", walltimestamp, `mpid, pids); + pids = 0; +} diff --git a/Proc/readbytes.d b/Proc/readbytes.d new file mode 100755 index 0000000..67612a2 --- /dev/null +++ b/Proc/readbytes.d @@ -0,0 +1,10 @@ +#!/usr/sbin/dtrace -s +/* + * readbytes.d - read bytes by process name. DTrace OneLiner. + * + * This is a DTrace OneLiner from the DTraceToolkit. + * + * $Id: readbytes.d 3 2007-08-01 10:50:08Z brendan $ + */ + +sysinfo:::readch { @bytes[execname] = sum(arg0); } diff --git a/Proc/readdist.d b/Proc/readdist.d new file mode 100755 index 0000000..0d0346d --- /dev/null +++ b/Proc/readdist.d @@ -0,0 +1,10 @@ +#!/usr/sbin/dtrace -s +/* + * readdist.d - read distribution by process name. DTrace OneLiner. + * + * This is a DTrace OneLiner from the DTraceToolkit. + * + * $Id: readdist.d 3 2007-08-01 10:50:08Z brendan $ + */ + +sysinfo:::readch { @dist[execname] = quantize(arg0); } diff --git a/Proc/rwbbypid.d b/Proc/rwbbypid.d new file mode 100755 index 0000000..72cb00d --- /dev/null +++ b/Proc/rwbbypid.d @@ -0,0 +1,61 @@ +#!/usr/sbin/dtrace -s +/* + * rwbbypid.d - read/write bytes by PID. + * Written using DTrace (Solaris 10 3/05) + * + * This script tracks the bytes read and written at the syscall level + * by processes, printing the totals in a report. This is tracking the + * successful number of bytes read or written. + * + * $Id: rwbbypid.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: rwbbypid.d # hit Ctrl-C to end sample + * + * FIELDS: + * PID process ID + * CMD process name + * DIR direction, Read or Write + * BYTES total bytes + * + * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 28-Jun-2005 Brendan Gregg Created this. + * 20-Apr-2006 " " Last update. + */ + +#pragma D option quiet + +dtrace:::BEGIN +{ + printf("Tracing... Hit Ctrl-C to end.\n"); +} + +sysinfo:::readch +{ + @bytes[pid, execname, "R"] = sum(arg0); +} + +sysinfo:::writech +{ + @bytes[pid, execname, "W"] = sum(arg0); +} + +dtrace:::END +{ + printf("%6s %-24s %4s %16s\n", "PID", "CMD", "DIR", "BYTES"); + printa("%6d %-24s %4s %@16d\n", @bytes); +} diff --git a/Proc/rwbypid.d b/Proc/rwbypid.d new file mode 100755 index 0000000..e4f0432 --- /dev/null +++ b/Proc/rwbypid.d @@ -0,0 +1,61 @@ +#!/usr/sbin/dtrace -s +/* + * rwbypid.d - read/write calls by PID. + * Written using DTrace (Solaris 10 3/05) + * + * This script tracks the number of reads and writes at the syscall level + * by processes, printing the totals in a report. This matches reads + * and writes whether they succeed or not. + * + * $Id: rwbypid.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: rwbypid.d # hit Ctrl-C to end sample + * + * FIELDS: + * PID process ID + * CMD process name + * DIR Read or Write + * COUNT total calls + * + * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 28-Jun-2005 Brendan Gregg Created this. + * 20-Apr-2006 " " Last update. + */ + +#pragma D option quiet + +dtrace:::BEGIN +{ + printf("Tracing... Hit Ctrl-C to end.\n"); +} + +syscall::*read*:entry +{ + @calls[pid, execname, "R"] = sum(arg0); +} + +syscall::*write*:entry +{ + @calls[pid, execname, "W"] = sum(arg0); +} + +dtrace:::END +{ + printf("%6s %-24s %4s %8s\n", "PID", "CMD", "DIR", "COUNT"); + printa("%6d %-24s %4s %@8d\n", @calls); +} diff --git a/Proc/rwbytype.d b/Proc/rwbytype.d new file mode 100755 index 0000000..6705d99 --- /dev/null +++ b/Proc/rwbytype.d @@ -0,0 +1,101 @@ +#!/usr/sbin/dtrace -s +/* + * rwbytype.d - read/write bytes by vnode type. + * Written using DTrace (Solaris 10 3/05). + * + * This program identifies the vnode type of read/write activity - whether + * that is for regular files, sockets, character special devices, etc. + * + * $Id: rwbytype.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: rwbytype.d # hit Ctrl-C to end sample + * + * FIELDS: + * PID number of rwbytype + * CMD process name + * VTYPE vnode type (describes I/O type) + * DIR direction (Read/Write) + * BYTES bytes transferred + * + * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 18-Oct-2005 Brendan Gregg Created this. + * 20-Apr-2006 " " Last update. + */ + +#pragma D option quiet + +typedef struct vtype2str { + string code; +}; + +translator struct vtype2str < int T > { + /* the order has been picked for performance reasons */ + code = + T == 1 ? "reg" : + T == 9 ? "sock" : + T == 4 ? "chr" : + T == 6 ? "fifo" : + T == 8 ? "proc" : + T == 2 ? "dir" : + T == 3 ? "blk" : + T == 5 ? "lnk" : + T == 7 ? "door" : + T == 10 ? "port" : + T == 11 ? "bad" : "non"; +}; + +dtrace:::BEGIN +{ + printf("Tracing... Hit Ctrl-C to end.\n"); +} + +fbt::fop_read:entry, +fbt::fop_write:entry +{ + self->type = xlate <struct vtype2str *>(args[0]->v_type)->code; + self->size = args[1]->uio_resid; + self->uiop = args[1]; +} + +fbt::fop_read:return +/self->uiop/ +{ + this->resid = self->uiop->uio_resid; + @bytes[pid, execname, self->type, "R"] = sum(self->size - this->resid); + self->type = 0; + self->size = 0; + self->uiop = 0; +} + +/* this is delibrately redundant code for performance reasons */ +fbt::fop_write:return +/self->uiop/ +{ + this->resid = self->uiop->uio_resid; + @bytes[pid, execname, self->type, "W"] = sum(self->size - this->resid); + self->type = 0; + self->size = 0; + self->uiop = 0; +} + +dtrace:::END +{ + printf("%-6s %-16s %6s %4s %9s\n", + "PID", "CMD", "VTYPE", "DIR", "BYTES"); + printa("%-6d %-16s %6s %4s %@9d\n", @bytes); +} diff --git a/Proc/sampleproc b/Proc/sampleproc new file mode 100755 index 0000000..891be14 --- /dev/null +++ b/Proc/sampleproc @@ -0,0 +1,105 @@ +#!/usr/bin/ksh +# +# sampleproc - sample processes on the CPUs. +# Written using DTrace (Solaris 10 3/05). +# +# This program samples which process is on each CPU, at a particular +# configurable rate. This can be used as an estimate for which process +# is consuming the most CPU time. +# +# $Id: sampleproc 8 2007-08-06 05:55:26Z brendan $ +# +# USAGE: sampleproc [hertz] # hit Ctrl-C to end sample +# +# FIELDS: +# PID Process ID +# COMMAND Command name +# COUNT Number of samples +# PERCENT Percent of CPU usage +# +# BASED ON: /usr/demo/dtrace/prof.d +# +# SEE ALSO: +# DTrace Guide "profile Provider" chapter (docs.sun.com) +# +# PORTIONS: Copyright (c) 2005 Brendan Gregg. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at Docs/cddl1.txt +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# CDDL HEADER END +# +# 09-Jun-2005 Brendan Gregg Created this. +# 09-Jul-2005 " " Last update. + +### Usage +function usage +{ + cat <<-END >&2 + USAGE: sampleproc [hertz] + eg, + sampleproc # defaults to 100 hertz + sampleproc 1000 # 1000 hertz + END + exit 1 +} + +### Process arguments +if (( $# == 0 )); then + hertz=100 +elif (( $# == 1 )); then + hertz=$1 + if [[ "$hertz" = *[a-zA-Z]* ]]; then + print "ERROR2: $hertz hertz is invalid." >&2 + exit 2 + fi + if (( hertz > 5000 )); then + print "ERROR3: $hertz hertz is too fast (max 5000)." >&2 + exit 3 + fi + if (( hertz < 1 )); then + print "ERROR4: $hertz hertz is too low (min 1)." >&2 + exit 4 + fi +else + usage +fi + +### Run DTrace +/usr/sbin/dtrace -n ' + #pragma D option quiet + + dtrace:::BEGIN + { + printf("Sampling at %d hertz... Hit Ctrl-C to end.\n",$1); + self->start = timestamp; + } + + profile:::profile-$1 + { + @Proc[pid, execname] = count(); + @BigProc[pid, execname] = sum(1000); /* dont ask */ + } + + dtrace:::END + { + this->end = timestamp; + + printf("%5s %-20s %10s\n", "PID", "CMD", "COUNT"); + printa("%5d %-20s %10@d\n", @Proc); + + normalize(@BigProc, + ((`ncpus_online * $1 * (this->end - self->start))/100000000)); + printf("\n%5s %-20s %10s\n", "PID", "CMD", "PERCENT"); + printa("%5d %-20s %10@d\n", @BigProc); + } +' $hertz diff --git a/Proc/shortlived.d b/Proc/shortlived.d new file mode 100755 index 0000000..268c370 --- /dev/null +++ b/Proc/shortlived.d @@ -0,0 +1,118 @@ +#!/usr/sbin/dtrace -qs +/* + * shortlived.d - determine time spent by short lived processes. + * Written in DTrace (Solaris 10 3/05). + * + * $Id: shortlived.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: shortlived.d # wait, then hit Ctrl-C + * + * Applications that run many short lived processes can cause load + * on the system that is difficult to identify - the processes + * aren't sampled in time by programs such as prstat. This program + * illustrates how much time was spent processing those extra + * processes, and a table of process name by total times for each. + * + * SEE ALSO: execsnoop + * + * Notes: + * - The measurements are minimum values, not all of the overheads + * caused by process generation and destruction are measured (DTrace + * can do so, but the script would become seriously complex). + * - The summary values are accurate, the by program and by PPID values + * are usually slightly smaller due to rounding errors. + * + * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 22-Apr-2005 Brendan Gregg Created this. + * 20-Apr-2006 " " Last update. + */ + +/* + * Start + */ +dtrace:::BEGIN +{ + /* save start time */ + start = timestamp; + + /* this is time spent on shortlived processes */ + procs = 0; + + /* print header */ + printf("Tracing... Hit Ctrl-C to stop.\n"); +} + +/* + * Measure parent fork time + */ +syscall::*fork*:entry +{ + /* save start of fork */ + self->fork = vtimestamp; +} +syscall::*fork*:return +/arg0 != 0 && self->fork/ +{ + /* record elapsed time for the fork syscall */ + this->elapsed = vtimestamp - self->fork; + procs += this->elapsed; + self->fork = 0; +} + +/* + * Measure child processes time + */ +syscall::*fork*:return +/arg0 == 0/ +{ + /* save start of child process */ + self->start = vtimestamp; + + /* memory cleanup */ + self->fork = 0; +} +proc:::exit +/self->start/ +{ + /* record elapsed time for process execution */ + this->elapsed = vtimestamp - self->start; + procs += this->elapsed; + + /* sum elapsed by process name and ppid */ + @Times_exec[execname] = sum(this->elapsed/1000000); + @Times_ppid[ppid] = sum(this->elapsed/1000000); + + /* memory cleanup */ + self->start = 0; +} + +/* + * Print report + */ +dtrace:::END +{ + this->total = timestamp - start; + printf("short lived processes: %6d.%03d secs\n", + procs/1000000000, (procs%1000000000)/1000000); + printf("total sample duration: %6d.%03d secs\n", + this->total/1000000000, (this->total%1000000000)/1000000); + printf("\nTotal time by process name,\n"); + printa("%18s %@12d ms\n", @Times_exec); + printf("\nTotal time by PPID,\n"); + printa("%18d %@12d ms\n", @Times_ppid); +} diff --git a/Proc/sigdist.d b/Proc/sigdist.d new file mode 100755 index 0000000..c3b2bc0 --- /dev/null +++ b/Proc/sigdist.d @@ -0,0 +1,61 @@ +#!/usr/sbin/dtrace -s +/* + * sigdist.d - signal distribution by process name. + * Written using DTrace (Solaris 10 3/05) + * + * This is a simple DTrace script that prints the number of signals + * recieved by process and signal number. This script is also available + * as /usr/demo/dtrace/sig.d, where it originates. + * + * $Id: sigdist.d 4 2007-08-01 11:01:38Z brendan $ + * + * USAGE: sigdist.d # hit Ctrl-C to end + * + * FIELDS: + * SENDER process name of sender + * RECIPIENT process name of target + * SIG signal number, see signal(3head) + * COUNT number of signals sent + * + * BASED ON: /usr/demo/dtrace/sig.d + * + * SEE ALSO: DTrace Guide "proc Provider" chapter (docs.sun.com) + * kill.d(1M) + * + * PORTIONS: Copyright (c) 2005, 2006 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 09-Jun-2005 Brendan Gregg Created this. + * 20-Apr-2006 " " Last update. + */ + +#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); +} diff --git a/Proc/stacksize.d b/Proc/stacksize.d new file mode 100755 index 0000000..fedcfbc --- /dev/null +++ b/Proc/stacksize.d @@ -0,0 +1,95 @@ +#!/usr/sbin/dtrace -s +/* + * stacksize.d - measure stack size for running threads. + * Written using DTrace (Solaris 10 3/05). + * + * $Id: stacksize.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: stacksize.d # hit Ctrl-C to end sample + * + * FIELDS: + * value size of the user stack + * count number of samples at this size + * + * SEE ALSO: pmap(1) + * + * COPYRIGHT: Copyright (c) 2006 Jonathan Adams + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 16-Feb-2006 Jonathan Adams Created this. + * 16-Feb-2006 " " Last update. + */ + +#pragma D option quiet + +this uintptr_t stkinfoptr; +this uintptr_t stkptr; + +dtrace:::BEGIN +{ + trace("Sampling... Hit Ctrl-C to end\n"); +} + +sched:::on-cpu, profile:::profile-997 +{ + this->stkinfoptr = 0; + this->stkptr = 0; +} + +sched:::on-cpu, profile:::profile-997 +/execname != "sched"/ +{ + this->stkinfoptr = curthread->t_lwp->lwp_ustack; + this->stkptr = (uintptr_t)0; +} + +sched:::on-cpu, profile:::profile-997 +/this->stkinfoptr != 0 && curpsinfo->pr_dmodel == PR_MODEL_ILP32/ +{ + this->stkinfo32 = (stack32_t *)copyin(this->stkinfoptr, + sizeof (stack32_t)); + this->stktop = (uintptr_t)this->stkinfo32->ss_sp + + this->stkinfo32->ss_size; + this->stkptr = (uintptr_t)uregs[R_SP]; +} + +sched:::on-cpu, profile:::profile-997 +/this->stkinfoptr != 0 && curpsinfo->pr_dmodel == PR_MODEL_LP64/ +{ + this->stkinfo = (stack_t *)copyin(this->stkinfoptr, + sizeof (stack_t)); + this->stktop = (uintptr_t)this->stkinfo->ss_sp + + this->stkinfo->ss_size; + this->stkptr = (uintptr_t)uregs[R_SP]; +} + +sched:::on-cpu, profile:::profile-997 +/this->stkptr != 0/ +{ + @sizes[execname] = quantize(this->stktop - this->stkptr); +} + +dtrace:::ERROR +{ + @errors[execname] = count(); +} + +dtrace:::END +{ + printa(@sizes); + printf("\nErrors:\n"); + printa(" %@d %s\n", @errors); +} diff --git a/Proc/sysbypid.d b/Proc/sysbypid.d new file mode 100755 index 0000000..bb80653 --- /dev/null +++ b/Proc/sysbypid.d @@ -0,0 +1,53 @@ +#!/usr/sbin/dtrace -s +/* + * sysbypid.d - print sysinfo events by process. + * Uses DTrace (Solaris 10 3/05). + * + * $Id: sysbypid.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: sysbypid.d + * + * FIELDS: + * EXEC Process name + * PID Process ID + * SYS System statistic (see /usr/include/sys/sysinfo.h) + * VALUE Value by which statistic was incremented + * + * The virtual memory statistics are documented in the cpu_sysinfo struct + * in the /usr/include/sys/sysinfo.h file; and also in the sysinfo provider + * chapter of the DTrace Guide, http://docs.sun.com/db/doc/817-6223. + * + * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 14-May-2005 Brendan Gregg Created this. + * 20-Apr-2006 " " Last update. + */ + +#pragma D option quiet + +dtrace:::BEGIN { + printf("Tracing... Hit Ctrl-C to end.\n"); +} + +sysinfo::: { + @Sys[execname, pid, probename] = sum(arg0); +} + +dtrace:::END { + printf("%16s %8s %22s %8s\n", "EXEC", "PID", "SYS", "VALUE"); + printa("%16s %8d %22s %@8d\n", @Sys); +} diff --git a/Proc/syscallbypid.d b/Proc/syscallbypid.d new file mode 100755 index 0000000..f33ac02 --- /dev/null +++ b/Proc/syscallbypid.d @@ -0,0 +1,54 @@ +#!/usr/sbin/dtrace -s +/* + * syscallbypid.d - report on syscalls by PID. + * Written using DTrace (Solaris 10 3/05) + * + * $Id: syscallbypid.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: syscallbypid.d # hit Ctrl-C to end sample + * + * FIELDS: + * PID process ID + * CMD process name + * SYSCALL syscall name + * COUNT number of syscalls for this PID + * + * This is based on a script from DExplorer. + * + * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * 15-May-2005 Brendan Gregg Created this. + * 20-Apr-2006 " " Last update. + */ + +#pragma D option quiet + +dtrace:::BEGIN +{ + printf("Tracing... Hit Ctrl-C to end.\n"); +} + +syscall:::entry +{ + @num[pid, execname, probefunc] = count(); +} + +dtrace:::END +{ + printf("%6s %-24s %-24s %8s\n", "PID", "CMD", "SYSCALL", "COUNT"); + printa("%6d %-24s %-24s %@8d\n", @num); +} diff --git a/Proc/syscallbyproc.d b/Proc/syscallbyproc.d new file mode 100755 index 0000000..d0faa75 --- /dev/null +++ b/Proc/syscallbyproc.d @@ -0,0 +1,10 @@ +#!/usr/sbin/dtrace -s +/* + * syscallbyproc.d - report on syscalls by process name . DTrace OneLiner. + * + * This is a DTrace OneLiner from the DTraceToolkit. + * + * $Id: syscallbyproc.d 3 2007-08-01 10:50:08Z brendan $ + */ + +syscall:::entry { @num[execname] = count(); } diff --git a/Proc/threaded.d b/Proc/threaded.d new file mode 100755 index 0000000..7f5770b --- /dev/null +++ b/Proc/threaded.d @@ -0,0 +1,66 @@ +#!/usr/sbin/dtrace -s +/* + * threaded.d - sample multi-threaded CPU usage. + * Written using DTrace (Solaris 10 3/05). + * + * This measures thread IDs as a process runs across multiple CPUs. + * It is a simple script that can help determine if a multi-threaded + * application is effectively using it's threads, or if the threads have + * serialised. See the example file in Docs/Examples/threaded_example.txt + * for a demonstration. + * + * $Id: threaded.d 3 2007-08-01 10:50:08Z brendan $ + * + * USAGE: threaded.d + * + * FIELDS: + * PID process ID + * CMD process name + * value thread ID + * count number of samples + * + * SEE ALSO: prstat -L + * + * COPYRIGHT: Copyright (c) 2005 Brendan Gregg. + * + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at Docs/cddl1.txt + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * CDDL HEADER END + * + * Author: Brendan Gregg [Sydney, Australia] + * + * 25-Jul-2005 Brendan Gregg Created this. + * 25-Jul-2005 " " Last update. + */ + +#pragma D option quiet + +/* + * Sample at 100 Hertz + */ +profile:::profile-100 +/pid != 0/ +{ + @sample[pid, execname] = lquantize(tid, 0, 128, 1); +} + +/* + * Print output every 1 second + */ +profile:::tick-1sec +{ + printf("%Y,\n", walltimestamp); + printa("\n PID: %-8d CMD: %s\n%@d", @sample); + printf("\n"); + trunc(@sample); +} diff --git a/Proc/topsysproc b/Proc/topsysproc new file mode 100755 index 0000000..5836f68 --- /dev/null +++ b/Proc/topsysproc @@ -0,0 +1,121 @@ +#!/usr/bin/sh +# +# topsysproc - display top syscalls by process name. +# Written using DTrace (Solaris 10 3/05). +# +# This program continually prints a report of the number of system calls +# by process name, and refreshes the display every 1 second or as specified +# at the command line. Similar data can be fetched with "prstat -m". +# +# $Id: topsysproc 19 2007-09-12 07:47:59Z brendan $ +# +# USAGE: topsysproc [interval] +# +# FIELDS: +# load avg load averages, see uptime(1) +# syscalls total number of syscalls in this interval +# PROCESS process name +# COUNT number of occurances in this interval +# +# NOTE: There may be several PIDs with the same process name. +# +# SEE ALSO: prstat(1M) +# +# INSPIRATION: top(1) by William LeFebvre +# +# COPYRIGHT: Copyright (c) 2005 Brendan Gregg. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at Docs/cddl1.txt +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# CDDL HEADER END +# +# 13-Jun-2005 Brendan Gregg Created this. +# 20-Apr-2006 " " Last update. +# + +# +# Check options +# +if [ "$1" = "-h" -o "$1" = "--help" ]; then + cat <<-END + USAGE: topsysproc [interval] + eg, + topsysproc # default, 1 second updates + topsysproc 5 # 5 second updates + END + exit 1 +fi +interval=1 +if [ "$1" -gt 0 ]; then + interval=$1 +fi + +# +# Run DTrace +# +/usr/sbin/dtrace -n ' + #pragma D option quiet + #pragma D option destructive + + /* constants */ + inline int INTERVAL = '$interval'; + inline int SCREEN = 20; + + /* variables */ + dtrace:::BEGIN + { + secs = 0; + printf("Tracing... Please wait.\n"); + } + + /* record syscall event */ + syscall:::entry + { + @Name[execname] = count(); + @Total = count(); + } + + /* update screen */ + profile:::tick-1sec + /++secs >= INTERVAL/ + { + /* fetch load averages */ + this->load1a = `hp_avenrun[0] / 65536; + this->load5a = `hp_avenrun[1] / 65536; + this->load15a = `hp_avenrun[2] / 65536; + this->load1b = ((`hp_avenrun[0] % 65536) * 100) / 65536; + this->load5b = ((`hp_avenrun[1] % 65536) * 100) / 65536; + this->load15b = ((`hp_avenrun[2] % 65536) * 100) / 65536; + + /* clear screen */ + system("clear"); + + /* print load average */ + printf("%Y, load average: %d.%02d, %d.%02d, %d.%02d", + walltimestamp, this->load1a, this->load1b, this->load5a, + this->load5b, this->load15a, this->load15b); + + /* print syscall count */ + printa(" syscalls: %@d\n",@Total); + + /* print report */ + trunc(@Name, SCREEN); + printf("\n %-25s %12s\n", "PROCESS", "COUNT"); + printa(" %-25s %@12d\n", @Name); + + /* reset variables */ + trunc(@Name); + clear(@Total); + secs = 0; + } +' diff --git a/Proc/writebytes.d b/Proc/writebytes.d new file mode 100755 index 0000000..1fec0e9 --- /dev/null +++ b/Proc/writebytes.d @@ -0,0 +1,10 @@ +#!/usr/sbin/dtrace -s +/* + * writebytes.d - write bytes by process name. DTrace OneLiner. + * + * This is a DTrace OneLiner from the DTraceToolkit. + * + * $Id: writebytes.d 3 2007-08-01 10:50:08Z brendan $ + */ + +sysinfo:::writech { @bytes[execname] = sum(arg0); } diff --git a/Proc/writedist.d b/Proc/writedist.d new file mode 100755 index 0000000..099c252 --- /dev/null +++ b/Proc/writedist.d @@ -0,0 +1,10 @@ +#!/usr/sbin/dtrace -s +/* + * writedist.d - write distribution by process name. DTrace OneLiner. + * + * This is a DTrace OneLiner from the DTraceToolkit. + * + * $Id: writedist.d 3 2007-08-01 10:50:08Z brendan $ + */ + +sysinfo:::writech { @dist[execname] = quantize(arg0); } |