kern/53153: RESTARTABLE_PANICS debugging option is broken
Bruce M Simpson
bms at spc.org
Fri Jun 13 00:50:21 PDT 2003
The following reply was made to PR kern/53153; it has been noted by GNATS.
From: Bruce M Simpson <bms at spc.org>
To: freebsd-gnats-submit at FreeBSD.org, bms at spc.org
Cc:
Subject: Re: kern/53153: RESTARTABLE_PANICS debugging option is broken
Date: Fri, 13 Jun 2003 08:19:13 +0100
--x+6KMIRAuhnl3hBn
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
The attached patch solves the problem.
BMS
--x+6KMIRAuhnl3hBn
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="rpanic.patch"
This is a patch to fix the notion of RESTARTABLE_PANICS in -CURRENT.
Simply removing the __dead2 attribute will break things. Instead,
offer an interface to callers which must be expressly used in order
to be able to recover from a panic. Being able to recover from a panic
can be extremely useful in the debugging cycle.
Generated by diffcoll on Fri 13 Jun 2003 08:09:55 BST
diff -uN src/sys/kern/kern_shutdown.c.orig src/sys/kern/kern_shutdown.c
--- /usr/src/sys/kern/kern_shutdown.c.orig Fri Jun 13 07:06:56 2003
+++ /usr/src/sys/kern/kern_shutdown.c Fri Jun 13 07:49:14 2003
@@ -466,19 +466,57 @@
static u_int panic_cpu = NOCPU;
#endif
+static void vpanic(int restart, const char *fmt, va_list ap);
+
+void
+panic(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vpanic(0, fmt, ap);
+ va_end(ap);
+
+ /* honour __dead2 attribute, even when vpanic() can return. */
+ for (;;)
+ ;
+}
+
+#if defined(RESTARTABLE_PANICS)
+/*
+ * A restartable panic will only take place if the
+ * caller specifically requests one by using this
+ * entry point, so as to avoid breaking existing
+ * consumers of the panic() interface.
+ */
+void
+rpanic(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vpanic(1, fmt, ap);
+ va_end(ap);
+}
+#endif /* RESTARTABLE_PANICS */
+
/*
* Panic is called on unresolvable fatal errors. It prints "panic: mesg",
* and then reboots. If we are called twice, then we avoid trying to sync
* the disks as this often leads to recursive panics.
*
+ * Panics may be recovered from, if the caller specifically requests
+ * one by calling rpanic(). This interface is used to avoid breaking
+ * existing code which can't deal with the semantic of a restartable
+ * panic.
+ *
* MPSAFE
*/
-void
-panic(const char *fmt, ...)
+static void
+vpanic(int restart, const char *fmt, va_list ap)
{
struct thread *td = curthread;
int bootopt, newpanic;
- va_list ap;
static char buf[256];
#ifdef SMP
@@ -504,11 +542,9 @@
newpanic = 1;
}
- va_start(ap, fmt);
(void)vsnprintf(buf, sizeof(buf), fmt, ap);
if (panicstr == fmt)
panicstr = buf;
- va_end(ap);
printf("panic: %s\n", buf);
#ifdef SMP
/* two separate prints in case of an unmapped page and trap */
@@ -527,7 +563,7 @@
Debugger ("panic");
#ifdef RESTARTABLE_PANICS
/* See if the user aborted the panic, in which case we continue. */
- if (panicstr == NULL) {
+ if (restart && panicstr == NULL) {
#ifdef SMP
atomic_store_rel_int(&panic_cpu, NOCPU);
#endif
diff -uN src/sys/sys/systm.h.orig src/sys/sys/systm.h
--- /usr/src/sys/sys/systm.h.orig Mon Jun 9 21:15:44 2003
+++ /usr/src/sys/sys/systm.h Fri Jun 13 07:59:02 2003
@@ -132,11 +132,12 @@
void *hashinit(int count, struct malloc_type *type, u_long *hashmask);
void *phashinit(int count, struct malloc_type *type, u_long *nentries);
-#ifdef RESTARTABLE_PANICS
-void panic(const char *, ...) __printflike(1, 2);
-#else
void panic(const char *, ...) __dead2 __printflike(1, 2);
-#endif
+#if defined(RESTARTABLE_PANICS)
+void rpanic(const char *, ...) __printflike(1, 2);
+#else
+#define rpanic(format, args...) panic(format, args)
+#endif /* RESTARTABLE_PANICS */
void backtrace(void);
void cpu_boot(int);
diff -uN src/share/man/man9/panic.9.orig src/share/man/man9/panic.9
--- /usr/src/share/man/man9/panic.9.orig Fri Jun 13 07:21:49 2003
+++ /usr/src/share/man/man9/panic.9 Fri Jun 13 08:09:48 2003
@@ -41,6 +41,10 @@
.In sys/param.h
.Ft void
.Fn panic "const char *fmt" ...
+.Ft void
+.Fn rpanic "const char *fmt" ...
+.Pp
+.Nm options RESTARTABLE_PANICS
.Sh DESCRIPTION
The
.Fn panic
@@ -53,6 +57,20 @@
is set to the address of the message text for retrieval from the OS
core dump.
.Pp
+If the
+.Nm RESTARTABLE_PANICS
+option is defined in the kernel, then the
+.Fn rpanic
+function provides the notion of a "recoverable panic". Callers must
+specifically use this interface in order for the
+.Fn panic
+to be recoverable, so as to avoid breaking existing code.
+.Pp
+If the option is not defined, then
+.Fn rpanic
+behaves identically to
+.Fn panic .
+.Pp
If the kernel debugger is installed control is passed to it, otherwise
an attempt to save a core dump of the OS to a configured dump device
is made.
@@ -64,4 +82,6 @@
.Sh RETURN VALUES
The
.Fn panic
-function does not return.
+function does not return. The
+.Fn rpanic
+function may return, but has no return value.
--x+6KMIRAuhnl3hBn--
More information about the freebsd-bugs
mailing list