xref: /freebsd/usr.sbin/crashinfo/crashinfo.sh (revision 6356dba0b403daa023dec24559ab1f8e602e4f14)
1#!/bin/sh
2#
3# Copyright (c) 2008 Yahoo!, Inc.
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14# 3. Neither the name of the author nor the names of any co-contributors
15#    may be used to endorse or promote products derived from this software
16#    without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28# SUCH DAMAGE.
29#
30# $FreeBSD$
31
32usage()
33{
34	echo "usage: crashinfo [-d crashdir] [-n dumpnr] [-k kernel] [core]"
35	exit 1
36}
37
38find_kernel()
39{
40	local ivers k kvers
41
42	ivers=$(awk '
43	/Version String/ {
44		print
45		nextline=1
46		next
47	}
48	// {
49		if (nextline) {
50			print
51			nextline=0
52		}
53	}' $INFO)
54
55	# Look for a matching kernel version.
56	for k in /boot/kernel/kernel $(ls -t /boot/*/kernel); do
57		kvers=$(echo 'printf "  Version String: %s", version' | \
58		    gdb -x /dev/stdin -batch $k 2>/dev/null)
59		if [ "$ivers" = "$kvers" ]; then
60			KERNEL=$k
61			break
62		fi
63	done
64}
65
66CRASHDIR=/var/crash
67DUMPNR=
68KERNEL=
69
70while getopts "d:n:k:" opt; do
71	case "$opt" in
72	d)
73		CRASHDIR=$OPTARG
74		;;
75	n)
76		DUMPNR=$OPTARG
77		;;
78	k)
79		KERNEL=$OPTARG
80		;;
81	\?)
82		usage
83		;;
84	esac
85done
86
87shift $((OPTIND - 1))
88
89if [ $# -eq 1 ]; then
90	if [ -n "$DUMPNR" ]; then
91		echo "-n and an explicit vmcore are mutually exclusive"
92		usage
93	fi
94
95	# Figure out the crash directory and number from the vmcore name.
96	CRASHDIR=`dirname $1`
97	DUMPNR=$(expr $(basename $1) : 'vmcore\.\([0-9]*\)$')
98	if [ -z "$DUMPNR" ]; then
99		echo "Unable to determine dump number from vmcore file $1."
100		exit 1
101	fi
102elif [ $# -gt 1 ]; then
103	usage
104else
105	# If we don't have an explicit dump number, operate on the most
106	# recent dump.
107	if [ -z "$DUMPNR" ]; then
108		if ! [ -r $CRASHDIR/bounds ]; then
109			echo "No crash dumps in $CRASHDIR."
110			exit 1
111		fi
112		next=`cat $CRASHDIR/bounds`
113		if [ -z "$next" ] || [ "$next" -eq 0 ]; then
114			echo "No crash dumps in $CRASHDIR."
115			exit 1
116		fi
117		DUMPNR=$(($next - 1))
118	fi
119fi
120
121VMCORE=$CRASHDIR/vmcore.$DUMPNR
122INFO=$CRASHDIR/info.$DUMPNR
123FILE=$CRASHDIR/core.txt.$DUMPNR
124HOSTNAME=`hostname`
125
126if [ ! -e $VMCORE ]; then
127	echo "$VMCORE not found"
128	exit 1
129fi
130
131if [ ! -e $INFO ]; then
132	echo "$INFO not found"
133	exit 1
134fi
135
136# If the user didn't specify a kernel, then try to find one.
137if [ -z "$KERNEL" ]; then
138	find_kernel
139	if [ -z "$KERNEL" ]; then
140		echo "Unable to find matching kernel for $VMCORE"
141		exit 1
142	fi
143elif [ ! -e $KERNEL ]; then
144	echo "$KERNEL not found"
145	exit 1
146fi
147
148echo "Writing crash summary to $FILE."
149
150# Simulate uname
151ostype=$(echo -e printf '"%s", ostype' | gdb -x /dev/stdin -batch $KERNEL)
152osrelease=$(echo -e printf '"%s", osrelease' | gdb -x /dev/stdin -batch $KERNEL)
153version=$(echo -e printf '"%s", version' | gdb -x /dev/stdin -batch $KERNEL | \
154    tr '\t\n' '  ')
155machine=$(echo -e printf '"%s", machine' | gdb -x /dev/stdin -batch $KERNEL)
156
157exec > $FILE 2>&1
158
159echo "$HOSTNAME dumped core - see $VMCORE"
160echo
161date
162echo
163echo "$ostype $HOSTNAME $osrelease $version $machine"
164echo
165sed -ne '/^  Panic String: /{s//panic: /;p;}' $INFO
166echo
167
168# XXX: /bin/sh on 7.0+ is broken so we can't simply pipe the commands to
169# kgdb via stdin and have to use a temporary file instead.
170file=`mktemp /tmp/crashinfo.XXXXXX`
171if [ $? -eq 0 ]; then
172	echo "bt" >> $file
173	echo "quit" >> $file
174	kgdb $KERNEL $VMCORE < $file
175	rm -f $file
176	echo
177fi
178echo
179
180echo "------------------------------------------------------------------------"
181echo "ps -axl"
182echo
183ps -M $VMCORE -N $KERNEL -axl
184echo
185
186echo "------------------------------------------------------------------------"
187echo "vmstat -s"
188echo
189vmstat -M $VMCORE -N $KERNEL -s
190echo
191
192echo "------------------------------------------------------------------------"
193echo "vmstat -m"
194echo
195vmstat -M $VMCORE -N $KERNEL -m
196echo
197
198echo "------------------------------------------------------------------------"
199echo "vmstat -z"
200echo
201vmstat -M $VMCORE -N $KERNEL -z
202echo
203
204echo "------------------------------------------------------------------------"
205echo "vmstat -i"
206echo
207vmstat -M $VMCORE -N $KERNEL -i
208echo
209
210echo "------------------------------------------------------------------------"
211echo "pstat -T"
212echo
213pstat -M $VMCORE -N $KERNEL -T
214echo
215
216echo "------------------------------------------------------------------------"
217echo "pstat -s"
218echo
219pstat -M $VMCORE -N $KERNEL -s
220echo
221
222echo "------------------------------------------------------------------------"
223echo "iostat"
224echo
225iostat -M $VMCORE -N $KERNEL
226echo
227
228echo "------------------------------------------------------------------------"
229echo "ipcs -a"
230echo
231ipcs -C $VMCORE -N $KERNEL -a
232echo
233
234echo "------------------------------------------------------------------------"
235echo "ipcs -T"
236echo
237ipcs -C $VMCORE -N $KERNEL -T
238echo
239
240# XXX: This doesn't actually work in 5.x+
241if false; then
242echo "------------------------------------------------------------------------"
243echo "w -dn"
244echo
245w -M $VMCORE -N $KERNEL -dn
246echo
247fi
248
249echo "------------------------------------------------------------------------"
250echo "nfsstat"
251echo
252nfsstat -M $VMCORE -N $KERNEL
253echo
254
255echo "------------------------------------------------------------------------"
256echo "netstat -s"
257echo
258netstat -M $VMCORE -N $KERNEL -s
259echo
260
261echo "------------------------------------------------------------------------"
262echo "netstat -m"
263echo
264netstat -M $VMCORE -N $KERNEL -m
265echo
266
267echo "------------------------------------------------------------------------"
268echo "netstat -id"
269echo
270netstat -M $VMCORE -N $KERNEL -id
271echo
272
273echo "------------------------------------------------------------------------"
274echo "netstat -anr"
275echo
276netstat -M $VMCORE -N $KERNEL -anr
277echo
278
279echo "------------------------------------------------------------------------"
280echo "netstat -anA"
281echo
282netstat -M $VMCORE -N $KERNEL -anA
283echo
284
285echo "------------------------------------------------------------------------"
286echo "netstat -aL"
287echo
288netstat -M $VMCORE -N $KERNEL -aL
289echo
290
291echo "------------------------------------------------------------------------"
292echo "fstat"
293echo
294fstat -M $VMCORE -N $KERNEL
295echo
296
297echo "------------------------------------------------------------------------"
298echo "dmesg"
299echo
300dmesg -a -M $VMCORE -N $KERNEL
301echo
302
303echo "------------------------------------------------------------------------"
304echo "kernel config"
305echo
306config -x $KERNEL
307