Fix cut-to-width in the presence of bad constants in dead code.
[sbcl.git] / src / runtime / interr.c
index 9238601..889d644 100644 (file)
@@ -28,6 +28,7 @@
 #include "genesis/static-symbols.h"
 #include "genesis/vector.h"
 #include "thread.h"
+#include "monitor.h"
 \f
 /* the way that we shut down the system on a fatal error */
 
@@ -37,33 +38,121 @@ default_lossage_handler(void)
     exit(1);
 }
 static void (*lossage_handler)(void) = default_lossage_handler;
-void
-set_lossage_handler(void handler(void))
+
+#if QSHOW
+static void
+configurable_lossage_handler()
 {
-    lossage_handler = 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
-lose(char *fmt, ...)
+void enable_lossage_handler(void)
 {
-    va_list ap;
-    fprintf(stderr, "fatal error encountered in SBCL pid %d",getpid());
+#if QSHOW
+    lossage_handler = configurable_lossage_handler;
+#else
+    lossage_handler = monitor_or_something;
+#endif
+}
+void disable_lossage_handler(void)
+{
+    lossage_handler = default_lossage_handler;
+}
+
+static
+void print_message(char *fmt, va_list ap)
+{
+    fprintf(stderr, " in SBCL pid %d",getpid());
 #if defined(LISP_FEATURE_SB_THREAD)
-    fprintf(stderr, "(tid %lu)",thread_self());
+    fprintf(stderr, "(tid %lu)", (uword_t) thread_self());
 #endif
     if (fmt) {
         fprintf(stderr, ":\n");
-        va_start(ap, fmt);
         vfprintf(stderr, fmt, ap);
-        va_end(ap);
     }
     fprintf(stderr, "\n");
-    fflush(stderr);
+}
+
+static inline void
+call_lossage_handler() never_returns;
+
+static inline void
+call_lossage_handler()
+{
     lossage_handler();
     fprintf(stderr, "Argh! lossage_handler() returned, total confusion..\n");
     exit(1);
 }
+
+void
+lose(char *fmt, ...)
+{
+    va_list ap;
+    /* Block signals to prevent other threads, timers and such from
+     * interfering. If only all threads could be stopped somehow. */
+    block_blockable_signals(0, 0);
+    fprintf(stderr, "fatal error encountered");
+    va_start(ap, fmt);
+    print_message(fmt, ap);
+    va_end(ap);
+    fprintf(stderr, "\n");
+    fflush(stderr);
+    call_lossage_handler();
+}
+
+boolean lose_on_corruption_p = 0;
+
+void
+corruption_warning_and_maybe_lose(char *fmt, ...)
+{
+    va_list ap;
+#ifndef LISP_FEATURE_WIN32
+    sigset_t oldset;
+    block_blockable_signals(0, &oldset);
+#endif
+    fprintf(stderr, "CORRUPTION WARNING");
+    va_start(ap, fmt);
+    print_message(fmt, ap);
+    va_end(ap);
+    fprintf(stderr, "The integrity of this image is possibly compromised.\n");
+    if (lose_on_corruption_p)
+        fprintf(stderr, "Exiting.\n");
+    else
+        fprintf(stderr, "Continuing with fingers crossed.\n");
+    fflush(stderr);
+    if (lose_on_corruption_p)
+        call_lossage_handler();
+#ifndef LISP_FEATURE_WIN32
+    else
+        thread_sigmask(SIG_SETMASK,&oldset,0);
+#endif
+}
 \f
+char *internal_error_descriptions[] = {INTERNAL_ERROR_NAMES};
 /* internal error handler for when the Lisp error system doesn't exist
  *
  * FIXME: Shouldn't error output go to stderr instead of stdout? (Alas,
@@ -76,7 +165,9 @@ describe_internal_error(os_context_t *context)
     int len, scoffset, sc, offset, ch;
 
     len = *ptr++;
-    printf("internal error #%d\n", *ptr++);
+    printf("internal error #%d (%s)\n", *ptr,
+           internal_error_descriptions[*ptr]);
+    ptr++;
     len--;
     while (len > 0) {
         scoffset = *ptr++;
@@ -172,6 +263,6 @@ lispobj debug_print(lispobj string)
     fprintf(stderr, "%s\n",
             (char *)(((struct vector *)native_pointer(string))->data));
     /* shut GCC up about not using this, because that's the point.. */
-    if (untouched);
+    (void)untouched;
     return NIL;
 }