xref: /netbsd-src/external/cddl/dtracetoolkit/dist/Shell/sh_wasted.d (revision c29d51755812ace2e87aeefdb06cb2b4dac7087a)
1 #!/usr/sbin/dtrace -Zs
2 /*
3  * sh_wasted.d - measure Bourne shell elapsed times for "wasted" commands.
4  *               Written for the sh DTrace provider.
5  *
6  * $Id: sh_wasted.d,v 1.1.1.1 2015/09/30 22:01:09 christos Exp $
7  *
8  * USAGE: sh_wasted.d { -p PID | -c cmd }	# hit Ctrl-C to end
9  *
10  * This script measures "wasted" commands - those which are called externally
11  * but are in fact builtins to the shell. Ever seen a script which calls
12  * /usr/bin/echo needlessly? This script measures that cost.
13  *
14  * FIELDS:
15  *		FILE		Filename of the shell or shellscript
16  *		NAME		Name of call
17  *		TIME		Total elapsed time for calls (us)
18  *
19  * IDEA: Mike Shapiro
20  *
21  * Filename and call names are printed if available.
22  *
23  * COPYRIGHT: Copyright (c) 2007 Brendan Gregg.
24  *
25  * CDDL HEADER START
26  *
27  *  The contents of this file are subject to the terms of the
28  *  Common Development and Distribution License, Version 1.0 only
29  *  (the "License").  You may not use this file except in compliance
30  *  with the License.
31  *
32  *  You can obtain a copy of the license at Docs/cddl1.txt
33  *  or http://www.opensolaris.org/os/licensing.
34  *  See the License for the specific language governing permissions
35  *  and limitations under the License.
36  *
37  * CDDL HEADER END
38  *
39  * 09-Sep-2007	Brendan Gregg	Created this.
40  */
41 
42 #pragma D option quiet
43 
44 dtrace:::BEGIN
45 {
46 	isbuiltin["echo"] = 1;
47 	isbuiltin["test"] = 1;
48 	/* add builtins here */
49 
50 	printf("Tracing... Hit Ctrl-C to end.\n");
51 	self->start = timestamp;
52 }
53 
54 sh$target:::command-entry
55 {
56 	self->command = timestamp;
57 }
58 
59 sh$target:::command-return
60 {
61 	this->elapsed = timestamp - self->command;
62 	this->path = copyinstr(arg1);
63 	this->cmd = basename(this->path);
64 }
65 
66 sh$target:::command-return
67 /self->command && !isbuiltin[this->cmd]/
68 {
69 	@types_cmd[basename(copyinstr(arg0)), this->path] = sum(this->elapsed);
70 	self->command = 0;
71 }
72 
73 sh$target:::command-return
74 /self->command/
75 {
76 	@types_wasted[basename(copyinstr(arg0)), this->path] =
77 	    sum(this->elapsed);
78 	self->command = 0;
79 }
80 
81 proc:::exit
82 /pid == $target/
83 {
84 	exit(0);
85 }
86 
87 dtrace:::END
88 {
89 	this->elapsed = (timestamp - self->start) / 1000;
90 	printf("Script duration: %d us\n", this->elapsed);
91 
92 	normalize(@types_cmd, 1000);
93 	printf("\nExternal command elapsed times,\n");
94 	printf("   %-30s %-22s %8s\n", "FILE", "NAME", "TIME(us)");
95 	printa("   %-30s %-22s %@8d\n", @types_cmd);
96 
97 	normalize(@types_wasted, 1000);
98 	printf("\nWasted command elapsed times,\n");
99 	printf("   %-30s %-22s %8s\n", "FILE", "NAME", "TIME(us)");
100 	printa("   %-30s %-22s %@8d\n", @types_wasted);
101 }
102