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 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. 41gdb_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 54find_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 83CRASHDIR=/var/crash 84DUMPNR= 85KERNEL= 86 87while 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 102done 103 104shift $((OPTIND - 1)) 105 106if [ $# -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 119elif [ $# -gt 1 ]; then 120 usage 121else 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 136fi 137 138VMCORE=$CRASHDIR/vmcore.$DUMPNR 139INFO=$CRASHDIR/info.$DUMPNR 140FILE=$CRASHDIR/core.txt.$DUMPNR 141HOSTNAME=`hostname` 142 143if [ ! -e $VMCORE ]; then 144 echo "$VMCORE not found" 145 exit 1 146fi 147 148if [ ! -e $INFO ]; then 149 echo "$INFO not found" 150 exit 1 151fi 152 153# If the user didn't specify a kernel, then try to find one. 154if [ -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 160elif [ ! -e $KERNEL ]; then 161 echo "$KERNEL not found" 162 exit 1 163fi 164 165echo "Writing crash summary to $FILE." 166 167umask 077 168 169# Simulate uname 170ostype=$(gdb_command $KERNEL 'printf "%s", ostype') 171osrelease=$(gdb_command $KERNEL 'printf "%s", osrelease') 172version=$(gdb_command $KERNEL 'printf "%s", version' | tr '\t\n' ' ') 173machine=$(gdb_command $KERNEL 'printf "%s", machine') 174 175exec > $FILE 2>&1 176 177echo "$HOSTNAME dumped core - see $VMCORE" 178echo 179date 180echo 181echo "$ostype $HOSTNAME $osrelease $version $machine" 182echo 183sed -ne '/^ Panic String: /{s//panic: /;p;}' $INFO 184echo 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. 188file=`mktemp /tmp/crashinfo.XXXXXX` 189if [ $? -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 199fi 200echo 201 202echo "------------------------------------------------------------------------" 203echo "ps -axlww" 204echo 205ps -M $VMCORE -N $KERNEL -axlww 206echo 207 208echo "------------------------------------------------------------------------" 209echo "vmstat -s" 210echo 211vmstat -M $VMCORE -N $KERNEL -s 212echo 213 214echo "------------------------------------------------------------------------" 215echo "vmstat -m" 216echo 217vmstat -M $VMCORE -N $KERNEL -m 218echo 219 220echo "------------------------------------------------------------------------" 221echo "vmstat -z" 222echo 223vmstat -M $VMCORE -N $KERNEL -z 224echo 225 226echo "------------------------------------------------------------------------" 227echo "vmstat -i" 228echo 229vmstat -M $VMCORE -N $KERNEL -i 230echo 231 232echo "------------------------------------------------------------------------" 233echo "pstat -T" 234echo 235pstat -M $VMCORE -N $KERNEL -T 236echo 237 238echo "------------------------------------------------------------------------" 239echo "pstat -s" 240echo 241pstat -M $VMCORE -N $KERNEL -s 242echo 243 244echo "------------------------------------------------------------------------" 245echo "iostat" 246echo 247iostat -M $VMCORE -N $KERNEL 248echo 249 250echo "------------------------------------------------------------------------" 251echo "ipcs -a" 252echo 253ipcs -C $VMCORE -N $KERNEL -a 254echo 255 256echo "------------------------------------------------------------------------" 257echo "ipcs -T" 258echo 259ipcs -C $VMCORE -N $KERNEL -T 260echo 261 262# XXX: This doesn't actually work in 5.x+ 263if false; then 264echo "------------------------------------------------------------------------" 265echo "w -dn" 266echo 267w -M $VMCORE -N $KERNEL -dn 268echo 269fi 270 271echo "------------------------------------------------------------------------" 272echo "nfsstat" 273echo 274nfsstat -M $VMCORE -N $KERNEL 275echo 276 277echo "------------------------------------------------------------------------" 278echo "netstat -s" 279echo 280netstat -M $VMCORE -N $KERNEL -s 281echo 282 283echo "------------------------------------------------------------------------" 284echo "netstat -m" 285echo 286netstat -M $VMCORE -N $KERNEL -m 287echo 288 289echo "------------------------------------------------------------------------" 290echo "netstat -anA" 291echo 292netstat -M $VMCORE -N $KERNEL -anA 293echo 294 295echo "------------------------------------------------------------------------" 296echo "netstat -aL" 297echo 298netstat -M $VMCORE -N $KERNEL -aL 299echo 300 301echo "------------------------------------------------------------------------" 302echo "fstat" 303echo 304fstat -M $VMCORE -N $KERNEL 305echo 306 307echo "------------------------------------------------------------------------" 308echo "dmesg" 309echo 310dmesg -a -M $VMCORE -N $KERNEL 311echo 312 313echo "------------------------------------------------------------------------" 314echo "kernel config" 315echo 316config -x $KERNEL 317 318echo 319echo "------------------------------------------------------------------------" 320echo "ddb capture buffer" 321echo 322 323ddb capture -M $VMCORE -N $KERNEL print 324