xref: /netbsd-src/external/cddl/dtracetoolkit/dist/Shell/sh_flowinfo.d (revision c29d51755812ace2e87aeefdb06cb2b4dac7087a)
1 #!/usr/sbin/dtrace -Zs
2 /*
3  * sh_flowinfo.d - snoop Bourne shell flow with additional info.
4  *                 Written for the sh DTrace provider.
5  *
6  * $Id: sh_flowinfo.d,v 1.1.1.1 2015/09/30 22:01:09 christos Exp $
7  *
8  * This traces shell activity from all Bourne shells on the system that are
9  * running with sh provider support.
10  *
11  * USAGE: sh_flowinfo.d			# hit Ctrl-C to end
12  *
13  * This watches shell function entries and returns, and indents child
14  * function calls. Shell builtins and external commands are also printed.
15  *
16  * FIELDS:
17  *		C		CPU-id
18  *		PID		Process ID
19  *		DELTA(us)	Elapsed time from previous line to this line
20  *		FILE		Filename of the shell script
21  *		LINE		Line number of filename
22  *		TYPE		Type of call (func/builtin/cmd/subsh)
23  *		NAME		Shell function, builtin or command name
24  *
25  * WARNING: Watch the first column carefully, it prints the CPU-id. If it
26  * changes, then it is very likely that the output has been shuffled.
27  *
28  * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
29  *
30  * CDDL HEADER START
31  *
32  *  The contents of this file are subject to the terms of the
33  *  Common Development and Distribution License, Version 1.0 only
34  *  (the "License").  You may not use this file except in compliance
35  *  with the License.
36  *
37  *  You can obtain a copy of the license at Docs/cddl1.txt
38  *  or http://www.opensolaris.org/os/licensing.
39  *  See the License for the specific language governing permissions
40  *  and limitations under the License.
41  *
42  * CDDL HEADER END
43  *
44  * 09-Sep-2007	Brendan Gregg	Created this.
45  */
46 
47 #pragma D option quiet
48 #pragma D option switchrate=10
49 
50 self int depth;
51 
52 dtrace:::BEGIN
53 {
54 	self->depth = 0;
55 	printf("%3s %6s %10s  %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)",
56 	    "FILE", "LINE", "TYPE", "NAME");
57 }
58 
59 sh*:::function-entry,
60 sh*:::function-return,
61 sh*:::builtin-entry,
62 sh*:::builtin-return,
63 sh*:::command-entry,
64 sh*:::command-return,
65 sh*:::subshell-entry,
66 sh*:::subshell-return
67 /self->last == 0/
68 {
69 	self->last = timestamp;
70 }
71 
72 sh*:::function-entry
73 {
74 	this->delta = (timestamp - self->last) / 1000;
75 	printf("%3d %6d %10d  %16s:%-4d %-8s %*s-> %s\n", cpu, pid,
76 	    this->delta, basename(copyinstr(arg0)), arg2, "func",
77 	    self->depth * 2, "", copyinstr(arg1));
78 	self->depth++;
79 	self->last = timestamp;
80 }
81 
82 sh*:::function-return
83 {
84 	this->delta = (timestamp - self->last) / 1000;
85 	self->depth -= self->depth > 0 ? 1 : 0;
86 	printf("%3d %6d %10d  %16s:-    %-8s %*s<- %s\n", cpu, pid,
87 	    this->delta, basename(copyinstr(arg0)), "func", self->depth * 2,
88 	    "", copyinstr(arg1));
89 	self->last = timestamp;
90 }
91 
92 sh*:::builtin-entry
93 {
94 	this->delta = (timestamp - self->last) / 1000;
95 	printf("%3d %6d %10d  %16s:%-4d %-8s %*s-> %s\n", cpu, pid,
96 	    this->delta, basename(copyinstr(arg0)), arg2, "builtin",
97 	    self->depth * 2, "", copyinstr(arg1));
98 	self->depth++;
99 	self->last = timestamp;
100 }
101 
102 sh*:::builtin-return
103 {
104 	this->delta = (timestamp - self->last) / 1000;
105 	self->depth -= self->depth > 0 ? 1 : 0;
106 	printf("%3d %6d %10d  %16s:-    %-8s %*s<- %s\n", cpu, pid,
107 	    this->delta, basename(copyinstr(arg0)), "builtin",
108 	    self->depth * 2, "", copyinstr(arg1));
109 	self->last = timestamp;
110 }
111 
112 sh*:::command-entry
113 {
114 	this->delta = (timestamp - self->last) / 1000;
115 	printf("%3d %6d %10d  %16s:%-4d %-8s %*s-> %s\n", cpu, pid,
116 	    this->delta, basename(copyinstr(arg0)), arg2, "cmd",
117 	    self->depth * 2, "", copyinstr(arg1));
118 	self->depth++;
119 	self->last = timestamp;
120 }
121 
122 sh*:::command-return
123 {
124 	this->delta = (timestamp - self->last) / 1000;
125 	self->depth -= self->depth > 0 ? 1 : 0;
126 	printf("%3d %6d %10d  %16s:-    %-8s %*s<- %s\n", cpu, pid,
127 	    this->delta, basename(copyinstr(arg0)), "cmd",
128 	    self->depth * 2, "", copyinstr(arg1));
129 	self->last = timestamp;
130 }
131 
132 sh*:::subshell-entry
133 /arg1 != 0/
134 {
135 	this->delta = (timestamp - self->last) / 1000;
136 	printf("%3d %6d %10d  %16s:-    %-8s %*s-> pid %d\n", cpu, pid,
137 	    this->delta, basename(copyinstr(arg0)), "subsh",
138 	    self->depth * 2, "", arg1);
139 	self->depth++;
140 	self->last = timestamp;
141 }
142 
143 sh*:::subshell-return
144 /self->last/
145 {
146 	this->delta = (timestamp - self->last) / 1000;
147 	self->depth -= self->depth > 0 ? 1 : 0;
148 	printf("%3d %6d %10d  %16s:-    %-8s %*s<- = %d\n", cpu, pid,
149 	    this->delta, basename(copyinstr(arg0)), "subsh",
150 	    self->depth * 2, "", arg1);
151 	self->last = timestamp;
152 }
153