1#!/bin/sh 2# 3# SPDX-License-Identifier: BSD-3-Clause 4# 5# Copyright (c) 2008 Yahoo!, Inc. 6# All rights reserved. 7# 8# Redistribution and use in source and binary forms, with or without 9# modification, are permitted provided that the following conditions 10# are met: 11# 1. Redistributions of source code must retain the above copyright 12# notice, this list of conditions and the following disclaimer. 13# 2. Redistributions in binary form must reproduce the above copyright 14# notice, this list of conditions and the following disclaimer in the 15# documentation and/or other materials provided with the distribution. 16# 3. Neither the name of the author nor the names of any co-contributors 17# may be used to endorse or promote products derived from this software 18# without specific prior written permission. 19# 20# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30# SUCH DAMAGE. 31# 32# $FreeBSD$ 33 34usage() 35{ 36 echo "usage: crashinfo [-b] [-d crashdir] [-n dumpnr]" \ 37 "[-k kernel] [core]" 38 exit 1 39} 40 41# Find a gdb binary to use and save the value in GDB. 42find_gdb() 43{ 44 local binary 45 46 for binary in /usr/local/bin/gdb /usr/libexec/gdb /usr/bin/gdb; do 47 if [ -x ${binary} ]; then 48 GDB=${binary} 49 return 50 fi 51 done 52} 53 54# Run a single gdb command against a kernel file in batch mode. 55# The kernel file is specified as the first argument and the command 56# is given in the remaining arguments. 57gdb_command() 58{ 59 local k 60 61 k=$1 ; shift 62 63 if [ ${GDB} = /usr/local/bin/gdb ]; then 64 ${GDB} -batch -ex "$@" $k 65 else 66 echo -e "$@" | ${GDB} -x /dev/stdin -batch $k 67 fi 68} 69 70find_kernel() 71{ 72 local ivers k kvers 73 74 ivers=$(awk ' 75 /Version String/ { 76 print 77 nextline=1 78 next 79 } 80 nextline==1 { 81 if ($0 ~ "^ [A-Za-z ]+: ") { 82 nextline=0 83 } else { 84 print 85 } 86 }' $INFO) 87 88 # Look for a matching kernel version, handling possible truncation 89 # of the version string recovered from the dump. 90 for k in `sysctl -n kern.bootfile` $(ls -t /boot/*/kernel); do 91 kvers=$(gdb_command $k 'printf " Version String: %s", version' | \ 92 awk "{line=line\$0\"\n\"} END{print substr(line,1,${#ivers})}" \ 93 2>/dev/null) 94 if [ "$ivers" = "$kvers" ]; then 95 KERNEL=$k 96 break 97 fi 98 done 99} 100 101BATCH=false 102CRASHDIR=/var/crash 103DUMPNR= 104KERNEL= 105 106while getopts "bd:n:k:" opt; do 107 case "$opt" in 108 b) 109 BATCH=true 110 ;; 111 d) 112 CRASHDIR=$OPTARG 113 ;; 114 n) 115 DUMPNR=$OPTARG 116 ;; 117 k) 118 KERNEL=$OPTARG 119 ;; 120 \?) 121 usage 122 ;; 123 esac 124done 125 126shift $((OPTIND - 1)) 127 128if [ $# -eq 1 ]; then 129 if [ -n "$DUMPNR" ]; then 130 echo "-n and an explicit vmcore are mutually exclusive" 131 usage 132 fi 133 134 # Figure out the crash directory and number from the vmcore name. 135 CRASHDIR=`dirname $1` 136 DUMPNR=$(expr $(basename $1) : 'vmcore\.\([0-9]*\)$') 137 if [ -z "$DUMPNR" ]; then 138 echo "Unable to determine dump number from vmcore file $1." 139 exit 1 140 fi 141elif [ $# -gt 1 ]; then 142 usage 143else 144 # If we don't have an explicit dump number, operate on the most 145 # recent dump. 146 if [ -z "$DUMPNR" ]; then 147 if ! [ -r $CRASHDIR/bounds ]; then 148 echo "No crash dumps in $CRASHDIR." 149 exit 1 150 fi 151 next=`cat $CRASHDIR/bounds` 152 if [ -z "$next" ] || [ "$next" -eq 0 ]; then 153 echo "No crash dumps in $CRASHDIR." 154 exit 1 155 fi 156 DUMPNR=$(($next - 1)) 157 fi 158fi 159 160VMCORE=$CRASHDIR/vmcore.$DUMPNR 161INFO=$CRASHDIR/info.$DUMPNR 162FILE=$CRASHDIR/core.txt.$DUMPNR 163HOSTNAME=`hostname` 164 165if $BATCH; then 166 echo "Writing crash summary to $FILE." 167 exec > $FILE 2>&1 168fi 169 170find_gdb 171if [ -z "$GDB" ]; then 172 echo "Unable to find a kernel debugger." 173 exit 1 174fi 175 176if [ ! -e $VMCORE ]; then 177 echo "$VMCORE not found" 178 exit 1 179fi 180 181if [ ! -e $INFO ]; then 182 echo "$INFO not found" 183 exit 1 184fi 185 186# If the user didn't specify a kernel, then try to find one. 187if [ -z "$KERNEL" ]; then 188 find_kernel 189 if [ -z "$KERNEL" ]; then 190 echo "Unable to find matching kernel for $VMCORE" 191 exit 1 192 fi 193elif [ ! -e $KERNEL ]; then 194 echo "$KERNEL not found" 195 exit 1 196fi 197 198umask 077 199 200# Simulate uname 201ostype=$(gdb_command $KERNEL 'printf "%s", ostype') 202osrelease=$(gdb_command $KERNEL 'printf "%s", osrelease') 203version=$(gdb_command $KERNEL 'printf "%s", version' | tr '\t\n' ' ') 204machine=$(gdb_command $KERNEL 'printf "%s", machine') 205 206if ! $BATCH; then 207 echo "Writing crash summary to $FILE." 208 exec > $FILE 2>&1 209fi 210 211echo "$HOSTNAME dumped core - see $VMCORE" 212echo 213date 214echo 215echo "$ostype $HOSTNAME $osrelease $version $machine" 216echo 217sed -ne '/^ Panic String: /{s//panic: /;p;}' $INFO 218echo 219 220# XXX: /bin/sh on 7.0+ is broken so we can't simply pipe the commands to 221# kgdb via stdin and have to use a temporary file instead. 222file=`mktemp /tmp/crashinfo.XXXXXX` 223if [ $? -eq 0 ]; then 224 echo "bt" >> $file 225 echo "quit" >> $file 226 ${GDB%gdb}kgdb $KERNEL $VMCORE < $file 227 rm -f $file 228 echo 229fi 230echo 231 232echo "------------------------------------------------------------------------" 233echo "ps -axlww" 234echo 235ps -M $VMCORE -N $KERNEL -axlww 236echo 237 238echo "------------------------------------------------------------------------" 239echo "vmstat -s" 240echo 241vmstat -M $VMCORE -N $KERNEL -s 242echo 243 244echo "------------------------------------------------------------------------" 245echo "vmstat -m" 246echo 247vmstat -M $VMCORE -N $KERNEL -m 248echo 249 250echo "------------------------------------------------------------------------" 251echo "vmstat -z" 252echo 253vmstat -M $VMCORE -N $KERNEL -z 254echo 255 256echo "------------------------------------------------------------------------" 257echo "vmstat -i" 258echo 259vmstat -M $VMCORE -N $KERNEL -i 260echo 261 262echo "------------------------------------------------------------------------" 263echo "pstat -T" 264echo 265pstat -M $VMCORE -N $KERNEL -T 266echo 267 268echo "------------------------------------------------------------------------" 269echo "pstat -s" 270echo 271pstat -M $VMCORE -N $KERNEL -s 272echo 273 274echo "------------------------------------------------------------------------" 275echo "iostat" 276echo 277iostat -M $VMCORE -N $KERNEL 278echo 279 280echo "------------------------------------------------------------------------" 281echo "ipcs -a" 282echo 283ipcs -C $VMCORE -N $KERNEL -a 284echo 285 286echo "------------------------------------------------------------------------" 287echo "ipcs -T" 288echo 289ipcs -C $VMCORE -N $KERNEL -T 290echo 291 292# XXX: This doesn't actually work in 5.x+ 293if false; then 294echo "------------------------------------------------------------------------" 295echo "w -dn" 296echo 297w -M $VMCORE -N $KERNEL -dn 298echo 299fi 300 301echo "------------------------------------------------------------------------" 302echo "nfsstat" 303echo 304nfsstat -M $VMCORE -N $KERNEL 305echo 306 307echo "------------------------------------------------------------------------" 308echo "netstat -s" 309echo 310netstat -M $VMCORE -N $KERNEL -s 311echo 312 313echo "------------------------------------------------------------------------" 314echo "netstat -m" 315echo 316netstat -M $VMCORE -N $KERNEL -m 317echo 318 319echo "------------------------------------------------------------------------" 320echo "netstat -anA" 321echo 322netstat -M $VMCORE -N $KERNEL -anA 323echo 324 325echo "------------------------------------------------------------------------" 326echo "netstat -aL" 327echo 328netstat -M $VMCORE -N $KERNEL -aL 329echo 330 331echo "------------------------------------------------------------------------" 332echo "fstat" 333echo 334fstat -M $VMCORE -N $KERNEL 335echo 336 337echo "------------------------------------------------------------------------" 338echo "dmesg" 339echo 340dmesg -a -M $VMCORE -N $KERNEL 341echo 342 343echo "------------------------------------------------------------------------" 344echo "kernel config" 345echo 346config -x $KERNEL 347 348echo 349echo "------------------------------------------------------------------------" 350echo "ddb capture buffer" 351echo 352 353ddb capture -M $VMCORE -N $KERNEL print 354