1181335Sjhb#!/bin/sh
2181335Sjhb#
3181335Sjhb# Copyright (c) 2008 Yahoo!, Inc.
4181335Sjhb# All rights reserved.
5181335Sjhb#
6181335Sjhb# Redistribution and use in source and binary forms, with or without
7181335Sjhb# modification, are permitted provided that the following conditions
8181335Sjhb# are met:
9181335Sjhb# 1. Redistributions of source code must retain the above copyright
10181335Sjhb#    notice, this list of conditions and the following disclaimer.
11181335Sjhb# 2. Redistributions in binary form must reproduce the above copyright
12181335Sjhb#    notice, this list of conditions and the following disclaimer in the
13181335Sjhb#    documentation and/or other materials provided with the distribution.
14181335Sjhb# 3. Neither the name of the author nor the names of any co-contributors
15181335Sjhb#    may be used to endorse or promote products derived from this software
16181335Sjhb#    without specific prior written permission.
17181335Sjhb#
18181335Sjhb# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19181335Sjhb# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20181335Sjhb# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21181335Sjhb# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22181335Sjhb# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23181335Sjhb# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24181335Sjhb# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25181335Sjhb# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26181335Sjhb# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27181335Sjhb# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28181335Sjhb# SUCH DAMAGE.
29181335Sjhb#
30181335Sjhb# $FreeBSD$
31181335Sjhb
32181335Sjhbusage()
33181335Sjhb{
34181335Sjhb	echo "usage: crashinfo [-d crashdir] [-n dumpnr] [-k kernel] [core]"
35181335Sjhb	exit 1
36181335Sjhb}
37181335Sjhb
38303403Sjhb# Run a single gdb command against a kernel file in batch mode.
39303403Sjhb# The kernel file is specified as the first argument and the command
40303403Sjhb# is given in the remaining arguments.
41303403Sjhbgdb_command()
42303403Sjhb{
43303403Sjhb	local k
44303403Sjhb
45303403Sjhb	k=$1 ; shift
46303403Sjhb
47303403Sjhb	if [ -x /usr/local/bin/gdb ]; then
48303403Sjhb		/usr/local/bin/gdb -batch -ex "$@" $k
49303403Sjhb	else
50303403Sjhb		echo -e "$@" | /usr/bin/gdb -x /dev/stdin -batch $k
51303403Sjhb	fi
52303403Sjhb}
53303403Sjhb
54181335Sjhbfind_kernel()
55181335Sjhb{
56181335Sjhb	local ivers k kvers
57181335Sjhb
58181335Sjhb	ivers=$(awk '
59181335Sjhb	/Version String/ {
60181335Sjhb		print
61181335Sjhb		nextline=1
62181335Sjhb		next
63181335Sjhb	}
64232666Semaste	nextline==1 {
65232666Semaste		if ($0 ~ "^  [A-Za-z ]+: ") {
66232666Semaste			nextline=0
67232666Semaste		} else {
68181335Sjhb			print
69181335Sjhb		}
70181335Sjhb	}' $INFO)
71181335Sjhb
72181335Sjhb	# Look for a matching kernel version.
73216077Scperciva	for k in `sysctl -n kern.bootfile` $(ls -t /boot/*/kernel); do
74303403Sjhb		kvers=$(gdb_command $k 'printf "  Version String: %s", version' \
75303403Sjhb		     2>/dev/null)
76181335Sjhb		if [ "$ivers" = "$kvers" ]; then
77181335Sjhb			KERNEL=$k
78181335Sjhb			break
79181335Sjhb		fi
80181335Sjhb	done
81181335Sjhb}
82181335Sjhb
83181335SjhbCRASHDIR=/var/crash
84181335SjhbDUMPNR=
85181335SjhbKERNEL=
86181335Sjhb
87181335Sjhbwhile getopts "d:n:k:" opt; do
88181335Sjhb	case "$opt" in
89181335Sjhb	d)
90181335Sjhb		CRASHDIR=$OPTARG
91181335Sjhb		;;
92181335Sjhb	n)
93181335Sjhb		DUMPNR=$OPTARG
94181335Sjhb		;;
95181335Sjhb	k)
96181335Sjhb		KERNEL=$OPTARG
97181335Sjhb		;;
98181335Sjhb	\?)
99181335Sjhb		usage
100181335Sjhb		;;
101181335Sjhb	esac
102181335Sjhbdone
103181335Sjhb
104181335Sjhbshift $((OPTIND - 1))
105181335Sjhb
106181335Sjhbif [ $# -eq 1 ]; then
107181335Sjhb	if [ -n "$DUMPNR" ]; then
108181335Sjhb		echo "-n and an explicit vmcore are mutually exclusive"
109181335Sjhb		usage
110181335Sjhb	fi
111181335Sjhb
112181335Sjhb	# Figure out the crash directory and number from the vmcore name.
113181335Sjhb	CRASHDIR=`dirname $1`
114181335Sjhb	DUMPNR=$(expr $(basename $1) : 'vmcore\.\([0-9]*\)$')
115181335Sjhb	if [ -z "$DUMPNR" ]; then
116181335Sjhb		echo "Unable to determine dump number from vmcore file $1."
117181335Sjhb		exit 1
118181335Sjhb	fi
119181335Sjhbelif [ $# -gt 1 ]; then
120181335Sjhb	usage
121181335Sjhbelse
122181335Sjhb	# If we don't have an explicit dump number, operate on the most
123181335Sjhb	# recent dump.
124181335Sjhb	if [ -z "$DUMPNR" ]; then
125181335Sjhb		if ! [ -r $CRASHDIR/bounds ]; then
126181335Sjhb			echo "No crash dumps in $CRASHDIR."
127181335Sjhb			exit 1
128181335Sjhb		fi			
129181335Sjhb		next=`cat $CRASHDIR/bounds`
130181335Sjhb		if [ -z "$next" ] || [ "$next" -eq 0 ]; then
131181335Sjhb			echo "No crash dumps in $CRASHDIR."
132181335Sjhb			exit 1
133181335Sjhb		fi
134181335Sjhb		DUMPNR=$(($next - 1))
135181335Sjhb	fi
136181335Sjhbfi
137181335Sjhb
138181335SjhbVMCORE=$CRASHDIR/vmcore.$DUMPNR
139181335SjhbINFO=$CRASHDIR/info.$DUMPNR
140181335SjhbFILE=$CRASHDIR/core.txt.$DUMPNR
141181335SjhbHOSTNAME=`hostname`
142181335Sjhb
143181335Sjhbif [ ! -e $VMCORE ]; then
144181335Sjhb	echo "$VMCORE not found"
145181335Sjhb	exit 1
146181335Sjhbfi
147181335Sjhb
148181335Sjhbif [ ! -e $INFO ]; then
149181335Sjhb	echo "$INFO not found"
150181335Sjhb	exit 1
151181335Sjhbfi
152181335Sjhb
153181335Sjhb# If the user didn't specify a kernel, then try to find one.
154181335Sjhbif [ -z "$KERNEL" ]; then
155181335Sjhb	find_kernel
156181335Sjhb	if [ -z "$KERNEL" ]; then
157181335Sjhb		echo "Unable to find matching kernel for $VMCORE"
158181335Sjhb		exit 1
159181335Sjhb	fi
160181335Sjhbelif [ ! -e $KERNEL ]; then
161181335Sjhb	echo "$KERNEL not found"
162181335Sjhb	exit 1
163181335Sjhbfi
164181335Sjhb
165181335Sjhbecho "Writing crash summary to $FILE."
166181335Sjhb
167198846Sdelphijumask 077
168198846Sdelphij
169181335Sjhb# Simulate uname
170303403Sjhbostype=$(gdb_command $KERNEL 'printf "%s", ostype')
171303403Sjhbosrelease=$(gdb_command $KERNEL 'printf "%s", osrelease')
172303403Sjhbversion=$(gdb_command $KERNEL 'printf "%s", version' | tr '\t\n' '  ')
173303403Sjhbmachine=$(gdb_command $KERNEL 'printf "%s", machine')
174181335Sjhb
175181335Sjhbexec > $FILE 2>&1
176181335Sjhb
177181335Sjhbecho "$HOSTNAME dumped core - see $VMCORE"
178181335Sjhbecho
179181335Sjhbdate
180181335Sjhbecho
181181335Sjhbecho "$ostype $HOSTNAME $osrelease $version $machine"
182181335Sjhbecho
183181335Sjhbsed -ne '/^  Panic String: /{s//panic: /;p;}' $INFO
184181335Sjhbecho
185181335Sjhb
186181335Sjhb# XXX: /bin/sh on 7.0+ is broken so we can't simply pipe the commands to
187181335Sjhb# kgdb via stdin and have to use a temporary file instead.
188181335Sjhbfile=`mktemp /tmp/crashinfo.XXXXXX`
189181335Sjhbif [ $? -eq 0 ]; then
190181335Sjhb	echo "bt" >> $file
191181335Sjhb	echo "quit" >> $file
192303403Sjhb	if [ -x /usr/local/bin/kgdb ]; then
193303403Sjhb		/usr/local/bin/kgdb $KERNEL $VMCORE < $file
194303403Sjhb	else
195303403Sjhb		kgdb $KERNEL $VMCORE < $file
196303403Sjhb	fi
197181335Sjhb	rm -f $file
198181335Sjhb	echo
199181335Sjhbfi
200181335Sjhbecho
201181335Sjhb
202181335Sjhbecho "------------------------------------------------------------------------"
203260196Spluknetecho "ps -axlww"
204181335Sjhbecho
205260196Spluknetps -M $VMCORE -N $KERNEL -axlww
206181335Sjhbecho
207181335Sjhb
208181335Sjhbecho "------------------------------------------------------------------------"
209181335Sjhbecho "vmstat -s"
210181335Sjhbecho
211181335Sjhbvmstat -M $VMCORE -N $KERNEL -s
212181335Sjhbecho
213181335Sjhb
214181335Sjhbecho "------------------------------------------------------------------------"
215181335Sjhbecho "vmstat -m"
216181335Sjhbecho
217181335Sjhbvmstat -M $VMCORE -N $KERNEL -m
218181335Sjhbecho
219181335Sjhb
220181335Sjhbecho "------------------------------------------------------------------------"
221181335Sjhbecho "vmstat -z"
222181335Sjhbecho
223181335Sjhbvmstat -M $VMCORE -N $KERNEL -z
224181335Sjhbecho
225181335Sjhb
226181335Sjhbecho "------------------------------------------------------------------------"
227181335Sjhbecho "vmstat -i"
228181335Sjhbecho
229181335Sjhbvmstat -M $VMCORE -N $KERNEL -i
230181335Sjhbecho
231181335Sjhb
232181335Sjhbecho "------------------------------------------------------------------------"
233181335Sjhbecho "pstat -T"
234181335Sjhbecho
235181335Sjhbpstat -M $VMCORE -N $KERNEL -T
236181335Sjhbecho
237181335Sjhb
238181335Sjhbecho "------------------------------------------------------------------------"
239181335Sjhbecho "pstat -s"
240181335Sjhbecho
241181335Sjhbpstat -M $VMCORE -N $KERNEL -s
242181335Sjhbecho
243181335Sjhb
244181335Sjhbecho "------------------------------------------------------------------------"
245181335Sjhbecho "iostat"
246181335Sjhbecho
247181335Sjhbiostat -M $VMCORE -N $KERNEL
248181335Sjhbecho
249181335Sjhb
250181335Sjhbecho "------------------------------------------------------------------------"
251181335Sjhbecho "ipcs -a"
252181335Sjhbecho
253181335Sjhbipcs -C $VMCORE -N $KERNEL -a
254181335Sjhbecho
255181335Sjhb
256181335Sjhbecho "------------------------------------------------------------------------"
257181335Sjhbecho "ipcs -T"
258181335Sjhbecho
259181335Sjhbipcs -C $VMCORE -N $KERNEL -T
260181335Sjhbecho
261181335Sjhb
262181335Sjhb# XXX: This doesn't actually work in 5.x+
263181335Sjhbif false; then
264181335Sjhbecho "------------------------------------------------------------------------"
265181335Sjhbecho "w -dn"
266181335Sjhbecho
267181335Sjhbw -M $VMCORE -N $KERNEL -dn
268181335Sjhbecho
269181335Sjhbfi
270181335Sjhb
271181335Sjhbecho "------------------------------------------------------------------------"
272181335Sjhbecho "nfsstat"
273181335Sjhbecho
274181335Sjhbnfsstat -M $VMCORE -N $KERNEL
275181335Sjhbecho
276181335Sjhb
277181335Sjhbecho "------------------------------------------------------------------------"
278181335Sjhbecho "netstat -s"
279181335Sjhbecho
280181335Sjhbnetstat -M $VMCORE -N $KERNEL -s
281181335Sjhbecho
282181335Sjhb
283181335Sjhbecho "------------------------------------------------------------------------"
284181335Sjhbecho "netstat -m"
285181335Sjhbecho
286181335Sjhbnetstat -M $VMCORE -N $KERNEL -m
287181335Sjhbecho
288181335Sjhb
289181335Sjhbecho "------------------------------------------------------------------------"
290181335Sjhbecho "netstat -anr"
291181335Sjhbecho
292181335Sjhbnetstat -M $VMCORE -N $KERNEL -anr
293181335Sjhbecho
294181335Sjhb
295181335Sjhbecho "------------------------------------------------------------------------"
296181335Sjhbecho "netstat -anA"
297181335Sjhbecho
298181335Sjhbnetstat -M $VMCORE -N $KERNEL -anA
299181335Sjhbecho
300181335Sjhb
301181335Sjhbecho "------------------------------------------------------------------------"
302181335Sjhbecho "netstat -aL"
303181335Sjhbecho
304181335Sjhbnetstat -M $VMCORE -N $KERNEL -aL
305181335Sjhbecho
306181335Sjhb
307181335Sjhbecho "------------------------------------------------------------------------"
308181335Sjhbecho "fstat"
309181335Sjhbecho
310181335Sjhbfstat -M $VMCORE -N $KERNEL
311181335Sjhbecho
312181335Sjhb
313181335Sjhbecho "------------------------------------------------------------------------"
314181335Sjhbecho "dmesg"
315181335Sjhbecho
316181335Sjhbdmesg -a -M $VMCORE -N $KERNEL
317181335Sjhbecho
318181335Sjhb
319181335Sjhbecho "------------------------------------------------------------------------"
320181335Sjhbecho "kernel config"
321181335Sjhbecho
322181335Sjhbconfig -x $KERNEL
323198586Sjhb
324198586Sjhbecho
325198586Sjhbecho "------------------------------------------------------------------------"
326198586Sjhbecho "ddb capture buffer"
327198586Sjhbecho
328198586Sjhb
329198586Sjhbddb capture -M $VMCORE -N $KERNEL print
330