From 5cfc11977fc09cfb6a95f3d9d485deb147b8f7d3 Mon Sep 17 00:00:00 2001 From: David Lichteblau Date: Tue, 11 Sep 2012 13:37:21 +0200 Subject: [PATCH] Add dyndebug flags backtrace_when_lost, sleep_when_lost 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 | 35 +++++++++++++++++++++++++++++++++++ src/runtime/print.c | 11 +++++++++-- src/runtime/runtime.h | 2 ++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/runtime/interr.c b/src/runtime/interr.c index 2187fd8..22cbc2a 100644 --- a/src/runtime/interr.c +++ b/src/runtime/interr.c @@ -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) { diff --git a/src/runtime/print.c b/src/runtime/print.c index e50da2e..9a7a3c6 100644 --- a/src/runtime/print.c +++ b/src/runtime/print.c @@ -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]); + } } } diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 4fb9539..186f296 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -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 -- 1.7.10.4