diff options
Diffstat (limited to 'cddl/contrib/dtracetoolkit/procsystime')
-rwxr-xr-x | cddl/contrib/dtracetoolkit/procsystime | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/cddl/contrib/dtracetoolkit/procsystime b/cddl/contrib/dtracetoolkit/procsystime new file mode 100755 index 0000000..3b4bae7 --- /dev/null +++ b/cddl/contrib/dtracetoolkit/procsystime @@ -0,0 +1,233 @@ +#!/bin/sh +# +# procsystime - print process system call time details. +# Written using DTrace (Solaris 10 3/05). +# +# $Id: procsystime 4 2007-08-01 11:01:38Z brendan $ +# +# USAGE: procsystime [-acehoT] [ -p PID | -n name | command ] +# +# -p PID # examine this PID +# -n name # examine this process name +# -a # print all details +# -c # print syscall counts +# -e # print elapsed times +# -o # print CPU times +# -T # print totals +# eg, +# procsystime -p 1871 # examine PID 1871 +# procsystime -n tar # examine processes called "tar" +# procsystime -aTn bash # print all details for bash shells +# procsystime df -h # run and examine "df -h" +# +# The elapsed times are interesting, to help identify syscalls that take +# some time to complete (during which the process may have slept). CPU time +# helps us identify syscalls that are consuming CPU cycles to run. +# +# FIELDS: +# SYSCALL System call name +# TIME (ns) Total time, nanoseconds +# COUNT Number of occurrences +# +# 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] +# +# 27-Apr-2005 Brendan Gregg Created this. +# 08-Jun-2005 " " Added command option. +# 22-Sep-2005 " " Allowed systemwide tracing. +# 22-Sep-2005 " " Last update. +# + + +############################## +# --- Process Arguments --- +# + +### Default variables +opt_filter=0; opt_pid=0; opt_name=0; pid=0; pname="."; +opt_elapsed=0; opt_cpu=0; opt_counts=0; opt_totals=0 +opt_command=0; command=""; + +### Process options +while getopts acehn:op:T name +do + case $name in + p) opt_filter=1; opt_pid=1; pid=$OPTARG ;; + n) opt_filter=1; opt_name=1; pname=$OPTARG ;; + a) opt_totals=1; opt_elapsed=1; opt_cpu=1; opt_counts=1 ;; + e) opt_elapsed=1 ;; + c) opt_counts=1 ;; + o) opt_cpu=1 ;; + T) opt_totals=1 ;; + h|?) cat <<-END >&2 + USAGE: procsystime [-aceho] [ -p PID | -n name | command ] + -p PID # examine this PID + -n name # examine this process name + -a # print all details + -e # print elapsed times + -c # print syscall counts + -o # print CPU times + -T # print totals + eg, + procsystime -p 1871 # examine PID 1871 + procsystime -n tar # examine processes called "tar" + procsystime -aTn bash # print all details for bash + procsystime df -h # run and examine "df -h" + END + exit 1 + esac +done +shift `expr $OPTIND - 1` + +### Option logic +if [ $opt_pid -eq 0 -a $opt_name -eq 0 -a "$*" != "" ]; then + opt_filter=1 + opt_command=1 + command="$*" +fi +if [ $opt_elapsed -eq 0 -a $opt_cpu -eq 0 -a $opt_counts -eq 0 ]; then + opt_elapsed=1; +fi + + +################################# +# --- Main Program, DTrace --- +# +dtrace=' + #pragma D option quiet + + /* + * Command line arguments + */ + inline int OPT_elapsed = '$opt_elapsed'; + inline int OPT_cpu = '$opt_cpu'; + inline int OPT_counts = '$opt_counts'; + inline int OPT_filter = '$opt_filter'; + inline int OPT_pid = '$opt_pid'; + inline int OPT_name = '$opt_name'; + inline int OPT_totals = '$opt_totals'; + inline int OPT_command = '$opt_command'; + inline int PID = '$pid'; + inline string NAME = "'$pname'"; + inline string COMMAND = "'$command'"; + + dtrace:::BEGIN + { + self->start = 0; + self->vstart = 0; + } + dtrace:::BEGIN + /! OPT_command/ + { + printf("Tracing... Hit Ctrl-C to end...\n"); + } + + /* + * Set start timestamp and counts + */ + syscall:::entry + /(! OPT_filter) || + (OPT_pid && pid == PID) || + (OPT_name && execname == NAME) || + (OPT_command && pid == $target)/ + { + self->ok = 1; + } + syscall:::entry + /self->ok/ + { + OPT_counts ? @Counts[probefunc] = count() : 1; + (OPT_counts && OPT_totals) ? @Counts["TOTAL:"] = count() : 1; + OPT_elapsed ? self->start = timestamp : 1; + OPT_cpu ? self->vstart = vtimestamp : 1; + self->ok = 0; + } + + /* + * Calculate time deltas + */ + syscall:::return + /self->start/ + { + this->elapsed = timestamp - self->start; + @Elapsed[probefunc] = sum(this->elapsed); + OPT_totals ? @Elapsed["TOTAL:"] = sum(this->elapsed) : 1; + self->start = 0; + } + syscall:::return + /self->vstart/ + { + this->cpu = vtimestamp - self->vstart; + @CPU[probefunc] = sum(this->cpu); + OPT_totals ? @CPU["TOTAL:"] = sum(this->cpu) : 1; + self->vstart = 0; + } + + /* + * Elapsed time report + */ + dtrace:::END + /OPT_elapsed/ + { + printf("\nElapsed Times for "); + OPT_pid ? printf("PID %d,\n\n",PID) : 1; + OPT_name ? printf("processes %s,\n\n",NAME) : 1; + OPT_command ? printf("command %s,\n\n",COMMAND) : 1; + (! OPT_filter) ? printf("all processes,\n\n") : 1; + printf("%16s %18s\n","SYSCALL","TIME (ns)"); + printa("%16s %@18d\n",@Elapsed); + } + + /* + * CPU time report + */ + dtrace:::END + /OPT_cpu/ + { + printf("\nCPU Times for "); + OPT_pid ? printf("PID %d,\n\n",PID) : 1; + OPT_name ? printf("processes %s,\n\n",NAME) : 1; + OPT_command ? printf("command %s,\n\n",COMMAND) : 1; + (! OPT_filter) ? printf("all processes,\n\n") : 1; + printf("%16s %18s\n","SYSCALL","TIME (ns)"); + printa("%16s %@18d\n",@CPU); + } + + /* + * Syscall count report + */ + dtrace:::END + /OPT_counts/ + { + printf("\nSyscall Counts for "); + OPT_pid ? printf("PID %d,\n\n",PID) : 1; + OPT_name ? printf("processes %s,\n\n",NAME) : 1; + OPT_command ? printf("command %s,\n\n",COMMAND) : 1; + (! OPT_filter) ? printf("all processes,\n\n") : 1; + printf("%16s %18s\n","SYSCALL","COUNT"); + OPT_counts ? printa("%16s %@18d\n",@Counts) : 1; + } +' + +### Run DTrace +if [ $opt_command -eq 1 ]; then + /usr/sbin/dtrace -n "$dtrace" -x evaltime=exec -c "$command" >&2 +else + /usr/sbin/dtrace -n "$dtrace" >&2 +fi + |