X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Finterr.c;h=f7da2d3670b32bf839fa579e796f55cfc6b7b349;hb=1b32a547d26cf078ba9f2948edeb27ff91e78f49;hp=b8a863f5077f23c59c4f2c39ab9737c38d281d52;hpb=81cfdf526490d642c73602ebac9bcacb8af644e1;p=sbcl.git diff --git a/src/runtime/interr.c b/src/runtime/interr.c index b8a863f..f7da2d3 100644 --- a/src/runtime/interr.c +++ b/src/runtime/interr.c @@ -15,15 +15,20 @@ #include #include +#include +#include "sbcl.h" #include "arch.h" #include "signal.h" #include "runtime.h" -#include "sbcl.h" #include "interr.h" #include "print.h" #include "lispregs.h" +#include "genesis/static-symbols.h" +#include "genesis/vector.h" +#include "thread.h" +#include "monitor.h" /* the way that we shut down the system on a fatal error */ @@ -33,29 +38,84 @@ default_lossage_handler(void) exit(1); } static void (*lossage_handler)(void) = default_lossage_handler; -void -set_lossage_handler(void handler(void)) + +void enable_lossage_handler(void) { - lossage_handler = handler; + lossage_handler = monitor_or_something; +} +void disable_lossage_handler(void) +{ + lossage_handler = default_lossage_handler; } -never_returns -lose(char *fmt, ...) +static +void print_message(char *fmt, va_list ap) { - va_list ap; - fprintf(stderr, "fatal error encountered in SBCL runtime system"); + fprintf(stderr, " in SBCL pid %d",getpid()); +#if defined(LISP_FEATURE_SB_THREAD) + fprintf(stderr, "(tid %lu)", (unsigned long) thread_self()); +#endif if (fmt) { - fprintf(stderr, ":\n"); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); + fprintf(stderr, ":\n"); + vfprintf(stderr, fmt, 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(); + 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; + thread_sigmask(SIG_BLOCK, &blockable_sigset, &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 +} /* internal error handler for when the Lisp error system doesn't exist * @@ -72,79 +132,79 @@ describe_internal_error(os_context_t *context) printf("internal error #%d\n", *ptr++); len--; while (len > 0) { - scoffset = *ptr++; - len--; - if (scoffset == 253) { - scoffset = *ptr++; - len--; - } - else if (scoffset == 254) { - scoffset = ptr[0] + ptr[1]*256; - ptr += 2; - len -= 2; - } - else if (scoffset == 255) { - scoffset = ptr[0] + (ptr[1]<<8) + (ptr[2]<<16) + (ptr[3]<<24); - ptr += 4; - len -= 4; - } - sc = scoffset & 0x1f; - offset = scoffset >> 5; - - printf(" SC: %d, Offset: %d", sc, offset); - switch (sc) { - case sc_AnyReg: - case sc_DescriptorReg: - putchar('\t'); - brief_print(*os_context_register_addr(context, offset)); - break; - - case sc_BaseCharReg: - ch = *os_context_register_addr(context, offset); -#ifdef __i386__ - if (offset&1) - ch = ch>>8; - ch = ch & 0xff; + scoffset = *ptr++; + len--; + if (scoffset == 253) { + scoffset = *ptr++; + len--; + } + else if (scoffset == 254) { + scoffset = ptr[0] + ptr[1]*256; + ptr += 2; + len -= 2; + } + else if (scoffset == 255) { + scoffset = ptr[0] + (ptr[1]<<8) + (ptr[2]<<16) + (ptr[3]<<24); + ptr += 4; + len -= 4; + } + sc = scoffset & 0x1f; + offset = scoffset >> 5; + + printf(" SC: %d, Offset: %d", sc, offset); + switch (sc) { + case sc_AnyReg: + case sc_DescriptorReg: + putchar('\t'); + brief_print(*os_context_register_addr(context, offset)); + break; + + case sc_CharacterReg: + ch = *os_context_register_addr(context, offset); +#ifdef LISP_FEATURE_X86 + if (offset&1) + ch = ch>>8; + ch = ch & 0xff; #endif - switch (ch) { - case '\n': printf("\t'\\n'\n"); break; - case '\b': printf("\t'\\b'\n"); break; - case '\t': printf("\t'\\t'\n"); break; - case '\r': printf("\t'\\r'\n"); break; - default: - if (ch < 32 || ch > 127) - printf("\\%03o", ch); - else - printf("\t'%c'\n", ch); - break; - } - break; - case sc_SapReg: + switch (ch) { + case '\n': printf("\t'\\n'\n"); break; + case '\b': printf("\t'\\b'\n"); break; + case '\t': printf("\t'\\t'\n"); break; + case '\r': printf("\t'\\r'\n"); break; + default: + if (ch < 32 || ch > 127) + printf("\\%03o", ch); + else + printf("\t'%c'\n", ch); + break; + } + break; + case sc_SapReg: #ifdef sc_WordPointerReg - case sc_WordPointerReg: + case sc_WordPointerReg: #endif - printf("\t0x%08x\n", *os_context_register_addr(context, offset)); - break; - case sc_SignedReg: - printf("\t%d\n", *os_context_register_addr(context, offset)); - break; - case sc_UnsignedReg: - printf("\t%u\n", *os_context_register_addr(context, offset)); - break; + printf("\t0x%08lx\n", (unsigned long) *os_context_register_addr(context, offset)); + break; + case sc_SignedReg: + printf("\t%ld\n", (long) *os_context_register_addr(context, offset)); + break; + case sc_UnsignedReg: + printf("\t%lu\n", (unsigned long) *os_context_register_addr(context, offset)); + break; #ifdef sc_SingleFloatReg - case sc_SingleFloatReg: - printf("\t%g\n", *(float *)&context->sc_fpregs[offset]); - break; + case sc_SingleFloatReg: + printf("\t%g\n", *(float *)&context->sc_fpregs[offset]); + break; #endif #ifdef sc_DoubleFloatReg - case sc_DoubleFloatReg: - printf("\t%g\n", *(double *)&context->sc_fpregs[offset]); - break; + case sc_DoubleFloatReg: + printf("\t%g\n", *(double *)&context->sc_fpregs[offset]); + break; #endif - default: - printf("\t???\n"); - break; - } + default: + printf("\t???\n"); + break; + } } } @@ -152,16 +212,19 @@ describe_internal_error(os_context_t *context) lispobj debug_print(lispobj string) { - /* This is a kludge. It's not actually safe - in general - to use + /* 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 */ + 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); + fprintf(stderr, "%s\n", + (char *)(((struct vector *)native_pointer(string))->data)); + /* shut GCC up about not using this, because that's the point.. */ + (void)untouched; return NIL; }