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