]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - cddl/contrib/dtracetoolkit/errinfo
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / cddl / contrib / dtracetoolkit / errinfo
1 #!/usr/bin/perl
2 #
3 # errinfo - report on syscall failures and print errno error messages.
4 #           Written using Perl and DTrace (Solaris 10 03/05)
5 #
6 # When system calls fail, an errno variable is set to convay a meaningful
7 # message to the end user - so long as the program does something with it
8 # (eg, "ls" printing "No such file or directory"). This program fetches
9 # and prints details for all syscall failures along with their message,
10 # whether the failing program is already printing this info or not.
11 #
12 # $Id: errinfo 3 2007-08-01 10:50:08Z brendan $
13 #
14 # USAGE:        errinfo [-ch] [-p PID] [-n name]
15 #
16 #               -c              # counts - aggregate style
17 #               -p PID          # examine this PID only
18 #               -n name         # examine processes with this name only
19 #       eg,
20 #               errinfo                 # default output - snoop event style
21 #               errinfo -n ssh          # examine "ssh" processes only
22 #               errinfo -cn ssh         # examine "ssh" using counts
23 #
24 # FIELDS:
25 #               EXEC            Program name (truncated)
26 #               SYSCALL         System call name
27 #               ERR             Value of errno
28 #               DESC            Description of errno message
29 #
30 # SEE ALSO:     /usr/include/sys/errno.h
31 #
32 # COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
33 #
34 # CDDL HEADER START
35 #
36 #  The contents of this file are subject to the terms of the
37 #  Common Development and Distribution License, Version 1.0 only
38 #  (the "License").  You may not use this file except in compliance
39 #  with the License.
40 #
41 #  You can obtain a copy of the license at Docs/cddl1.txt
42 #  or http://www.opensolaris.org/os/licensing.
43 #  See the License for the specific language governing permissions
44 #  and limitations under the License.
45 #
46 # CDDL HEADER END
47 #
48 # Author: Brendan Gregg  [Sydney, Australia]
49 #
50 # 18-Apr-2005   Brendan Gregg   Created this.
51 # 20-Apr-2006      "      "     Last update.
52 #
53
54 use Getopt::Std;
55
56 #
57 #  Defaults
58 #
59 $FILTER = "";
60 $COUNT = 0;
61
62 #
63 #  Command line arguments
64 #
65 &Usage() if $ARGV[0] eq "--help";
66 getopts('ch:n:p:') || &Usage();
67 &Usage() if $opt_h;
68 $COUNT = 1 if $opt_c;
69 $FILTER = "&& execname == \"$opt_n\"" if defined $opt_n;
70 $FILTER = "&& pid == $opt_p" if defined $opt_p;
71
72 #
73 #  Load errno descriptions
74 #
75 open(ERRNO,"/usr/include/sys/errno.h") || die "ERROR1: reading errno.h: $!\n";
76 while (chomp($line = <ERRNO>)) {
77         next unless $line =~ /^#define/;
78         ($errno,$desc) = $line =~ /^#define\s+\S+\s+(\d+)\s+\/\*(.*)\*\//;
79         $Errno{$errno} = $desc;
80 }
81 close ERRNO;
82
83 #
84 #  Declare DTrace script
85 #
86  if ($COUNT) {          # aggregate style
87 $dtrace = <<END;
88 /usr/sbin/dtrace -n '
89         #pragma D option quiet
90         syscall:::return 
91         /errno != 0 && pid != \$pid $FILTER/ 
92         { 
93                 \@Errs[execname, probefunc, errno] = count(); 
94         }
95         dtrace:::END {
96                 printa("%s %s %d %\@d\\n", \@Errs);
97         }'
98 END
99  } else {               # snoop style
100 $dtrace = <<END; 
101 /usr/sbin/dtrace -n '
102         #pragma D option quiet
103         #pragma D option switchrate=5hz
104         syscall:::return 
105         /errno != 0 && pid != \$pid $FILTER/ 
106         { 
107                 printf("%s %s %d\\n", execname, probefunc, errno); 
108         }'
109 END
110  }
111
112 #
113 #  Cleanup on signals
114 #
115 $SIG{INT} = \&Cleanup_Signal;    # Ctrl-C
116 $SIG{QUIT} = \&Cleanup_Signal;   # Ctrl-\
117 $SIG{TERM} = \&Cleanup_Signal;   # TERM
118
119 #
120 #  Run DTrace, process output
121 #
122
123 if ($COUNT) {
124         print STDERR "Tracing... Hit Ctrl-C to end.\n";
125         $header = 1;
126 } else {
127         printf("%16s %16s %4s  %s\n","EXEC","SYSCALL","ERR","DESC");
128 }
129
130 ### Open DTrace
131 open(DTRACE,"$dtrace |") || die "ERROR2: Can't start dtrace (perms?): $!\n";
132
133 ### Process DTrace output
134 while (chomp($line = <DTRACE>)) {
135
136         ### Print count header
137         if ($COUNT && $header) {
138                 printf("\n%16s %16s %4s %6s  %s\n",
139                  "EXEC","SYSCALL","ERR","COUNT","DESC");
140                 $header = 0;
141         }
142
143         ### Split data
144         ($execname,$syscall,$errno,$counts) = split(' ',$line);
145         next if $errno eq "";
146
147         ### Fetch errno description
148         $desc = $Errno{$errno};
149
150         ### Print output line
151         if ($COUNT) {
152                 printf("%16s %16s %4d %6d %s\n",
153                  $execname,$syscall,$errno,$counts,$desc);
154         } else {
155                 printf("%16s %16s %4d %s\n",$execname,$syscall,$errno,$desc);
156         }
157 }
158 close(DTRACE);
159
160 #
161 #  Triggered by signals
162 #
163 sub Cleanup_Signal {
164 }
165
166 #
167 #  Usage message
168 #
169 sub Usage {
170         print STDERR "USAGE: errinfo [-ch] [-p PID] [-n name]\n";
171         print STDERR <<ENDUSAGE;
172      eg,
173        errinfo       # default output - snoop event style
174           -c         # counts - aggregate style
175           -p 871     # examine PID 871 only
176           -n ssh     # examine processes with the name "ssh" only
177           -cn ssh    # examine "ssh" using counts
178 ENDUSAGE
179         exit(1);
180 }