summaryrefslogtreecommitdiffstats
path: root/Proc
diff options
context:
space:
mode:
authorgnn <gnn@FreeBSD.org>2012-05-12 20:38:18 +0000
committergnn <gnn@FreeBSD.org>2012-05-12 20:38:18 +0000
commit4297c1b2d07fec7f50b70e26e3adb4d062b19e15 (patch)
treeaec2772e8855e6dbaea6d8136ed0c47bcb825dee /Proc
parent111c75a23278cd9317f0a13867c22ee0f6c95b26 (diff)
downloadFreeBSD-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/Readme3
-rwxr-xr-xProc/crash.d181
-rwxr-xr-xProc/creatbyproc.d10
-rwxr-xr-xProc/dappprof239
-rwxr-xr-xProc/dapptrace259
-rwxr-xr-xProc/fddist116
-rwxr-xr-xProc/filebyproc.d10
-rwxr-xr-xProc/kill.d63
-rwxr-xr-xProc/lastwords90
-rwxr-xr-xProc/mmapfiles.d62
-rwxr-xr-xProc/newproc.d10
-rwxr-xr-xProc/pathopens.d100
-rwxr-xr-xProc/pfilestat282
-rwxr-xr-xProc/pidpersec.d57
-rwxr-xr-xProc/readbytes.d10
-rwxr-xr-xProc/readdist.d10
-rwxr-xr-xProc/rwbbypid.d61
-rwxr-xr-xProc/rwbypid.d61
-rwxr-xr-xProc/rwbytype.d101
-rwxr-xr-xProc/sampleproc105
-rwxr-xr-xProc/shortlived.d118
-rwxr-xr-xProc/sigdist.d61
-rwxr-xr-xProc/stacksize.d95
-rwxr-xr-xProc/sysbypid.d53
-rwxr-xr-xProc/syscallbypid.d54
-rwxr-xr-xProc/syscallbyproc.d10
-rwxr-xr-xProc/threaded.d66
-rwxr-xr-xProc/topsysproc121
-rwxr-xr-xProc/writebytes.d10
-rwxr-xr-xProc/writedist.d10
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); }
OpenPOWER on IntegriCloud