From bms@spc.org  Tue Jun 10 10:33:55 2003
Return-Path: <bms@spc.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 4F51137B401
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 10 Jun 2003 10:33:55 -0700 (PDT)
Received: from bigboy.spc.org (dolly.good1.com [195.206.69.225])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 484EC43FDF
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 10 Jun 2003 10:33:52 -0700 (PDT)
	(envelope-from bms@spc.org)
Received: from saboteur.dek.spc.org (unknown [81.3.72.84])
	by bigboy.spc.org (Postfix) with ESMTP id C974D32B6
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 10 Jun 2003 18:37:54 +0100 (BST)
Received: by saboteur.dek.spc.org (Postfix, from userid 1001)
	id 592B16C1; Mon,  9 Jun 2003 21:47:22 +0100 (BST)
Message-Id: <20030609204722.592B16C1@saboteur.dek.spc.org>
Date: Mon,  9 Jun 2003 21:47:22 +0100 (BST)
From: Bruce M Simpson <bms@spc.org>
Reply-To: Bruce M Simpson <bms@spc.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: RESTARTABLE_PANICS debugging option is broken
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         53153
>Category:       kern
>Synopsis:       RESTARTABLE_PANICS debugging option is broken
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jun 10 10:40:10 PDT 2003
>Closed-Date:    Mon Jul 21 11:32:43 PDT 2003
>Last-Modified:  Mon Jul 21 11:32:43 PDT 2003
>Originator:     Bruce M Simpson
>Release:        FreeBSD 5.1-RELEASE i386
>Organization:
>Environment:
System: FreeBSD saboteur.dek.spc.org 5.1-RELEASE FreeBSD 5.1-RELEASE #0: Mon Jun 9 16:25:10 BST 2003 root@saboteur.dek.spc.org:/usr/src/sys/i386/compile/SABOTEUR i386


	
>Description:
	Including the RESTARTABLE_PANICS option in a kernel compile
	results in multiple errors of the following kind:
		xxxx might be used uninitialized in this function
	where xxxx is one of the first variables in the function.

	Affected functions have the following properties:
	1) they call panic()
	2) they have a non-void return value

	Here is a list of the affected files:
	src/sys/dev/ppbus/ppb_msq.c
	src/sys/fs/devfs/devfs_devs.c
	src/sys/fs/msdosfs/msdosfs_vnops.c
	src/sys/kern/kern_intr.c
	src/sys/kern/subr_bus.c
	src/sys/kern/uipc_usrreq.c
	src/sys/kern/vfs_default.c
	src/sys/netinet6/ip6_output.c
	src/sys/netinet6/ipsec.c
	src/sys/netinet6/nd6.c
	src/sys/ufs/ffs/ffs_alloc.c
	src/sys/ufs/ffs/ffs_softdep.c
	src/sys/vm/uma_core.c
	src/sys/i386/i386/elf_machdep.c
	src/sys/i386/i386/vm86.c

	We have to agree on how to resolve this. Either RESTARTABLE_PANICS
	should be removed outright, or a misleading prototype would have
	to be declared (continue to advertise it with __dead2 in
	<sys/systm.h>, when it can in fact return). A kludge would have
	to be implemented in kern_shutdown.c.

	Otherwise all callers of panic() have to be changed to handle the
	'panic() can return' case.

>How-To-Repeat:
	
>Fix:

	


>Release-Note:
>Audit-Trail:

From: Bruce M Simpson <bms@spc.org>
To: freebsd-gnats-submit@FreeBSD.org, bms@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--

From: Bruce M Simpson <bms@spc.org>
To: freebsd-gnats-submit@FreeBSD.org, bms@spc.org
Cc:  
Subject: Re: kern/53153: RESTARTABLE_PANICS debugging option is broken
Date: Fri, 13 Jun 2003 08:12:48 +0100

 --Pgaa2uWPnPrfixyx
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 The attached patch solves the problem.
 
 BMS
 
 --Pgaa2uWPnPrfixyx
 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.
 
 
 --Pgaa2uWPnPrfixyx--
State-Changed-From-To: open->closed 
State-Changed-By: jhb 
State-Changed-When: Mon Jul 21 11:30:19 PDT 2003 
State-Changed-Why:  
After discussion with the submitter, we reached consensus that 
RESTARTABLE_PANICS is intentionally obtuse, and developers wishing to use it 
should use NO_WERROR or some such when using it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=53153 
>Unformatted:
