xref: /freebsd/usr.sbin/crashinfo/crashinfo.sh (revision aa0a1e58)
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 `sysctl -n kern.bootfile` $(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
150umask 077
151
152# Simulate uname
153ostype=$(echo -e printf '"%s", ostype' | gdb -x /dev/stdin -batch $KERNEL)
154osrelease=$(echo -e printf '"%s", osrelease' | gdb -x /dev/stdin -batch $KERNEL)
155version=$(echo -e printf '"%s", version' | gdb -x /dev/stdin -batch $KERNEL | \
156    tr '\t\n' '  ')
157machine=$(echo -e printf '"%s", machine' | gdb -x /dev/stdin -batch $KERNEL)
158
159exec > $FILE 2>&1
160
161echo "$HOSTNAME dumped core - see $VMCORE"
162echo
163date
164echo
165echo "$ostype $HOSTNAME $osrelease $version $machine"
166echo
167sed -ne '/^  Panic String: /{s//panic: /;p;}' $INFO
168echo
169
170# XXX: /bin/sh on 7.0+ is broken so we can't simply pipe the commands to
171# kgdb via stdin and have to use a temporary file instead.
172file=`mktemp /tmp/crashinfo.XXXXXX`
173if [ $? -eq 0 ]; then
174	echo "bt" >> $file
175	echo "quit" >> $file
176	kgdb $KERNEL $VMCORE < $file
177	rm -f $file
178	echo
179fi
180echo
181
182echo "------------------------------------------------------------------------"
183echo "ps -axl"
184echo
185ps -M $VMCORE -N $KERNEL -axl
186echo
187
188echo "------------------------------------------------------------------------"
189echo "vmstat -s"
190echo
191vmstat -M $VMCORE -N $KERNEL -s
192echo
193
194echo "------------------------------------------------------------------------"
195echo "vmstat -m"
196echo
197vmstat -M $VMCORE -N $KERNEL -m
198echo
199
200echo "------------------------------------------------------------------------"
201echo "vmstat -z"
202echo
203vmstat -M $VMCORE -N $KERNEL -z
204echo
205
206echo "------------------------------------------------------------------------"
207echo "vmstat -i"
208echo
209vmstat -M $VMCORE -N $KERNEL -i
210echo
211
212echo "------------------------------------------------------------------------"
213echo "pstat -T"
214echo
215pstat -M $VMCORE -N $KERNEL -T
216echo
217
218echo "------------------------------------------------------------------------"
219echo "pstat -s"
220echo
221pstat -M $VMCORE -N $KERNEL -s
222echo
223
224echo "------------------------------------------------------------------------"
225echo "iostat"
226echo
227iostat -M $VMCORE -N $KERNEL
228echo
229
230echo "------------------------------------------------------------------------"
231echo "ipcs -a"
232echo
233ipcs -C $VMCORE -N $KERNEL -a
234echo
235
236echo "------------------------------------------------------------------------"
237echo "ipcs -T"
238echo
239ipcs -C $VMCORE -N $KERNEL -T
240echo
241
242# XXX: This doesn't actually work in 5.x+
243if false; then
244echo "------------------------------------------------------------------------"
245echo "w -dn"
246echo
247w -M $VMCORE -N $KERNEL -dn
248echo
249fi
250
251echo "------------------------------------------------------------------------"
252echo "nfsstat"
253echo
254nfsstat -M $VMCORE -N $KERNEL
255echo
256
257echo "------------------------------------------------------------------------"
258echo "netstat -s"
259echo
260netstat -M $VMCORE -N $KERNEL -s
261echo
262
263echo "------------------------------------------------------------------------"
264echo "netstat -m"
265echo
266netstat -M $VMCORE -N $KERNEL -m
267echo
268
269echo "------------------------------------------------------------------------"
270echo "netstat -id"
271echo
272netstat -M $VMCORE -N $KERNEL -id
273echo
274
275echo "------------------------------------------------------------------------"
276echo "netstat -anr"
277echo
278netstat -M $VMCORE -N $KERNEL -anr
279echo
280
281echo "------------------------------------------------------------------------"
282echo "netstat -anA"
283echo
284netstat -M $VMCORE -N $KERNEL -anA
285echo
286
287echo "------------------------------------------------------------------------"
288echo "netstat -aL"
289echo
290netstat -M $VMCORE -N $KERNEL -aL
291echo
292
293echo "------------------------------------------------------------------------"
294echo "fstat"
295echo
296fstat -M $VMCORE -N $KERNEL
297echo
298
299echo "------------------------------------------------------------------------"
300echo "dmesg"
301echo
302dmesg -a -M $VMCORE -N $KERNEL
303echo
304
305echo "------------------------------------------------------------------------"
306echo "kernel config"
307echo
308config -x $KERNEL
309
310echo
311echo "------------------------------------------------------------------------"
312echo "ddb capture buffer"
313echo
314
315ddb capture -M $VMCORE -N $KERNEL print
316