#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 */
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
-never_returns
-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 %ld)",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,
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++;
{
/* This is a kludge. It's not actually safe - in general - to use
%primitive print on the alpha, because it skips half of the
- number stack setup that should usually be done on a function call,
- so the called routine (i.e. this one) ends up being able to overwrite
- local variables in the caller. Rather than fix this everywhere
- that %primitive print is used (it's only a debugging aid anyway)
- we just put guarantee our safety by putting an unused buffer on
- the stack before doing anything else here */
- char untouched[32]; /* GCC warns about not using this, but that's the point.. */
+ number stack setup that should usually be done on a function
+ call, so the called routine (i.e. this one) ends up being able
+ to overwrite local variables in the caller. Rather than fix
+ this everywhere that %primitive print is used (it's only a
+ debugging aid anyway) we just guarantee our safety by putting
+ an unused buffer on the stack before doing anything else
+ here */
+ char untouched[32];
fprintf(stderr, "%s\n",
- (char *)(((struct vector *)native_pointer(string))->data),untouched);
+ (char *)(((struct vector *)native_pointer(string))->data));
+ /* shut GCC up about not using this, because that's the point.. */
+ (void)untouched;
return NIL;
}