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