xref: /netbsd-src/external/cddl/dtracetoolkit/dist/dtruss (revision c29d51755812ace2e87aeefdb06cb2b4dac7087a)
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