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