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