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