Add dyndebug flags backtrace_when_lost, sleep_when_lost
authorDavid Lichteblau <david@lichteblau.com>
Tue, 11 Sep 2012 11:37:21 +0000 (13:37 +0200)
committerDavid Lichteblau <david@lichteblau.com>
Tue, 11 Sep 2012 12:42:51 +0000 (14:42 +0200)
Available when :SB-QSHOW is enabled, these settings can be enabled
through the SBCL_DYNDEBUG environment variable to customize SBCL's
behaviour prior to entry to ldb.

With backtrace_when_lost, lossage shows a backtrace before
continuing with the lossage handler as usual.  (Thanks to Dmitry
Kalyanov for this idea, here committed as a dyndebug option.)

With sleep_when_lost activated, the monitor is preempted, and SBCL
will instead cease to do anything except for a OS-level sleep call.
This behaviour has proven useful in preserving a failing thread's
current state until an external debugger can be attached.

src/runtime/interr.c
src/runtime/print.c
src/runtime/runtime.h

index 2187fd8..22cbc2a 100644 (file)
@@ -39,9 +39,44 @@ default_lossage_handler(void)
 }
 static void (*lossage_handler)(void) = default_lossage_handler;
 
+#if QSHOW
+static void
+configurable_lossage_handler()
+{
+    void lisp_backtrace(int frames);
+
+    if (dyndebug_config.dyndebug_backtrace_when_lost) {
+        fprintf(stderr, "lose: backtrace follows as requested\n");
+        lisp_backtrace(100);
+    }
+
+    if (dyndebug_config.dyndebug_sleep_when_lost) {
+        fprintf(stderr,
+"The system is too badly corrupted or confused to continue at the Lisp.\n"
+"level.  The monitor was enabled, but you requested `sleep_when_lost'\n"
+"behaviour though dyndebug.  To help with your debugging effort, this\n"
+"thread will not enter the monitor, and instead proceed immediately to an\n"
+"infinite sleep call, maximizing your chances that the thread's current\n"
+"state can be preserved until you attach an external debugger. Good luck!\n");
+        for (;;)
+#         ifdef LISP_FEATURE_WIN32
+            Sleep(10000);
+#         else
+            sleep(10);
+#         endif
+    }
+
+    monitor_or_something();
+}
+#endif
+
 void enable_lossage_handler(void)
 {
+#if QSHOW
+    lossage_handler = configurable_lossage_handler;
+#else
     lossage_handler = monitor_or_something;
+#endif
 }
 void disable_lossage_handler(void)
 {
index e50da2e..9a7a3c6 100644 (file)
@@ -69,6 +69,10 @@ dyndebug_init()
     dyndebug_init1(misc,           "MISC");
     dyndebug_init1(pagefaults,     "PAGEFAULTS");
 
+    int n_output_flags = n;
+    dyndebug_init1(backtrace_when_lost, "BACKTRACE_WHEN_LOST");
+    dyndebug_init1(sleep_when_lost,     "SLEEP_WHEN_LOST");
+
     if (n != DYNDEBUG_NFLAGS)
         fprintf(stderr, "Bug in dyndebug_init\n");
 
@@ -84,7 +88,7 @@ dyndebug_init()
             if (!token) break;
             unsigned i;
             if (!strcmp(token, "all"))
-                for (i = 0; i < DYNDEBUG_NFLAGS; i++)
+                for (i = 0; i < n_output_flags; i++)
                     *ptrs[i] = 1;
             else {
                 for (i = 0; i < DYNDEBUG_NFLAGS; i++)
@@ -104,8 +108,11 @@ dyndebug_init()
             fprintf(stderr, "Valid flags are:\n");
             fprintf(stderr, "  all  ;enables all of the following:\n");
             unsigned i;
-            for (i = 0; i < DYNDEBUG_NFLAGS; i++)
+            for (i = 0; i < DYNDEBUG_NFLAGS; i++) {
+                if (i == n_output_flags)
+                    fprintf(stderr, "Additional options:\n");
                 fprintf(stderr, "  %s\n", names[i]);
+            }
         }
     }
 
index 4fb9539..186f296 100644 (file)
@@ -113,6 +113,8 @@ extern struct dyndebug_config {
     int dyndebug_seh;
     int dyndebug_misc;
     int dyndebug_pagefaults;
+    int dyndebug_backtrace_when_lost;
+    int dyndebug_sleep_when_lost;
 } dyndebug_config;
 
 #ifdef LISP_FEATURE_GENCGC