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