sh_flowinfo.d revision 235380
167754Smsmith#!/usr/sbin/dtrace -Zs
267754Smsmith/*
377424Smsmith * sh_flowinfo.d - snoop Bourne shell flow with additional info.
4123315Snjl *                 Written for the sh DTrace provider.
567754Smsmith *
667754Smsmith * $Id: sh_flowinfo.d 52 2007-09-24 04:28:01Z brendan $
767754Smsmith *
867754Smsmith * This traces shell activity from all Bourne shells on the system that are
967754Smsmith * running with sh provider support.
1067754Smsmith *
1167754Smsmith * USAGE: sh_flowinfo.d			# hit Ctrl-C to end
12114237Snjl *
1370243Smsmith * This watches shell function entries and returns, and indents child
1467754Smsmith * function calls. Shell builtins and external commands are also printed.
1567754Smsmith *
1667754Smsmith * FIELDS:
1767754Smsmith *		C		CPU-id
1867754Smsmith *		PID		Process ID
1967754Smsmith *		DELTA(us)	Elapsed time from previous line to this line
2067754Smsmith *		FILE		Filename of the shell script
2167754Smsmith *		LINE		Line number of filename
2267754Smsmith *		TYPE		Type of call (func/builtin/cmd/subsh)
2367754Smsmith *		NAME		Shell function, builtin or command name
2467754Smsmith *
2567754Smsmith * WARNING: Watch the first column carefully, it prints the CPU-id. If it
2667754Smsmith * changes, then it is very likely that the output has been shuffled.
2767754Smsmith *
2867754Smsmith * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
2967754Smsmith *
3067754Smsmith * CDDL HEADER START
3167754Smsmith *
3267754Smsmith *  The contents of this file are subject to the terms of the
3367754Smsmith *  Common Development and Distribution License, Version 1.0 only
3467754Smsmith *  (the "License").  You may not use this file except in compliance
3567754Smsmith *  with the License.
3667754Smsmith *
3767754Smsmith *  You can obtain a copy of the license at Docs/cddl1.txt
3867754Smsmith *  or http://www.opensolaris.org/os/licensing.
3967754Smsmith *  See the License for the specific language governing permissions
4067754Smsmith *  and limitations under the License.
4167754Smsmith *
4267754Smsmith * CDDL HEADER END
4367754Smsmith *
4467754Smsmith * 09-Sep-2007	Brendan Gregg	Created this.
4567754Smsmith */
4667754Smsmith
4767754Smsmith#pragma D option quiet
4867754Smsmith#pragma D option switchrate=10
4967754Smsmith
5067754Smsmithself int depth;
5167754Smsmith
5267754Smsmithdtrace:::BEGIN
5367754Smsmith{
5467754Smsmith	self->depth = 0;
5567754Smsmith	printf("%3s %6s %10s  %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)",
5667754Smsmith	    "FILE", "LINE", "TYPE", "NAME");
5767754Smsmith}
5867754Smsmith
5967754Smsmithsh*:::function-entry,
6067754Smsmithsh*:::function-return,
6167754Smsmithsh*:::builtin-entry,
6267754Smsmithsh*:::builtin-return,
6367754Smsmithsh*:::command-entry,
6467754Smsmithsh*:::command-return,
6567754Smsmithsh*:::subshell-entry,
6667754Smsmithsh*:::subshell-return
6767754Smsmith/self->last == 0/
6867754Smsmith{
6967754Smsmith	self->last = timestamp;
7067754Smsmith}
7167754Smsmith
7267754Smsmithsh*:::function-entry
7367754Smsmith{
7467754Smsmith	this->delta = (timestamp - self->last) / 1000;
7567754Smsmith	printf("%3d %6d %10d  %16s:%-4d %-8s %*s-> %s\n", cpu, pid,
7667754Smsmith	    this->delta, basename(copyinstr(arg0)), arg2, "func",
7767754Smsmith	    self->depth * 2, "", copyinstr(arg1));
7867754Smsmith	self->depth++;
7967754Smsmith	self->last = timestamp;
8067754Smsmith}
8167754Smsmith
8267754Smsmithsh*:::function-return
8367754Smsmith{
8467754Smsmith	this->delta = (timestamp - self->last) / 1000;
8567754Smsmith	self->depth -= self->depth > 0 ? 1 : 0;
8667754Smsmith	printf("%3d %6d %10d  %16s:-    %-8s %*s<- %s\n", cpu, pid,
8767754Smsmith	    this->delta, basename(copyinstr(arg0)), "func", self->depth * 2,
8867754Smsmith	    "", copyinstr(arg1));
8967754Smsmith	self->last = timestamp;
9067754Smsmith}
9167754Smsmith
9267754Smsmithsh*:::builtin-entry
9367754Smsmith{
9467754Smsmith	this->delta = (timestamp - self->last) / 1000;
9567754Smsmith	printf("%3d %6d %10d  %16s:%-4d %-8s %*s-> %s\n", cpu, pid,
9667754Smsmith	    this->delta, basename(copyinstr(arg0)), arg2, "builtin",
9767754Smsmith	    self->depth * 2, "", copyinstr(arg1));
9867754Smsmith	self->depth++;
9967754Smsmith	self->last = timestamp;
10067754Smsmith}
10167754Smsmith
10267754Smsmithsh*:::builtin-return
10367754Smsmith{
10467754Smsmith	this->delta = (timestamp - self->last) / 1000;
10567754Smsmith	self->depth -= self->depth > 0 ? 1 : 0;
10667754Smsmith	printf("%3d %6d %10d  %16s:-    %-8s %*s<- %s\n", cpu, pid,
10767754Smsmith	    this->delta, basename(copyinstr(arg0)), "builtin",
10867754Smsmith	    self->depth * 2, "", copyinstr(arg1));
10967754Smsmith	self->last = timestamp;
11067754Smsmith}
11167754Smsmith
11267754Smsmithsh*:::command-entry
11367754Smsmith{
11467754Smsmith	this->delta = (timestamp - self->last) / 1000;
11567754Smsmith	printf("%3d %6d %10d  %16s:%-4d %-8s %*s-> %s\n", cpu, pid,
11667754Smsmith	    this->delta, basename(copyinstr(arg0)), arg2, "cmd",
11767754Smsmith	    self->depth * 2, "", copyinstr(arg1));
11877424Smsmith	self->depth++;
11967754Smsmith	self->last = timestamp;
12067754Smsmith}
12167754Smsmith
12267754Smsmithsh*:::command-return
12367754Smsmith{
12467754Smsmith	this->delta = (timestamp - self->last) / 1000;
12577424Smsmith	self->depth -= self->depth > 0 ? 1 : 0;
12691116Smsmith	printf("%3d %6d %10d  %16s:-    %-8s %*s<- %s\n", cpu, pid,
12767754Smsmith	    this->delta, basename(copyinstr(arg0)), "cmd",
12867754Smsmith	    self->depth * 2, "", copyinstr(arg1));
12967754Smsmith	self->last = timestamp;
13067754Smsmith}
13177424Smsmith
13267754Smsmithsh*:::subshell-entry
13399146Siwasaki/arg1 != 0/
13499146Siwasaki{
13587031Smsmith	this->delta = (timestamp - self->last) / 1000;
13667754Smsmith	printf("%3d %6d %10d  %16s:-    %-8s %*s-> pid %d\n", cpu, pid,
13787031Smsmith	    this->delta, basename(copyinstr(arg0)), "subsh",
13867754Smsmith	    self->depth * 2, "", arg1);
13987031Smsmith	self->depth++;
14087031Smsmith	self->last = timestamp;
14167754Smsmith}
14267754Smsmith
14367754Smsmithsh*:::subshell-return
14467754Smsmith/self->last/
14577424Smsmith{
14699146Siwasaki	this->delta = (timestamp - self->last) / 1000;
14767754Smsmith	self->depth -= self->depth > 0 ? 1 : 0;
14877424Smsmith	printf("%3d %6d %10d  %16s:-    %-8s %*s<- = %d\n", cpu, pid,
14967754Smsmith	    this->delta, basename(copyinstr(arg0)), "subsh",
15077424Smsmith	    self->depth * 2, "", arg1);
15177424Smsmith	self->last = timestamp;
152114237Snjl}
15377424Smsmith