Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 03 Aug 2001 12:32:16 -0700 (PDT)
From:      John Baldwin <jhb@FreeBSD.org>
To:        hackers@FreeBSD.org
Subject:   [PATCH] [BIKESHED] Restarting from panic
Message-ID:  <XFMail.010803123216.jhb@FreeBSD.org>

next in thread | raw e-mail | index | archive | help
I have the following simple and untested patch that I know a few people have
asked for.  It allows you to restart from a panic and continue executing rather
than dumping to the disk and executing.  This is remotely useful when doing
kernel development when one adds an assertion that ends up being wrong or an
assertion fails that isn't really critical in this case, thus, we want to
continue executing.  Granted, for some panics this can be quite dangerous as
some assertions do things like make sure pointers aren't NULL before we
dereference them.  I'm aware that this is a very efficient foot-shooting
implement with limited usefulness.  To activate the feature, reset the panicstr
variable to NULL from DDB and then do a continue.  The panic function will then
reset the panic state and bail out before calling boot().  The patch is at
http://www.FreeBSD.org/~jhb/patches/panic.patch and included below:

Index: kern_shutdown.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/kern_shutdown.c,v
retrieving revision 1.102
diff -u -r1.102 kern_shutdown.c
--- kern_shutdown.c     2001/06/25 18:30:42     1.102
+++ kern_shutdown.c     2001/08/03 19:20:54
@@ -565,12 +565,17 @@
        static char buf[256];
 
 #ifdef SMP
-       /* Only 1 CPU can panic at a time */
-       if (panic_cpu != PCPU_GET(cpuid) &&
-           atomic_cmpset_int(&panic_cpu, NOCPU, PCPU_GET(cpuid)) == 0) {
-               for (;;)
-                       ; /* nothing */
-       }
+       /*
+        * We don't want multiple CPU's to panic at the same time, so we
+        * use panic_cpu as a simple spinlock.  We have to keep checking
+        * panic_cpu if we are spinning in case the panic on the first
+        * CPU is canceled.
+        */
+       if (panic_cpu != PCPU_GET(cpuid))
+               while (atomic_cmpset_int(&panic_cpu, NOCPU,
+                   PCPU_GET(cpuid)) == 0)
+                       while (panic_cpu != NOCPU)
+                               ; /* nothing */
 #endif
 
        bootopt = RB_AUTOBOOT | RB_DUMP;
@@ -596,6 +601,13 @@
 #if defined(DDB)
        if (debugger_on_panic)
                Debugger ("panic");
+       /* See if the user aborted the panic, in which case we continue. */
+       if (panicstr == NULL) {
+#ifdef SMP
+               atomic_store_rel_int(&panic_cpu, NOCPU);
+#endif
+               return;
+       }
 #endif
        boot(bootopt);
 }

As Peter would say, *donning peril-sensitive sunglasses...*

-- 

John Baldwin <jhb@FreeBSD.org> -- http://www.FreeBSD.org/~jhb/
PGP Key: http://www.baldwin.cx/~john/pgpkey.asc
"Power Users Use the Power to Serve!"  -  http://www.FreeBSD.org/

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?XFMail.010803123216.jhb>