Add crash(8), a utility to diagnose kernel crashes. This is basically

ddb running on crash dumps, but with two notable changes:

- Breakpoints, watches, etc are obviously never going to work so they
  are not handled.

- You can pipe output to the shell, e.g. ps | grep foo

Items remaining to be done:

- Port it to architectures other than i386. This isn't difficult, just
  a case of making db_disasm.c/db_trace.c or their equivalent compile
  and work.

- Make more of the "show" commands work, e.g "show uvmexp".
This commit is contained in:
ad 2009-03-07 22:08:07 +00:00
parent cd6b1c8f08
commit 101a9782a2
13 changed files with 836 additions and 12 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.798 2009/03/03 06:01:56 mrg Exp $
# $NetBSD: mi,v 1.799 2009/03/07 22:08:07 ad Exp $
#
# Note: Don't delete entries from here - mark them as "obsolete" instead,
# unless otherwise stated below.
@ -1349,6 +1349,7 @@
./usr/sbin/chrtbl base-sysutil-bin
./usr/sbin/cnwctl base-netutil-bin
./usr/sbin/cpuctl base-sysutil-bin
./usr/sbin/crash base-sysutil-bin
./usr/sbin/cron base-cron-bin
./usr/sbin/daicctl base-isdn-bin
./usr/sbin/dbsym base-sysutil-bin bfd

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1237 2009/03/02 19:22:15 christos Exp $
# $NetBSD: mi,v 1.1238 2009/03/07 22:08:07 ad Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -3280,6 +3280,7 @@
./usr/libdata/debug/usr/sbin/chrtbl.debug comp-sysutil-debug debug
./usr/libdata/debug/usr/sbin/cnwctl.debug comp-netutil-debug debug
./usr/libdata/debug/usr/sbin/cpuctl.debug comp-sysutil-debug debug
./usr/libdata/debug/usr/sbin/crash.debug comp-sysutil-debug debug
./usr/libdata/debug/usr/sbin/cron.debug comp-cron-debug debug
./usr/libdata/debug/usr/sbin/daicctl.debug comp-isdn-debug debug
./usr/libdata/debug/usr/sbin/dbsym.debug comp-sysutil-debug bfd,debug

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1127 2009/02/27 03:13:55 kenh Exp $
# $NetBSD: mi,v 1.1128 2009/03/07 22:08:07 ad Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -2003,6 +2003,7 @@
./usr/share/man/cat8/compat_xenix.0 man-sys-catman .cat
./usr/share/man/cat8/comsat.0 man-man-catman .cat
./usr/share/man/cat8/cpuctl.0 man-sysutil-catman .cat
./usr/share/man/cat8/crash.0 man-sysutil-catman .cat
./usr/share/man/cat8/cron.0 man-cron-catman .cat
./usr/share/man/cat8/dbsym.0 man-sysutil-catman bfd,.cat
./usr/share/man/cat8/defer.0 man-postfix-catman postfix,.cat
@ -4446,6 +4447,7 @@
./usr/share/man/html8/compat_xenix.html man-sys-htmlman html
./usr/share/man/html8/comsat.html man-man-htmlman html
./usr/share/man/html8/cpuctl.html man-sysutil-htmlman html
./usr/share/man/html8/crash.html man-sysutil-htmlman html
./usr/share/man/html8/cron.html man-cron-htmlman html
./usr/share/man/html8/dbsym.html man-sysutil-htmlman bfd,html
./usr/share/man/html8/defer.html man-postfix-htmlman postfix,html
@ -6948,6 +6950,7 @@
./usr/share/man/man8/compat_xenix.8 man-sys-man .man
./usr/share/man/man8/comsat.8 man-man-man .man
./usr/share/man/man8/cpuctl.8 man-sysutil-man .man
./usr/share/man/man8/crash.8 man-crash-man .man
./usr/share/man/man8/cron.8 man-cron-man .man
./usr/share/man/man8/dbsym.8 man-sysutil-man bfd,.man
./usr/share/man/man8/defer.8 man-postfix-man postfix,.man

View File

@ -1,4 +1,4 @@
.\" $NetBSD: savecore.8,v 1.33 2004/10/21 10:13:00 dsainty Exp $
.\" $NetBSD: savecore.8,v 1.34 2009/03/07 22:08:08 ad Exp $
.\"
.\" Copyright (c) 1980, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@ -29,7 +29,7 @@
.\"
.\" @(#)savecore.8 8.1 (Berkeley) 6/5/93
.\"
.Dd October 16, 2004
.Dd March 3, 2009
.Dt SAVECORE 8
.Os
.Sh NAME
@ -69,6 +69,7 @@ the system log.
.Pp
The kernel and core file can then be analyzed using various tools,
including
.Xr crash 8 ,
.Xr dmesg 8 ,
.Xr fstat 1 ,
.Xr gdb 1 ,
@ -79,8 +80,9 @@ and
.Xr pstat 8 ,
to attempt to deduce the cause of the crash.
.Pp
Crashes are usually the result of kernel bugs; if this is suspected, a
full bug report should be filed using
Crashes are usually the result of hardware faults or kernel bugs.
If a kernel bug is suspected, a full bug report should be filed at
http://www.netbsd.org/, or using
.Xr send-pr 1 ,
containing as much information as possible about the circumstances of
the crash.
@ -181,7 +183,7 @@ will ignore it.
.Xr netstat 1 ,
.Xr ps 1 ,
.Xr send-pr 1 ,
.Xr secure_path 3 ,
.Xr crash 8 ,
.Xr dmesg 8 ,
.Xr iostat 8 ,
.Xr pstat 8 ,

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ddb.4,v 1.123 2009/02/04 20:45:17 wiz Exp $
.\" $NetBSD: ddb.4,v 1.124 2009/03/07 22:08:08 ad Exp $
.\"
.\" Copyright (c) 1997 - 2009 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -56,7 +56,7 @@
.\" any improvements or extensions that they make and grant Carnegie Mellon
.\" the rights to redistribute these changes.
.\"
.Dd February 2, 2009
.Dd March 7, 2009
.Dt DDB 4
.Os
.Sh NAME
@ -1386,6 +1386,7 @@ and modifiers as described above.
.Sh SEE ALSO
.Xr reboot 2 ,
.Xr options 4 ,
.Xr crash 8 ,
.Xr reboot 8 ,
.Xr sysctl 8 ,
.Xr cnmagic 9

View File

@ -1,11 +1,11 @@
# $NetBSD: Makefile,v 1.238 2008/11/12 13:17:27 pooka Exp $
# $NetBSD: Makefile,v 1.239 2009/03/07 22:08:08 ad Exp $
# from: @(#)Makefile 5.20 (Berkeley) 6/12/93
.include <bsd.own.mk>
SUBDIR= ac accton acpitools altq apm apmd arp bad144 bind bootp \
btattach btconfig btdevctl bthcid btpand catman \
chown chroot chrtbl cnwctl cpuctl cron dev_mkdb \
chown chroot chrtbl cnwctl cpuctl crash cron dev_mkdb \
dhcp diskpart dumpfs dumplfs edquota eeprom \
envstat eshconfig etcupdate extattrctl fssconfig fusermount fwctl \
gpioctl grfconfig grfinfo gspa hilinfo ifwatchd inetd installboot \

59
usr.sbin/crash/Makefile Normal file
View File

@ -0,0 +1,59 @@
# $NetBSD: Makefile,v 1.1 2009/03/07 22:08:08 ad Exp $
PROG= crash
MAN= crash.8
WARNS= 3
LDADD+= -lkvm -ledit -ltermcap
DPADD+= ${LIBKVM} ${LIBEDIT} ${LIBTERMCAP}
# some ddb kernel components need limited modifications. for now,
# punt if not noted as implemented here.
.if (${MACHINE} != "i386")
SRCS+= unsupported.c
.else
S= ${.CURDIR}/../../sys
CPPFLAGS+= -I${.CURDIR} -I${.OBJDIR} -I${S} -fno-strict-aliasing
CPPFLAGS+= -DDDB_VERBOSE_HELP -DDB_MAX_LINE=10000000 -D_KMEMUSER
# ddb files from kernel
.PATH: $S/ddb
SRCS+= db_command.c db_lwp.c db_proc.c db_xxx.c db_cpu.c
SRCS+= db_access.c db_elf.c db_examine.c
SRCS+= db_expr.c db_lex.c db_output.c db_print.c
SRCS+= db_sym.c db_variables.c db_write_cmd.c
# db_trace.c, db_disasm.c
.PATH: ${S}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
.for i in ${i} db_disasm db_trace
. if (exists(${S}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}/${i}.c))
SRCS+= ${i}.c
. endif
.endfor
# crash main source
SRCS+= crash.c
# arch.c
.PATH: ${.CURDIR}/arch
.if (exists(${.CURDIR}/arch/${MACHINE_ARCH}.c))
SRCS+= ${MACHINE_ARCH}.c
.else
SRCS+= generic.c
.endif
# vers.c
SRCS+= vers.c
vers.c: ${S}/conf/newvers.sh
${HOST_SH} ${S}/conf/newvers.sh
CLEANFILES+= vers.c version
.endif
.include <bsd.prog.mk>
.include <bsd.klinks.mk>

View File

@ -0,0 +1,50 @@
/* $NetBSD: generic.c,v 1.1 2009/03/07 22:08:08 ad Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Andrew Doran.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: generic.c,v 1.1 2009/03/07 22:08:08 ad Exp $");
#endif /* not lint */
#include <ddb/ddb.h>
#include <kvm.h>
#include <nlist.h>
#include <err.h>
#include <stdlib.h>
#include "extern.h"
void
db_mach_init(kvm_t *kd)
{
}

View File

@ -0,0 +1,72 @@
/* $NetBSD: i386.c,v 1.1 2009/03/07 22:08:08 ad Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Andrew Doran.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: i386.c,v 1.1 2009/03/07 22:08:08 ad Exp $");
#endif /* not lint */
#include <ddb/ddb.h>
#include <kvm.h>
#include <nlist.h>
#include <err.h>
#include <stdlib.h>
#include <machine/frame.h>
#include <machine/pcb.h>
#include "extern.h"
static struct nlist nl[] = {
{ .n_name = "_dumppcb" },
{ .n_name = NULL },
};
struct pcb pcb;
void
db_mach_init(kvm_t *kd)
{
if (kvm_nlist(kd, nl) == -1) {
errx(EXIT_FAILURE, "kvm_nlist: %s", kvm_geterr(kd));
}
if ((size_t)kvm_read(kd, nl[0].n_value, &pcb, sizeof(pcb)) !=
sizeof(pcb)) {
errx(EXIT_FAILURE, "cannot read dumppcb: %s", kvm_geterr(kd));
}
ddb_regs.tf_esp = pcb.pcb_esp;
ddb_regs.tf_ebp = pcb.pcb_ebp;
if (ddb_regs.tf_ebp != 0 && ddb_regs.tf_esp != 0) {
printf("Backtrace from time of crash is available.\n");
}
}

92
usr.sbin/crash/crash.8 Normal file
View File

@ -0,0 +1,92 @@
.\" $NetBSD: crash.8,v 1.1 2009/03/07 22:08:08 ad Exp $
.\"
.\" Copyright (c) 2009 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Andrew Doran.
.\"
.\" 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.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
.\"
.Dd March 7, 2009
.Dt CRASH 8
.Os
.Sh NAME
.Nm crash
.Nd examine and debug system images
.Sh SYNOPSIS
.Nm
.Op Fl M Ar core
.Op Fl N Ar system
.Sh DESCRIPTION
The
.Nm
command is used to examine and debug system images.
.Pp
If run without any arguments,
.Nm
operates on the running system.
.Pp
The options are as follows:
.Bl -tag -width xpalidocious
.It Fl M Ar core
Operate on the specified crash dump instead of the default
.Pa /dev/mem .
Crash dumps should be from the same version of the system and same machine
architecture as the running version of
.Nm crash ,
and must be uncompressed.
.It Fl N Ar kernel
Extract the name list from the specified kernel instead of the default
.Pa /dev/ksyms .
.El
.Pp
The command syntax used by
.Nm
is the same as the in-kernel debugger.
See the
.Xr ddb 4
manual page for more information.
.Pp
Operations and facilities that require a running system, such as breakpoints,
are not supported by
.Nm crash .
.Pp
.Nm
does not provide pagination.
However, by using the pipe symbol, output may be sent to commands available
from the shell.
For example:
.Bd -literal -offset abcd
crash> ps | more
crash> ps | grep ioflush
.Ed
.Sh SEE ALSO
.Xr ddb 4 ,
.Xr ps 1 ,
.Xr vmstat 1 ,
.Xr pstat 8
.Sh HISTORY
The
.Nm
command appeared in
.Nx 6.0 .

469
usr.sbin/crash/crash.c Normal file
View File

@ -0,0 +1,469 @@
/* $NetBSD: crash.c,v 1.1 2009/03/07 22:08:08 ad Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Andrew Doran.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: crash.c,v 1.1 2009/03/07 22:08:08 ad Exp $");
#endif /* not lint */
#include <ddb/ddb.h>
#include <sys/fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <machine/frame.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <histedit.h>
#include <paths.h>
#include <kvm.h>
#include <err.h>
#include <ctype.h>
#include "extern.h"
#define MAXSTAB (16 * 1024 * 1024)
static kvm_t *kd;
db_regs_t ddb_regs;
History *hist;
HistEvent he;
EditLine *elptr;
char imgrelease[16];
FILE *ofp;
static struct nlist nl[] = {
#define X_OSRELEASE 0
{ .n_name = "_osrelease" },
#define X_PANICSTR 1
{ .n_name = "_panicstr" },
{ .n_name = NULL },
};
void
db_vprintf(const char *fmt, va_list ap)
{
char buf[1024];
int b, c;
c = vsnprintf(buf, sizeof(buf), fmt, ap);
for (b = 0; b < c; b++) {
db_putchar(buf[b]);
}
}
void
db_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
db_vprintf(fmt, ap);
va_end(ap);
}
void
db_write_bytes(db_addr_t addr, size_t size, const char *str)
{
if (kvm_write(kd, addr, str, size) != size) {
warnx("kvm_write(%p, %zd): %s", (void *)addr, size,
kvm_geterr(kd));
longjmp(db_recover);
}
}
void
db_read_bytes(db_addr_t addr, size_t size, char *str)
{
if (kvm_read(kd, addr, str, size) != size) {
warnx("kvm_read(%p, %zd): %s", (void *)addr, size,
kvm_geterr(kd));
longjmp(db_recover);
}
}
void *
db_alloc(size_t sz)
{
return malloc(sz);
}
void *
db_zalloc(size_t sz)
{
return calloc(1, sz);
}
void
db_free(void *p, size_t sz)
{
free(p);
}
static void
punt(void)
{
db_printf("This command can only be used in-kernel.\n");
}
void
db_breakpoint_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
const char *modif)
{
punt();
}
void
db_continue_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
const char *modif)
{
db_cmd_loop_done = true;
}
void
db_delete_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
const char *modif)
{
punt();
}
void
db_deletewatch_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
const char *modif)
{
punt();
}
void
db_trace_until_matching_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
const char *modif)
{
punt();
}
void
db_single_step_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
const char *modif)
{
punt();
}
void
db_trace_until_call_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
const char *modif)
{
punt();
}
void
db_watchpoint_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
const char *modif)
{
punt();
}
int
db_readline(char *lstart, int lsize)
{
const char *el;
char *pcmd;
int cnt;
db_force_whitespace();
/* Close any open pipe. */
if (ofp != stdout) {
(void)fflush(ofp);
(void)pclose(ofp);
ofp = stdout;
}
/* Read next command. */
el = el_gets(elptr, &cnt);
if (el == NULL) {
*lstart = '\0';
return 0;
}
/* Save to history, and copy to caller's buffer. */
history(hist, &he, H_ENTER, el);
strlcpy(lstart, el, lsize);
if (cnt >= lsize) {
cnt = lsize - 1;
}
lstart[cnt] = '\0';
if (cnt > 0 && lstart[cnt - 1] == '\n') {
lstart[cnt - 1] = '\0';
}
/* Need to open a pipe? If not, return now. */
pcmd = strchr(lstart, '|');
if (pcmd == NULL) {
return strlen(lstart);
}
/* Open a pipe to specified command, redirect output. */
assert(ofp == stdout);
for (*pcmd++ = '\0'; isspace((int)*pcmd); pcmd++) {
/* nothing */
}
errno = 0;
ofp = popen(pcmd, "w");
if (ofp == NULL) {
warn("opening pipe for command `%s'", pcmd);
*lstart = '\0';
}
return strlen(lstart);
}
void
db_check_interrupt(void)
{
}
int
cngetc(void)
{
fprintf(stderr, "cngetc\n");
abort();
}
void
cnputc(int c)
{
putc(c, ofp);
}
static void
usage(void)
{
fprintf(stderr,
"usage: %s [options]\n\n"
"-M mem\tspecify memory file\n"
"-N nlist\tspecify name list file (default /dev/ksyms)\n",
getprogname());
exit(EXIT_FAILURE);
}
static const char *
prompt(void)
{
return "crash> ";
}
int
main(int argc, char **argv)
{
const char *nlistf, *memf;
uintptr_t panicstr;
struct winsize ws;
struct stat sb;
size_t sz;
void *elf;
int fd, ch;
char c;
nlistf = _PATH_KSYMS;
memf = _PATH_MEM;
ofp = stdout;
/*
* Parse options.
*/
while ((ch = getopt(argc, argv, "M:N:")) != -1) {
switch (ch) {
case 'M':
memf = optarg;
break;
case 'N':
nlistf = optarg;
break;
default:
usage();
}
}
argc -= optind;
argv += optind;
/*
* Print a list of images, and allow user to select.
*/
/* XXX */
/*
* Open the images (crash dump and symbol table).
*/
kd = kvm_open(nlistf, memf, NULL, O_RDONLY, getprogname());
if (kd == NULL) {
return EXIT_FAILURE;
}
fd = open(nlistf, O_RDONLY);
if (fd < 0) {
err(EXIT_FAILURE, "open(%s)", nlistf);
}
if (fstat(fd, &sb) < 0) {
err(EXIT_FAILURE, "stat(%s)", nlistf);
}
if ((sb.st_mode & S_IFMT) != S_IFREG) { /* XXX ksyms */
sz = MAXSTAB;
elf = malloc(sz);
if (elf == NULL) {
err(EXIT_FAILURE, "malloc(%zd)", sz);
}
sz = read(fd, elf, sz);
if ((ssize_t)sz < 0) {
err(EXIT_FAILURE, "read(%s)", nlistf);
}
if (sz == MAXSTAB) {
errx(EXIT_FAILURE, "symbol table > %d bytes",
MAXSTAB);
}
} else {
sz = sb.st_size;
elf = mmap(NULL, sz, PROT_READ, MAP_FILE, fd, 0);
if (elf == MAP_FAILED) {
err(EXIT_FAILURE, "mmap(%s)", nlistf);
}
}
/*
* Print kernel & crash versions.
*/
if (kvm_nlist(kd, nl) == -1) {
errx(EXIT_FAILURE, "kvm_nlist: %s", kvm_geterr(kd));
}
if ((size_t)kvm_read(kd, nl[X_OSRELEASE].n_value, imgrelease,
sizeof(imgrelease)) != sizeof(imgrelease)) {
errx(EXIT_FAILURE, "cannot read osrelease: %s",
kvm_geterr(kd));
}
printf("Crash version %s, image version %s.\n", osrelease, imgrelease);
if (strcmp(osrelease, imgrelease) != 0) {
printf("WARNING: versions differ, you may not be able to "
"examine this image.\n");
}
/*
* Print the panic string, if any.
*/
if ((size_t)kvm_read(kd, nl[X_PANICSTR].n_value, &panicstr,
sizeof(panicstr)) != sizeof(panicstr)) {
errx(EXIT_FAILURE, "cannot read panicstr: %s",
kvm_geterr(kd));
}
if (strcmp(memf, _PATH_MEM) == 0) {
printf("Output from a running system is unreliable.\n");
} else if (panicstr == 0) {
printf("System does not appear to have panicked.\n");
} else {
printf("System panicked: ");
for (;;) {
if ((size_t)kvm_read(kd, panicstr, &c, sizeof(c)) !=
sizeof(c)) {
errx(EXIT_FAILURE, "cannot read *panicstr: %s",
kvm_geterr(kd));
}
if (c == '\0') {
break;
}
putchar(c);
panicstr++;
}
putchar('\n');
}
/*
* Initialize line editing.
*/
hist = history_init();
history(hist, &he, H_SETSIZE, 100);
elptr = el_init(getprogname(), stdin, stdout, stderr);
el_set(elptr, EL_EDITOR, "emacs");
el_set(elptr, EL_SIGNAL, 1);
el_set(elptr, EL_HIST, history, hist);
el_set(elptr, EL_PROMPT, prompt);
el_source(elptr, NULL);
/*
* Initialize ddb.
*/
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) {
db_max_width = ws.ws_col;
}
db_mach_init(kd);
ddb_init(sz, elf, (char *)elf + sz);
/*
* Debug it!
*/
db_command_loop();
/*
* Clean up and exit.
*/
if (ofp != stdout) {
(void)fflush(ofp);
(void)pclose(ofp);
ofp = stdout;
}
el_end(elptr);
history_end(hist);
exit(EXIT_SUCCESS);
/* NOTREACHED */
}

34
usr.sbin/crash/extern.h Normal file
View File

@ -0,0 +1,34 @@
/* $NetBSD: extern.h,v 1.1 2009/03/07 22:08:08 ad Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Andrew Doran.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
void db_mach_init(kvm_t *);
extern char osrelease[];

View File

@ -0,0 +1,40 @@
/* $NetBSD: unsupported.c,v 1.1 2009/03/07 22:08:08 ad Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Andrew Doran.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <err.h>
#include <stdlib.h>
int
main(int argc, char **argv)
{
errx(EXIT_FAILURE, "not yet supported on this platform");
}