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