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