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