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