1#!/usr/sbin/dtrace -Zs 2/* 3 * sh_pidcolors.d - Demonstration of deeper DTrace Bourne shell analysis. 4 * Written for the sh DTrace provider. 5 * 6 * $Id: sh_pidcolors.d 27 2007-09-13 09:26:01Z brendan $ 7 * 8 * USAGE: sh_pidcolors.d { -p PID | -c cmd } # hit Ctrl-C to end 9 * 10 * This extends sh_syscolors.d by including some "pid" provider tracing 11 * as a starting point for deeper analysis. Currently it adds the probes, 12 * 13 * pid$target:a.out:e*:entry, 14 * pid$target:a.out:e*:return 15 * 16 * which means, all functions from the /usr/bin/sh binary that begin with 17 * the letter "e". This adds about 34 probes. Customise it to whichever 18 * parts of /usr/bin/sh or the system libraries you are interested in. 19 * 20 * FIELDS: 21 * C CPU-id 22 * PID Process ID 23 * DELTA(us) Elapsed time from previous line to this line 24 * FILE Filename of the shell script 25 * LINE Line number of filename 26 * TYPE Type of call (func/builtin/cmd/line/shell) 27 * NAME Shell function, builtin or command name 28 * 29 * The filename for syscalls may be printed as the shell name, if the 30 * script was invoked using the form "shell filename" rather than running 31 * the script with an interpreter line. 32 * 33 * WARNING: Watch the first column carefully, it prints the CPU-id. If it 34 * changes, then it is very likely that the output has been shuffled. 35 * 36 * COPYRIGHT: Copyright (c) 2007 Brendan Gregg. 37 * 38 * CDDL HEADER START 39 * 40 * The contents of this file are subject to the terms of the 41 * Common Development and Distribution License, Version 1.0 only 42 * (the "License"). You may not use this file except in compliance 43 * with the License. 44 * 45 * You can obtain a copy of the license at Docs/cddl1.txt 46 * or http://www.opensolaris.org/os/licensing. 47 * See the License for the specific language governing permissions 48 * and limitations under the License. 49 * 50 * CDDL HEADER END 51 * 52 * 09-Sep-2007 Brendan Gregg Created this. 53 */ 54 55#pragma D option quiet 56#pragma D option switchrate=10 57 58self int depth; 59 60dtrace:::BEGIN 61{ 62 color_shell = "\033[2;35m"; /* violet, faint */ 63 color_line = "\033[1;35m"; /* violet, bold */ 64 color_lib = "\033[2;34m"; /* blue, faint */ 65 color_syscall = "\033[2;32m"; /* green, faint */ 66 color_off = "\033[0m"; /* default */ 67 68 printf("%s %6s %10s %16s:%-4s %-8s -- %s\n", "C", "PID", "DELTA(us)", 69 "FILE", "LINE", "TYPE", "NAME"); 70} 71 72sh$target:::function-entry, 73sh$target:::function-return, 74sh$target:::builtin-entry, 75sh$target:::command-entry, 76syscall:::entry, 77syscall:::return, 78/* Customize Here, */ 79pid$target:a.out:e*:entry, 80pid$target:a.out:e*:return 81/self->last == 0 && pid == $target/ 82{ 83 self->last = timestamp; 84} 85 86sh$target:::function-entry 87{ 88 this->delta = (timestamp - self->last) / 1000; 89 printf("%s%d %6d %10d %16s:%-4d %-8s %*s-> %s%s\n", color_shell, 90 cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "func", 91 self->depth * 2, "", copyinstr(arg1), color_off); 92 self->depth++; 93 self->last = timestamp; 94} 95 96sh$target:::function-return 97{ 98 this->delta = (timestamp - self->last) / 1000; 99 self->depth -= self->depth > 0 ? 1 : 0; 100 printf("%s%d %6d %10d %16s:- %-8s %*s<- %s%s\n", color_shell, 101 cpu, pid, this->delta, basename(copyinstr(arg0)), "func", 102 self->depth * 2, "", copyinstr(arg1), color_off); 103 self->last = timestamp; 104} 105 106sh$target:::builtin-entry 107{ 108 this->delta = (timestamp - self->last) / 1000; 109 printf("%s%d %6d %10d %16s:%-4d %-8s %*s-> %s%s\n", color_shell, 110 cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "builtin", 111 self->depth * 2, "", copyinstr(arg1), color_off); 112 self->depth++; 113 self->last = timestamp; 114} 115 116sh$target:::builtin-return 117{ 118 this->delta = (timestamp - self->last) / 1000; 119 self->depth -= self->depth > 0 ? 1 : 0; 120 printf("%s%d %6d %10d %16s:%-4d %-8s %*s<- %s%s\n", color_shell, 121 cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "builtin", 122 self->depth * 2, "", copyinstr(arg1), color_off); 123 self->last = timestamp; 124} 125 126sh$target:::command-entry 127{ 128 this->delta = (timestamp - self->last) / 1000; 129 printf("%s%d %6d %10d %16s:%-4d %-8s %*s-> %s%s\n", color_shell, 130 cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "cmd", 131 self->depth * 2, "", copyinstr(arg1), color_off); 132 self->depth++; 133 self->last = timestamp; 134} 135 136sh$target:::command-return 137{ 138 this->delta = (timestamp - self->last) / 1000; 139 self->depth -= self->depth > 0 ? 1 : 0; 140 printf("%s%d %6d %10d %16s:%-4d %-8s %*s<- %s%s\n", color_shell, 141 cpu, pid, this->delta, basename(copyinstr(arg0)), arg2, "cmd", 142 self->depth * 2, "", copyinstr(arg1), color_off); 143 self->last = timestamp; 144} 145 146sh$target:::line 147{ 148 this->delta = (timestamp - self->last) / 1000; 149 printf("%s%d %6d %10d %16s:%-4d %-8s %*s-- %s\n", color_line, 150 cpu, pid, this->delta, basename(copyinstr(arg0)), arg1, "line", 151 self->depth * 2, "", color_off); 152 self->last = timestamp; 153} 154 155/* Customise Here, */ 156pid$target:a.out:e*:entry 157{ 158 this->delta = (timestamp - self->last) / 1000; 159 printf("%s%d %6d %10d %16s:- %-8s %*s-> %s%s\n", color_lib, 160 cpu, pid, this->delta, basename(execname), "sh", 161 self->depth * 2, "", probefunc, color_off); 162 self->depth++; 163 self->last = timestamp; 164} 165 166/* Customise Here, */ 167pid$target:a.out:e*:return 168{ 169 this->delta = (timestamp - self->last) / 1000; 170 self->depth -= self->depth > 0 ? 1 : 0; 171 printf("%s%d %6d %10d %16s:- %-8s %*s<- %s%s\n", color_lib, 172 cpu, pid, this->delta, basename(execname), "sh", 173 self->depth * 2, "", probefunc, color_off); 174 self->last = timestamp; 175} 176 177syscall:::entry 178/pid == $target/ 179{ 180 this->delta = (timestamp - self->last) / 1000; 181 printf("%s%d %6d %10d %16s:- %-8s %*s-> %s%s\n", color_syscall, 182 cpu, pid, this->delta, basename(execname), "syscall", 183 self->depth * 2, "", probefunc, color_off); 184 self->depth++; 185 self->last = timestamp; 186} 187 188syscall:::return 189/pid == $target/ 190{ 191 this->delta = (timestamp - self->last) / 1000; 192 self->depth -= self->depth > 0 ? 1 : 0; 193 printf("%s%d %6d %10d %16s:- %-8s %*s<- %s%s\n", color_syscall, 194 cpu, pid, this->delta, basename(execname), "syscall", 195 self->depth * 2, "", probefunc, color_off); 196 self->last = timestamp; 197} 198 199proc:::exit 200/pid == $target/ 201{ 202 exit(0); 203} 204