Index: head/etc/rc.d/savecore =================================================================== --- head/etc/rc.d/savecore (revision 319476) +++ head/etc/rc.d/savecore (revision 319477) @@ -1,82 +1,82 @@ #!/bin/sh # # $FreeBSD$ # # PROVIDE: savecore # REQUIRE: dumpon ddb syslogd # KEYWORD: nojail . /etc/rc.subr name="savecore" rcvar="savecore_enable" desc="Save a core dump of the operating system" start_cmd="savecore_start" start_precmd="savecore_prestart" stop_cmd=":" savecore_prestart() { # Quit if we have no dump device case ${dumpdev} in [Nn][Oo] | '') debug 'No dump device. Quitting.' return 1 ;; [Aa][Uu][Tt][Oo]) if [ ! -L /dev/dumpdev ]; then return 1 fi dumpdev=`/bin/realpath /dev/dumpdev` ;; esac # If there is no crash directory set it now case ${dumpdir} in '') dumpdir='/var/crash' ;; [Nn][Oo]) dumpdir='NO' ;; esac if [ ! -c "${dumpdev}" ]; then warn "Dump device does not exist. Savecore not run." return 1 fi if [ ! -d "${dumpdir}" ]; then warn "Dump directory does not exist. Savecore not run." return 1 fi return 0 } savecore_start() { local dev case "${dumpdev}" in [Aa][Uu][Tt][Oo]) dev= ;; *) dev="${dumpdev}" ;; esac if savecore -C "${dev}" >/dev/null; then savecore ${savecore_flags} ${dumpdir} ${dumpdev} if checkyesno crashinfo_enable; then - ${crashinfo_program} -d ${dumpdir} + ${crashinfo_program} -b -d ${dumpdir} fi sync else check_startmsgs && echo 'No core dumps found.' fi } load_rc_config $name run_rc_command "$1" Index: head/usr.sbin/crashinfo/crashinfo.8 =================================================================== --- head/usr.sbin/crashinfo/crashinfo.8 (revision 319476) +++ head/usr.sbin/crashinfo/crashinfo.8 (revision 319477) @@ -1,109 +1,115 @@ .\" Copyright (c) 2008 Yahoo!, Inc. .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. Neither the name of the author nor the names of any co-contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .\" -.Dd June 28, 2008 +.Dd April 19, 2017 .Dt CRASHINFO 8 .Os .Sh NAME .Nm crashinfo .Nd "analyze a core dump of the operating system" .Sh SYNOPSIS .Nm .Op Fl d Ar crashdir .Op Fl n Ar dumpnr .Op Fl k Ar kernel .Op Ar core .Sh DESCRIPTION The .Nm utility analyzes a core dump saved by .Xr savecore 8 . It generates a text file containing the analysis in the same directory as the core dump. For a given core dump file named .Pa vmcore.XX the generated text file will be named .Pa core.txt.XX . .Pp By default, .Nm analyzes the most recent core dump in the core dump directory. A specific core dump may be specified via either the .Ar core or .Ar dumpnr arguments. Once .Nm has located a core dump, it analyzes the core dump to determine the exact version of the kernel that generated the core. It then looks for a matching kernel file under each of the subdirectories in .Pa /boot . The location of the kernel file can also be explicitly provided via the .Ar kernel argument. .Pp Once .Nm has located a core dump and kernel, it uses several utilities to analyze the core including .Xr dmesg 8 , .Xr fstat 1 , .Xr iostat 8 , .Xr ipcs 1 , .Xr kgdb 1 , .Xr netstat 1 , .Xr nfsstat 1 , .Xr ps 1 , .Xr pstat 8 , and .Xr vmstat 8 . .Pp The options are as follows: .Bl -tag -width indent +.It Fl b +Run in batch mode. Write most messages to the +.Pa core.txt.XX +file instead of the terminal. This flag is used when +.Nm +is run during boot. .It Fl d Ar crashdir Specify an alternate core dump directory. The default crash dump directory is .Pa /var/crash . .It Fl n Ar dumpnr Use the core dump saved in .Pa vmcore. Ns Ar dumpnr instead of the latest core in the core dump directory. .It Fl k Ar kernel Specify an explicit kernel file. .El .Sh SEE ALSO .Xr textdump 4 , .Xr savecore 8 .Sh HISTORY The .Nm utility appeared in .Fx 6.4 . Index: head/usr.sbin/crashinfo/crashinfo.sh =================================================================== --- head/usr.sbin/crashinfo/crashinfo.sh (revision 319476) +++ head/usr.sbin/crashinfo/crashinfo.sh (revision 319477) @@ -1,338 +1,349 @@ #!/bin/sh # # Copyright (c) 2008 Yahoo!, Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of the author nor the names of any co-contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ usage() { - echo "usage: crashinfo [-d crashdir] [-n dumpnr] [-k kernel] [core]" + echo "usage: crashinfo [-b] [-d crashdir] [-n dumpnr]" \ + "[-k kernel] [core]" exit 1 } # Find a gdb binary to use and save the value in GDB. find_gdb() { local binary for binary in /usr/local/bin/gdb /usr/libexec/gdb /usr/bin/gdb; do if [ -x ${binary} ]; then GDB=${binary} return fi done } # Run a single gdb command against a kernel file in batch mode. # The kernel file is specified as the first argument and the command # is given in the remaining arguments. gdb_command() { local k k=$1 ; shift if [ ${GDB} = /usr/local/bin/gdb ]; then ${GDB} -batch -ex "$@" $k else echo -e "$@" | ${GDB} -x /dev/stdin -batch $k fi } find_kernel() { local ivers k kvers ivers=$(awk ' /Version String/ { print nextline=1 next } nextline==1 { if ($0 ~ "^ [A-Za-z ]+: ") { nextline=0 } else { print } }' $INFO) # Look for a matching kernel version. for k in `sysctl -n kern.bootfile` $(ls -t /boot/*/kernel); do kvers=$(gdb_command $k 'printf " Version String: %s", version' \ 2>/dev/null) if [ "$ivers" = "$kvers" ]; then KERNEL=$k break fi done } +BATCH=false CRASHDIR=/var/crash DUMPNR= KERNEL= -while getopts "d:n:k:" opt; do +while getopts "bd:n:k:" opt; do case "$opt" in + b) + BATCH=true + ;; d) CRASHDIR=$OPTARG ;; n) DUMPNR=$OPTARG ;; k) KERNEL=$OPTARG ;; \?) usage ;; esac done shift $((OPTIND - 1)) if [ $# -eq 1 ]; then if [ -n "$DUMPNR" ]; then echo "-n and an explicit vmcore are mutually exclusive" usage fi # Figure out the crash directory and number from the vmcore name. CRASHDIR=`dirname $1` DUMPNR=$(expr $(basename $1) : 'vmcore\.\([0-9]*\)$') if [ -z "$DUMPNR" ]; then echo "Unable to determine dump number from vmcore file $1." exit 1 fi elif [ $# -gt 1 ]; then usage else # If we don't have an explicit dump number, operate on the most # recent dump. if [ -z "$DUMPNR" ]; then if ! [ -r $CRASHDIR/bounds ]; then echo "No crash dumps in $CRASHDIR." exit 1 fi next=`cat $CRASHDIR/bounds` if [ -z "$next" ] || [ "$next" -eq 0 ]; then echo "No crash dumps in $CRASHDIR." exit 1 fi DUMPNR=$(($next - 1)) fi fi VMCORE=$CRASHDIR/vmcore.$DUMPNR INFO=$CRASHDIR/info.$DUMPNR FILE=$CRASHDIR/core.txt.$DUMPNR HOSTNAME=`hostname` +if $BATCH; then + echo "Writing crash summary to $FILE." + exec > $FILE 2>&1 +fi + find_gdb if [ -z "$GDB" ]; then echo "Unable to find a kernel debugger." exit 1 fi if [ ! -e $VMCORE ]; then echo "$VMCORE not found" exit 1 fi if [ ! -e $INFO ]; then echo "$INFO not found" exit 1 fi # If the user didn't specify a kernel, then try to find one. if [ -z "$KERNEL" ]; then find_kernel if [ -z "$KERNEL" ]; then echo "Unable to find matching kernel for $VMCORE" exit 1 fi elif [ ! -e $KERNEL ]; then echo "$KERNEL not found" exit 1 fi -echo "Writing crash summary to $FILE." - umask 077 # Simulate uname ostype=$(gdb_command $KERNEL 'printf "%s", ostype') osrelease=$(gdb_command $KERNEL 'printf "%s", osrelease') version=$(gdb_command $KERNEL 'printf "%s", version' | tr '\t\n' ' ') machine=$(gdb_command $KERNEL 'printf "%s", machine') -exec > $FILE 2>&1 +if ! $BATCH; then + echo "Writing crash summary to $FILE." + exec > $FILE 2>&1 +fi echo "$HOSTNAME dumped core - see $VMCORE" echo date echo echo "$ostype $HOSTNAME $osrelease $version $machine" echo sed -ne '/^ Panic String: /{s//panic: /;p;}' $INFO echo # XXX: /bin/sh on 7.0+ is broken so we can't simply pipe the commands to # kgdb via stdin and have to use a temporary file instead. file=`mktemp /tmp/crashinfo.XXXXXX` if [ $? -eq 0 ]; then echo "bt" >> $file echo "quit" >> $file ${GDB%gdb}kgdb $KERNEL $VMCORE < $file rm -f $file echo fi echo echo "------------------------------------------------------------------------" echo "ps -axlww" echo ps -M $VMCORE -N $KERNEL -axlww echo echo "------------------------------------------------------------------------" echo "vmstat -s" echo vmstat -M $VMCORE -N $KERNEL -s echo echo "------------------------------------------------------------------------" echo "vmstat -m" echo vmstat -M $VMCORE -N $KERNEL -m echo echo "------------------------------------------------------------------------" echo "vmstat -z" echo vmstat -M $VMCORE -N $KERNEL -z echo echo "------------------------------------------------------------------------" echo "vmstat -i" echo vmstat -M $VMCORE -N $KERNEL -i echo echo "------------------------------------------------------------------------" echo "pstat -T" echo pstat -M $VMCORE -N $KERNEL -T echo echo "------------------------------------------------------------------------" echo "pstat -s" echo pstat -M $VMCORE -N $KERNEL -s echo echo "------------------------------------------------------------------------" echo "iostat" echo iostat -M $VMCORE -N $KERNEL echo echo "------------------------------------------------------------------------" echo "ipcs -a" echo ipcs -C $VMCORE -N $KERNEL -a echo echo "------------------------------------------------------------------------" echo "ipcs -T" echo ipcs -C $VMCORE -N $KERNEL -T echo # XXX: This doesn't actually work in 5.x+ if false; then echo "------------------------------------------------------------------------" echo "w -dn" echo w -M $VMCORE -N $KERNEL -dn echo fi echo "------------------------------------------------------------------------" echo "nfsstat" echo nfsstat -M $VMCORE -N $KERNEL echo echo "------------------------------------------------------------------------" echo "netstat -s" echo netstat -M $VMCORE -N $KERNEL -s echo echo "------------------------------------------------------------------------" echo "netstat -m" echo netstat -M $VMCORE -N $KERNEL -m echo echo "------------------------------------------------------------------------" echo "netstat -anA" echo netstat -M $VMCORE -N $KERNEL -anA echo echo "------------------------------------------------------------------------" echo "netstat -aL" echo netstat -M $VMCORE -N $KERNEL -aL echo echo "------------------------------------------------------------------------" echo "fstat" echo fstat -M $VMCORE -N $KERNEL echo echo "------------------------------------------------------------------------" echo "dmesg" echo dmesg -a -M $VMCORE -N $KERNEL echo echo "------------------------------------------------------------------------" echo "kernel config" echo config -x $KERNEL echo echo "------------------------------------------------------------------------" echo "ddb capture buffer" echo ddb capture -M $VMCORE -N $KERNEL print