crashinfo - Add script to gather info from dumps
[dragonfly.git] / usr.sbin / crashinfo / crashinfo.sh
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
32 usage()
33 {
34         echo "usage: crashinfo [-d crashdir] [-n dumpnr] [-k kernel] [core]"
35         exit 1
36 }
37
38 find_kernel()
39 {
40         local ivers k kvers file
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         file=`mktemp /tmp/crashinfo.XXXXXX`
56         if [ $? -eq 0 ]; then
57                 echo 'printf "  Version String: %s", version' > $file
58                 # Look for a matching kernel version.
59                 for k in /boot/kernel/kernel $(ls -t $CRASHDIR/kern.*) $(ls -t /boot/*/kernel); do
60                         kvers=$(gdb -x $file -batch $k 2>/dev/null)
61                         if [ "$ivers" = "$kvers" ]; then
62                                 KERNEL=$k
63                                 KVERS=$kvers
64                                 break
65                         fi
66                 done
67                 rm -f $file
68         fi
69 }
70
71 CRASHDIR=/var/crash
72 DUMPNR=
73 KERNEL=
74 KVERS=
75
76 while getopts "d:n:k:" opt; do
77         case "$opt" in
78         d)
79                 CRASHDIR=$OPTARG
80                 ;;
81         n)
82                 DUMPNR=$OPTARG
83                 ;;
84         k)
85                 KERNEL=$OPTARG
86                 ;;
87         \?)
88                 usage
89                 ;;
90         esac
91 done
92
93 shift $((OPTIND - 1))
94
95 if [ $# -eq 1 ]; then
96         if [ -n "$DUMPNR" ]; then
97                 echo "-n and an explicit vmcore are mutually exclusive"
98                 usage
99         fi
100
101         # Figure out the crash directory and number from the vmcore name.
102         CRASHDIR=`dirname $1`
103         DUMPNR=$(expr $(basename $1) : 'vmcore\.\([0-9]*\)$')
104         if [ -z "$DUMPNR" ]; then
105                 echo "Unable to determine dump number from vmcore file $1."
106                 exit 1
107         fi
108 elif [ $# -gt 1 ]; then
109         usage
110 else
111         # If we don't have an explicit dump number, operate on the most
112         # recent dump.
113         if [ -z "$DUMPNR" ]; then
114                 if ! [ -r $CRASHDIR/bounds ]; then
115                         echo "No crash dumps in $CRASHDIR."
116                         exit 1
117                 fi                      
118                 next=`cat $CRASHDIR/bounds`
119                 if [ -z "$next" ] || [ "$next" -eq 0 ]; then
120                         echo "No crash dumps in $CRASHDIR."
121                         exit 1
122                 fi
123                 DUMPNR=$(($next - 1))
124         fi
125 fi
126
127 VMCORE=$CRASHDIR/vmcore.$DUMPNR
128 INFO=$CRASHDIR/info.$DUMPNR
129 FILE=$CRASHDIR/core.txt.$DUMPNR
130 HOSTNAME=`hostname`
131
132 if [ ! -e $VMCORE ]; then
133         echo "$VMCORE not found"
134         exit 1
135 fi
136
137 if [ ! -e $INFO ]; then
138         echo "$INFO not found"
139         exit 1
140 fi
141
142 # If the user didn't specify a kernel, then try to find one.
143 if [ -z "$KERNEL" ]; then
144         find_kernel
145         if [ -z "$KERNEL" ]; then
146                 echo "Unable to find matching kernel for $VMCORE"
147                 exit 1
148         fi
149 elif [ ! -e $KERNEL ]; then
150         echo "$KERNEL not found"
151         exit 1
152 fi
153
154 echo "Writing crash summary to $FILE."
155
156 # Simulate uname
157 #ostype=$(echo -e printf '"%s", ostype' | gdb -x /dev/stdin -batch $KERNEL)
158 #osrelease=$(echo -e printf '"%s", osrelease' | gdb -x /dev/stdin -batch $KERNEL)
159 #version=$(echo -e printf '"%s", version' | gdb -x /dev/stdin -batch $KERNEL | \
160 #    tr '\t\n' '  ')
161 #machine=$(echo -e printf '"%s", machine' | gdb -x /dev/stdin -batch $KERNEL)
162
163 exec > $FILE 2>&1
164
165 echo "$HOSTNAME dumped core - see $VMCORE"
166 echo
167 date
168 echo
169 #echo "$ostype $HOSTNAME $osrelease $version $machine"
170 echo $KVERS
171 echo
172 sed -ne '/^  Panic String: /{s//panic: /;p;}' $INFO
173 echo
174
175 # XXX: /bin/sh on 7.0+ is broken so we can't simply pipe the commands to
176 # kgdb via stdin and have to use a temporary file instead.
177 file=`mktemp /tmp/crashinfo.XXXXXX`
178 if [ $? -eq 0 ]; then
179         echo "bt" >> $file
180         if [ -e /usr/src/test/debug/gdb.kernel ]; then
181                 echo "source /usr/src/test/debug/gdb.kernel" >> $file
182                 echo "psx" >> $file
183                 echo "running_threads" >> $file
184                 echo "lstok" >> $file
185                 echo "kldstat" >> $file
186                 echo "lsvfs" >> $file
187                 echo "lsvfsops" >> $file
188                 echo "lsmount" >> $file
189         fi
190         echo "quit" >> $file
191         kgdb $KERNEL $VMCORE < $file
192         rm -f $file
193         echo
194 fi
195 echo
196
197 echo "------------------------------------------------------------------------"
198 echo "ps -axl"
199 echo
200 ps -M $VMCORE -N $KERNEL -axl
201 echo
202
203 echo "------------------------------------------------------------------------"
204 echo "vmstat -s"
205 echo
206 vmstat -M $VMCORE -N $KERNEL -s
207 echo
208
209 echo "------------------------------------------------------------------------"
210 echo "vmstat -m"
211 echo
212 vmstat -M $VMCORE -N $KERNEL -m
213 echo
214
215 echo "------------------------------------------------------------------------"
216 echo "vmstat -z"
217 echo
218 vmstat -M $VMCORE -N $KERNEL -z
219 echo
220
221 echo "------------------------------------------------------------------------"
222 echo "vmstat -i"
223 echo
224 vmstat -M $VMCORE -N $KERNEL -i
225 echo
226
227 echo "------------------------------------------------------------------------"
228 echo "pstat -T"
229 echo
230 pstat -M $VMCORE -N $KERNEL -T
231 echo
232
233 echo "------------------------------------------------------------------------"
234 echo "pstat -s"
235 echo
236 pstat -M $VMCORE -N $KERNEL -s
237 echo
238
239 #echo "------------------------------------------------------------------------"
240 #echo "iostat"
241 #echo
242 #iostat -M $VMCORE -N $KERNEL
243 #echo
244
245 echo "------------------------------------------------------------------------"
246 echo "ipcs -a"
247 echo
248 ipcs -C $VMCORE -N $KERNEL -a
249 echo
250
251 echo "------------------------------------------------------------------------"
252 echo "ipcs -T"
253 echo
254 ipcs -C $VMCORE -N $KERNEL -T
255 echo
256
257 # XXX: This doesn't actually work in 5.x+
258 if false; then
259 echo "------------------------------------------------------------------------"
260 echo "w -dn"
261 echo
262 w -M $VMCORE -N $KERNEL -dn
263 echo
264 fi
265
266 echo "------------------------------------------------------------------------"
267 echo "nfsstat"
268 echo
269 nfsstat -M $VMCORE -N $KERNEL
270 echo
271
272 echo "------------------------------------------------------------------------"
273 echo "netstat -s"
274 echo
275 netstat -M $VMCORE -N $KERNEL -s
276 echo
277
278 echo "------------------------------------------------------------------------"
279 echo "netstat -m"
280 echo
281 netstat -M $VMCORE -N $KERNEL -m
282 echo
283
284 echo "------------------------------------------------------------------------"
285 echo "netstat -id"
286 echo
287 netstat -M $VMCORE -N $KERNEL -id
288 echo
289
290 echo "------------------------------------------------------------------------"
291 echo "netstat -anr"
292 echo
293 netstat -M $VMCORE -N $KERNEL -anr
294 echo
295
296 echo "------------------------------------------------------------------------"
297 echo "netstat -anA"
298 echo
299 netstat -M $VMCORE -N $KERNEL -anA
300 echo
301
302 echo "------------------------------------------------------------------------"
303 echo "netstat -aL"
304 echo
305 netstat -M $VMCORE -N $KERNEL -aL
306 echo
307
308 echo "------------------------------------------------------------------------"
309 echo "fstat"
310 echo
311 fstat -M $VMCORE -N $KERNEL
312 echo
313
314 echo "------------------------------------------------------------------------"
315 echo "dmesg"
316 echo
317 dmesg -a -M $VMCORE -N $KERNEL
318 echo
319
320 #echo "------------------------------------------------------------------------"
321 #echo "kernel config"
322 #echo
323 #config -x $KERNEL