1*c29d5175Schristos#!/bin/sh 2*c29d5175Schristos# 3*c29d5175Schristos# dtruss - print process system call time details. 4*c29d5175Schristos# Written using DTrace (Solaris 10 3/05). 5*c29d5175Schristos# 6*c29d5175Schristos# $Id: dtruss,v 1.1.1.1 2015/09/30 22:01:06 christos Exp $ 7*c29d5175Schristos# 8*c29d5175Schristos# USAGE: dtruss [-acdeflhoLs] [-t syscall] { -p PID | -n name | command } 9*c29d5175Schristos# 10*c29d5175Schristos# -p PID # examine this PID 11*c29d5175Schristos# -n name # examine this process name 12*c29d5175Schristos# -t syscall # examine this syscall only 13*c29d5175Schristos# -a # print all details 14*c29d5175Schristos# -c # print system call counts 15*c29d5175Schristos# -d # print relative timestamps (us) 16*c29d5175Schristos# -e # print elapsed times (us) 17*c29d5175Schristos# -f # follow children as they are forked 18*c29d5175Schristos# -l # force printing of pid/lwpid per line 19*c29d5175Schristos# -o # print on cpu times (us) 20*c29d5175Schristos# -s # print stack backtraces 21*c29d5175Schristos# -L # don't print pid/lwpid per line 22*c29d5175Schristos# -b bufsize # dynamic variable buf size (default is "4m") 23*c29d5175Schristos# eg, 24*c29d5175Schristos# dtruss df -h # run and examine the "df -h" command 25*c29d5175Schristos# dtruss -p 1871 # examine PID 1871 26*c29d5175Schristos# dtruss -n tar # examine all processes called "tar" 27*c29d5175Schristos# dtruss -f test.sh # run test.sh and follow children 28*c29d5175Schristos# 29*c29d5175Schristos# See the man page dtruss(1M) for further details. 30*c29d5175Schristos# 31*c29d5175Schristos# SEE ALSO: procsystime # DTraceToolkit 32*c29d5175Schristos# dapptrace # DTraceToolkit 33*c29d5175Schristos# truss 34*c29d5175Schristos# 35*c29d5175Schristos# COPYRIGHT: Copyright (c) 2005, 2006, 2007 Brendan Gregg. 36*c29d5175Schristos# 37*c29d5175Schristos# CDDL HEADER START 38*c29d5175Schristos# 39*c29d5175Schristos# The contents of this file are subject to the terms of the 40*c29d5175Schristos# Common Development and Distribution License, Version 1.0 only 41*c29d5175Schristos# (the "License"). You may not use this file except in compliance 42*c29d5175Schristos# with the License. 43*c29d5175Schristos# 44*c29d5175Schristos# You can obtain a copy of the license at Docs/cddl1.txt 45*c29d5175Schristos# or http://www.opensolaris.org/os/licensing. 46*c29d5175Schristos# See the License for the specific language governing permissions 47*c29d5175Schristos# and limitations under the License. 48*c29d5175Schristos# 49*c29d5175Schristos# CDDL HEADER END 50*c29d5175Schristos# 51*c29d5175Schristos# TODO: Track signals, more output formatting. 52*c29d5175Schristos# 53*c29d5175Schristos# 29-Apr-2005 Brendan Gregg Created this. 54*c29d5175Schristos# 09-May-2005 " " Fixed evaltime (thanks Adam L.) 55*c29d5175Schristos# 16-May-2005 " " Added -t syscall tracing. 56*c29d5175Schristos# 17-Jun-2005 " " Added -s stack backtraces. 57*c29d5175Schristos# 17-Jun-2005 " " Last update. 58*c29d5175Schristos# 29-Jun-2007 " " Used progenyof() (thanks Aaron Gutman). 59*c29d5175Schristos# 06-Aug-2007 " " Various updates. 60*c29d5175Schristos# 61*c29d5175Schristos 62*c29d5175Schristos 63*c29d5175Schristos############################## 64*c29d5175Schristos# --- Process Arguments --- 65*c29d5175Schristos# 66*c29d5175Schristos 67*c29d5175Schristos### Default variables 68*c29d5175Schristosopt_pid=0; opt_name=0; pid=0; pname="."; opt_elapsed=0; opt_cpu=0 69*c29d5175Schristosopt_counts=0; opt_relative=0; opt_printid=0; opt_follow=0; opt_command=0 70*c29d5175Schristoscommand=""; opt_buf=0; buf="4m"; opt_trace=0; trace="."; opt_stack=0 71*c29d5175Schristos 72*c29d5175Schristos### Process options 73*c29d5175Schristoswhile getopts ab:cdefhln:op:st:L name 74*c29d5175Schristosdo 75*c29d5175Schristos case $name in 76*c29d5175Schristos b) opt_buf=1; buf=$OPTARG ;; 77*c29d5175Schristos p) opt_pid=1; pid=$OPTARG ;; 78*c29d5175Schristos n) opt_name=1; pname=$OPTARG ;; 79*c29d5175Schristos t) opt_trace=1; trace=$OPTARG ;; 80*c29d5175Schristos a) opt_counts=1; opt_relative=1; opt_elapsed=1; opt_follow=1 81*c29d5175Schristos opt_printid=1; opt_cpu=1 ;; 82*c29d5175Schristos c) opt_counts=1 ;; 83*c29d5175Schristos d) opt_relative=1 ;; 84*c29d5175Schristos e) opt_elapsed=1 ;; 85*c29d5175Schristos f) opt_follow=1 ;; 86*c29d5175Schristos l) opt_printid=1 ;; 87*c29d5175Schristos o) opt_cpu=1 ;; 88*c29d5175Schristos L) opt_printid=-1 ;; 89*c29d5175Schristos s) opt_stack=-1 ;; 90*c29d5175Schristos h|?) cat <<-END >&2 91*c29d5175Schristos USAGE: dtruss [-acdefholLs] [-t syscall] { -p PID | -n name | command } 92*c29d5175Schristos 93*c29d5175Schristos -p PID # examine this PID 94*c29d5175Schristos -n name # examine this process name 95*c29d5175Schristos -t syscall # examine this syscall only 96*c29d5175Schristos -a # print all details 97*c29d5175Schristos -c # print syscall counts 98*c29d5175Schristos -d # print relative times (us) 99*c29d5175Schristos -e # print elapsed times (us) 100*c29d5175Schristos -f # follow children (-p or cmd only) 101*c29d5175Schristos -l # force printing pid/lwpid 102*c29d5175Schristos -o # print on cpu times 103*c29d5175Schristos -s # print stack backtraces 104*c29d5175Schristos -L # don't print pid/lwpid 105*c29d5175Schristos -b bufsize # dynamic variable buf size 106*c29d5175Schristos eg, 107*c29d5175Schristos dtruss df -h # run and examine "df -h" 108*c29d5175Schristos dtruss -p 1871 # examine PID 1871 109*c29d5175Schristos dtruss -n tar # examine all processes called "tar" 110*c29d5175Schristos dtruss -f test.sh # run test.sh and follow children 111*c29d5175Schristos END 112*c29d5175Schristos exit 1 113*c29d5175Schristos esac 114*c29d5175Schristosdone 115*c29d5175Schristosshift `expr $OPTIND - 1` 116*c29d5175Schristos 117*c29d5175Schristos### Option logic 118*c29d5175Schristosif [ $opt_pid -eq 0 -a $opt_name -eq 0 ]; then 119*c29d5175Schristos opt_command=1 120*c29d5175Schristos if [ "$*" = "" ]; then 121*c29d5175Schristos $0 -h 122*c29d5175Schristos exit 123*c29d5175Schristos fi 124*c29d5175Schristos command="$*" # yes, I meant $*! 125*c29d5175Schristosfi 126*c29d5175Schristosif [ $opt_follow -eq 1 -o $opt_name -eq 1 ]; then 127*c29d5175Schristos if [ $opt_printid -ne -1 ]; then 128*c29d5175Schristos opt_printid=1 129*c29d5175Schristos else 130*c29d5175Schristos opt_printid=0 131*c29d5175Schristos fi 132*c29d5175Schristosfi 133*c29d5175Schristosif [ $opt_follow -eq 1 -a $opt_name -eq 1 ]; then 134*c29d5175Schristos echo "ERROR: -f option cannot be used with -n (use -p or cmd instead)." 135*c29d5175Schristos exit 1 136*c29d5175Schristosfi 137*c29d5175Schristos 138*c29d5175Schristos### Option translation 139*c29d5175Schristosif [ "$trace" = "exec" ]; then trace="exece"; fi 140*c29d5175Schristosif [ "$trace" = "time" ]; then trace="gtime"; fi 141*c29d5175Schristosif [ "$trace" = "exit" ]; then trace="rexit"; fi 142*c29d5175Schristos 143*c29d5175Schristos 144*c29d5175Schristos################################# 145*c29d5175Schristos# --- Main Program, DTrace --- 146*c29d5175Schristos# 147*c29d5175Schristos 148*c29d5175Schristos### Define D Script 149*c29d5175Schristosdtrace=' 150*c29d5175Schristos#pragma D option quiet 151*c29d5175Schristos#pragma D option switchrate=10 152*c29d5175Schristos 153*c29d5175Schristos/* 154*c29d5175Schristos * Command line arguments 155*c29d5175Schristos */ 156*c29d5175Schristosinline int OPT_command = '$opt_command'; 157*c29d5175Schristosinline int OPT_follow = '$opt_follow'; 158*c29d5175Schristosinline int OPT_printid = '$opt_printid'; 159*c29d5175Schristosinline int OPT_relative = '$opt_relative'; 160*c29d5175Schristosinline int OPT_elapsed = '$opt_elapsed'; 161*c29d5175Schristosinline int OPT_cpu = '$opt_cpu'; 162*c29d5175Schristosinline int OPT_counts = '$opt_counts'; 163*c29d5175Schristosinline int OPT_pid = '$opt_pid'; 164*c29d5175Schristosinline int OPT_name = '$opt_name'; 165*c29d5175Schristosinline int OPT_trace = '$opt_trace'; 166*c29d5175Schristosinline int OPT_stack = '$opt_stack'; 167*c29d5175Schristosinline string NAME = "'$pname'"; 168*c29d5175Schristosinline string TRACE = "'$trace'"; 169*c29d5175Schristos 170*c29d5175Schristosdtrace:::BEGIN 171*c29d5175Schristos{ 172*c29d5175Schristos /* print header */ 173*c29d5175Schristos OPT_printid ? printf("%-9s ", "PID/LWP") : 1; 174*c29d5175Schristos OPT_relative ? printf("%8s ", "RELATIVE") : 1; 175*c29d5175Schristos OPT_elapsed ? printf("%7s ", "ELAPSD") : 1; 176*c29d5175Schristos OPT_cpu ? printf("%6s ", "CPU") : 1; 177*c29d5175Schristos printf("SYSCALL(args) \t\t = return\n"); 178*c29d5175Schristos} 179*c29d5175Schristos 180*c29d5175Schristos/* 181*c29d5175Schristos * Save syscall entry info 182*c29d5175Schristos */ 183*c29d5175Schristossyscall:::entry 184*c29d5175Schristos/((OPT_command || OPT_pid) && pid == $target) || 185*c29d5175Schristos (OPT_name && execname == NAME) || 186*c29d5175Schristos (OPT_follow && progenyof($target))/ 187*c29d5175Schristos{ 188*c29d5175Schristos /* set start details */ 189*c29d5175Schristos self->start = timestamp; 190*c29d5175Schristos self->vstart = vtimestamp; 191*c29d5175Schristos self->arg0 = arg0; 192*c29d5175Schristos self->arg1 = arg1; 193*c29d5175Schristos self->arg2 = arg2; 194*c29d5175Schristos 195*c29d5175Schristos /* count occurances */ 196*c29d5175Schristos OPT_counts == 1 ? @Counts[probefunc] = count() : 1; 197*c29d5175Schristos} 198*c29d5175Schristos 199*c29d5175Schristos/* 200*c29d5175Schristos * Follow children 201*c29d5175Schristos */ 202*c29d5175Schristossyscall::fork*:return 203*c29d5175Schristos/(OPT_follow && progenyof($target)) && (!OPT_trace || (TRACE == probefunc))/ 204*c29d5175Schristos{ 205*c29d5175Schristos /* print output */ 206*c29d5175Schristos self->code = errno == 0 ? "" : "Err#"; 207*c29d5175Schristos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 208*c29d5175Schristos OPT_relative ? printf("%8d: ", vtimestamp/1000) : 1; 209*c29d5175Schristos OPT_elapsed ? printf("%7d: ", 0) : 1; 210*c29d5175Schristos OPT_cpu ? printf("%6d ", 0) : 1; 211*c29d5175Schristos printf("%s(0x%X, 0x%X, 0x%X)\t\t = %d %s%d\n", probefunc, 212*c29d5175Schristos self->arg0, self->arg1, self->arg2, (int)arg0, self->code, 213*c29d5175Schristos (int)errno); 214*c29d5175Schristos} 215*c29d5175Schristos 216*c29d5175Schristos/* 217*c29d5175Schristos * Check for syscall tracing 218*c29d5175Schristos */ 219*c29d5175Schristossyscall:::entry 220*c29d5175Schristos/OPT_trace && probefunc != TRACE/ 221*c29d5175Schristos{ 222*c29d5175Schristos /* drop info */ 223*c29d5175Schristos self->start = 0; 224*c29d5175Schristos self->vstart = 0; 225*c29d5175Schristos self->arg0 = 0; 226*c29d5175Schristos self->arg1 = 0; 227*c29d5175Schristos self->arg2 = 0; 228*c29d5175Schristos} 229*c29d5175Schristos 230*c29d5175Schristos/* 231*c29d5175Schristos * Print return data 232*c29d5175Schristos */ 233*c29d5175Schristos 234*c29d5175Schristos/* 235*c29d5175Schristos * The following code is written in an intentionally repetative way. 236*c29d5175Schristos * The first versions had no code redundancies, but performed badly during 237*c29d5175Schristos * benchmarking. The priority here is speed, not cleverness. I know there 238*c29d5175Schristos * are many obvious shortcuts to this code, I have tried them. This style has 239*c29d5175Schristos * shown in benchmarks to be the fastest (fewest probes fired, fewest actions). 240*c29d5175Schristos */ 241*c29d5175Schristos 242*c29d5175Schristos/* print 3 args, return as hex */ 243*c29d5175Schristossyscall::sigprocmask:return 244*c29d5175Schristos/self->start/ 245*c29d5175Schristos{ 246*c29d5175Schristos /* calculate elapsed time */ 247*c29d5175Schristos this->elapsed = timestamp - self->start; 248*c29d5175Schristos self->start = 0; 249*c29d5175Schristos this->cpu = vtimestamp - self->vstart; 250*c29d5175Schristos self->vstart = 0; 251*c29d5175Schristos self->code = errno == 0 ? "" : "Err#"; 252*c29d5175Schristos 253*c29d5175Schristos /* print optional fields */ 254*c29d5175Schristos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 255*c29d5175Schristos OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; 256*c29d5175Schristos OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; 257*c29d5175Schristos OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; 258*c29d5175Schristos 259*c29d5175Schristos /* print main data */ 260*c29d5175Schristos printf("%s(0x%X, 0x%X, 0x%X)\t\t = 0x%X %s%d\n", probefunc, 261*c29d5175Schristos (int)self->arg0, self->arg1, self->arg2, (int)arg0, 262*c29d5175Schristos self->code, (int)errno); 263*c29d5175Schristos OPT_stack ? ustack() : 1; 264*c29d5175Schristos OPT_stack ? trace("\n") : 1; 265*c29d5175Schristos self->arg0 = 0; 266*c29d5175Schristos self->arg1 = 0; 267*c29d5175Schristos self->arg2 = 0; 268*c29d5175Schristos} 269*c29d5175Schristos 270*c29d5175Schristos/* print 3 args, arg0 as a string */ 271*c29d5175Schristossyscall::access*:return, 272*c29d5175Schristossyscall::stat*:return, 273*c29d5175Schristossyscall::lstat*:return, 274*c29d5175Schristossyscall::readlink*:return, 275*c29d5175Schristossyscall::open*:return 276*c29d5175Schristos/self->start/ 277*c29d5175Schristos{ 278*c29d5175Schristos /* calculate elapsed time */ 279*c29d5175Schristos this->elapsed = timestamp - self->start; 280*c29d5175Schristos self->start = 0; 281*c29d5175Schristos this->cpu = vtimestamp - self->vstart; 282*c29d5175Schristos self->vstart = 0; 283*c29d5175Schristos self->code = errno == 0 ? "" : "Err#"; 284*c29d5175Schristos 285*c29d5175Schristos /* print optional fields */ 286*c29d5175Schristos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 287*c29d5175Schristos OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; 288*c29d5175Schristos OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; 289*c29d5175Schristos OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; 290*c29d5175Schristos 291*c29d5175Schristos /* print main data */ 292*c29d5175Schristos printf("%s(\"%S\", 0x%X, 0x%X)\t\t = %d %s%d\n", probefunc, 293*c29d5175Schristos copyinstr(self->arg0), self->arg1, self->arg2, (int)arg0, 294*c29d5175Schristos self->code, (int)errno); 295*c29d5175Schristos OPT_stack ? ustack() : 1; 296*c29d5175Schristos OPT_stack ? trace("\n") : 1; 297*c29d5175Schristos self->arg0 = 0; 298*c29d5175Schristos self->arg1 = 0; 299*c29d5175Schristos self->arg2 = 0; 300*c29d5175Schristos} 301*c29d5175Schristos 302*c29d5175Schristos/* print 3 args, arg1 as a string */ 303*c29d5175Schristossyscall::write:return, 304*c29d5175Schristossyscall::pwrite:return, 305*c29d5175Schristossyscall::*read*:return 306*c29d5175Schristos/self->start/ 307*c29d5175Schristos{ 308*c29d5175Schristos /* calculate elapsed time */ 309*c29d5175Schristos this->elapsed = timestamp - self->start; 310*c29d5175Schristos self->start = 0; 311*c29d5175Schristos this->cpu = vtimestamp - self->vstart; 312*c29d5175Schristos self->vstart = 0; 313*c29d5175Schristos self->code = errno == 0 ? "" : "Err#"; 314*c29d5175Schristos 315*c29d5175Schristos /* print optional fields */ 316*c29d5175Schristos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 317*c29d5175Schristos OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; 318*c29d5175Schristos OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; 319*c29d5175Schristos OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; 320*c29d5175Schristos 321*c29d5175Schristos /* print main data */ 322*c29d5175Schristos printf("%s(0x%X, \"%S\", 0x%X)\t\t = %d %s%d\n", probefunc, self->arg0, 323*c29d5175Schristos stringof(copyin(self->arg1, self->arg2)), self->arg2, (int)arg0, 324*c29d5175Schristos self->code, (int)errno); 325*c29d5175Schristos OPT_stack ? ustack() : 1; 326*c29d5175Schristos OPT_stack ? trace("\n") : 1; 327*c29d5175Schristos self->arg0 = 0; 328*c29d5175Schristos self->arg1 = 0; 329*c29d5175Schristos self->arg2 = 0; 330*c29d5175Schristos} 331*c29d5175Schristos 332*c29d5175Schristos/* print 0 arg output */ 333*c29d5175Schristossyscall::*fork*:return 334*c29d5175Schristos/self->start/ 335*c29d5175Schristos{ 336*c29d5175Schristos /* calculate elapsed time */ 337*c29d5175Schristos this->elapsed = timestamp - self->start; 338*c29d5175Schristos self->start = 0; 339*c29d5175Schristos this->cpu = vtimestamp - self->vstart; 340*c29d5175Schristos self->vstart = 0; 341*c29d5175Schristos self->code = errno == 0 ? "" : "Err#"; 342*c29d5175Schristos 343*c29d5175Schristos /* print optional fields */ 344*c29d5175Schristos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 345*c29d5175Schristos OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; 346*c29d5175Schristos OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; 347*c29d5175Schristos OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; 348*c29d5175Schristos 349*c29d5175Schristos /* print main data */ 350*c29d5175Schristos printf("%s()\t\t = %d %s%d\n", probefunc, 351*c29d5175Schristos (int)arg0, self->code, (int)errno); 352*c29d5175Schristos OPT_stack ? ustack() : 1; 353*c29d5175Schristos OPT_stack ? trace("\n") : 1; 354*c29d5175Schristos self->arg0 = 0; 355*c29d5175Schristos self->arg1 = 0; 356*c29d5175Schristos self->arg2 = 0; 357*c29d5175Schristos} 358*c29d5175Schristos 359*c29d5175Schristos/* print 1 arg output */ 360*c29d5175Schristossyscall::close:return 361*c29d5175Schristos/self->start/ 362*c29d5175Schristos{ 363*c29d5175Schristos /* calculate elapsed time */ 364*c29d5175Schristos this->elapsed = timestamp - self->start; 365*c29d5175Schristos self->start = 0; 366*c29d5175Schristos this->cpu = vtimestamp - self->vstart; 367*c29d5175Schristos self->vstart = 0; 368*c29d5175Schristos self->code = errno == 0 ? "" : "Err#"; 369*c29d5175Schristos 370*c29d5175Schristos /* print optional fields */ 371*c29d5175Schristos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 372*c29d5175Schristos OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; 373*c29d5175Schristos OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; 374*c29d5175Schristos OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; 375*c29d5175Schristos 376*c29d5175Schristos /* print main data */ 377*c29d5175Schristos printf("%s(0x%X)\t\t = %d %s%d\n", probefunc, self->arg0, 378*c29d5175Schristos (int)arg0, self->code, (int)errno); 379*c29d5175Schristos OPT_stack ? ustack() : 1; 380*c29d5175Schristos OPT_stack ? trace("\n") : 1; 381*c29d5175Schristos self->arg0 = 0; 382*c29d5175Schristos self->arg1 = 0; 383*c29d5175Schristos self->arg2 = 0; 384*c29d5175Schristos} 385*c29d5175Schristos 386*c29d5175Schristos/* print 2 arg output */ 387*c29d5175Schristossyscall::utimes:return, 388*c29d5175Schristossyscall::munmap:return 389*c29d5175Schristos/self->start/ 390*c29d5175Schristos{ 391*c29d5175Schristos /* calculate elapsed time */ 392*c29d5175Schristos this->elapsed = timestamp - self->start; 393*c29d5175Schristos self->start = 0; 394*c29d5175Schristos this->cpu = vtimestamp - self->vstart; 395*c29d5175Schristos self->vstart = 0; 396*c29d5175Schristos self->code = errno == 0 ? "" : "Err#"; 397*c29d5175Schristos 398*c29d5175Schristos /* print optional fields */ 399*c29d5175Schristos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 400*c29d5175Schristos OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; 401*c29d5175Schristos OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; 402*c29d5175Schristos OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; 403*c29d5175Schristos 404*c29d5175Schristos /* print main data */ 405*c29d5175Schristos printf("%s(0x%X, 0x%X)\t\t = %d %s%d\n", probefunc, self->arg0, 406*c29d5175Schristos self->arg1, (int)arg0, self->code, (int)errno); 407*c29d5175Schristos OPT_stack ? ustack() : 1; 408*c29d5175Schristos OPT_stack ? trace("\n") : 1; 409*c29d5175Schristos self->arg0 = 0; 410*c29d5175Schristos self->arg1 = 0; 411*c29d5175Schristos self->arg2 = 0; 412*c29d5175Schristos} 413*c29d5175Schristos 414*c29d5175Schristos/* print 3 arg output - default */ 415*c29d5175Schristossyscall:::return 416*c29d5175Schristos/self->start/ 417*c29d5175Schristos{ 418*c29d5175Schristos /* calculate elapsed time */ 419*c29d5175Schristos this->elapsed = timestamp - self->start; 420*c29d5175Schristos self->start = 0; 421*c29d5175Schristos this->cpu = vtimestamp - self->vstart; 422*c29d5175Schristos self->vstart = 0; 423*c29d5175Schristos self->code = errno == 0 ? "" : "Err#"; 424*c29d5175Schristos 425*c29d5175Schristos /* print optional fields */ 426*c29d5175Schristos OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; 427*c29d5175Schristos OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; 428*c29d5175Schristos OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; 429*c29d5175Schristos OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; 430*c29d5175Schristos 431*c29d5175Schristos /* print main data */ 432*c29d5175Schristos printf("%s(0x%X, 0x%X, 0x%X)\t\t = %d %s%d\n", probefunc, self->arg0, 433*c29d5175Schristos self->arg1, self->arg2, (int)arg0, self->code, (int)errno); 434*c29d5175Schristos OPT_stack ? ustack() : 1; 435*c29d5175Schristos OPT_stack ? trace("\n") : 1; 436*c29d5175Schristos self->arg0 = 0; 437*c29d5175Schristos self->arg1 = 0; 438*c29d5175Schristos self->arg2 = 0; 439*c29d5175Schristos} 440*c29d5175Schristos 441*c29d5175Schristos/* program exited */ 442*c29d5175Schristosproc:::exit 443*c29d5175Schristos/(OPT_command || OPT_pid) && pid == $target/ 444*c29d5175Schristos{ 445*c29d5175Schristos exit(0); 446*c29d5175Schristos} 447*c29d5175Schristos 448*c29d5175Schristos/* print counts */ 449*c29d5175Schristosdtrace:::END 450*c29d5175Schristos{ 451*c29d5175Schristos OPT_counts == 1 ? printf("\n%-32s %16s\n", "CALL", "COUNT") : 1; 452*c29d5175Schristos OPT_counts == 1 ? printa("%-32s %@16d\n", @Counts) : 1; 453*c29d5175Schristos} 454*c29d5175Schristos' 455*c29d5175Schristos 456*c29d5175Schristos### Run DTrace 457*c29d5175Schristosif [ $opt_command -eq 1 ]; then 458*c29d5175Schristos /usr/sbin/dtrace -x dynvarsize=$buf -x evaltime=exec -n "$dtrace" \ 459*c29d5175Schristos -c "$command" >&2 460*c29d5175Schristoselif [ $opt_pid -eq 1 ]; then 461*c29d5175Schristos /usr/sbin/dtrace -x dynvarsize=$buf -n "$dtrace" -p "$pid" >&2 462*c29d5175Schristoselse 463*c29d5175Schristos /usr/sbin/dtrace -x dynvarsize=$buf -n "$dtrace" >&2 464*c29d5175Schristosfi 465