2 * stuff to handle internal errors
6 * This software is part of the SBCL system. See the README file for
9 * This software is derived from the CMU CL system, which was
10 * written at Carnegie Mellon University and released into the
11 * public domain. The software is in the public domain and is
12 * provided with absolutely no warranty. See the COPYING and CREDITS
13 * files for more information.
28 #include "genesis/static-symbols.h"
29 #include "genesis/vector.h"
33 /* the way that we shut down the system on a fatal error */
36 default_lossage_handler(void)
40 static void (*lossage_handler)(void) = default_lossage_handler;
44 configurable_lossage_handler()
46 void lisp_backtrace(int frames);
48 if (dyndebug_config.dyndebug_backtrace_when_lost) {
49 fprintf(stderr, "lose: backtrace follows as requested\n");
53 if (dyndebug_config.dyndebug_sleep_when_lost) {
55 "The system is too badly corrupted or confused to continue at the Lisp.\n"
56 "level. The monitor was enabled, but you requested `sleep_when_lost'\n"
57 "behaviour though dyndebug. To help with your debugging effort, this\n"
58 "thread will not enter the monitor, and instead proceed immediately to an\n"
59 "infinite sleep call, maximizing your chances that the thread's current\n"
60 "state can be preserved until you attach an external debugger. Good luck!\n");
62 # ifdef LISP_FEATURE_WIN32
69 monitor_or_something();
73 void enable_lossage_handler(void)
76 lossage_handler = configurable_lossage_handler;
78 lossage_handler = monitor_or_something;
81 void disable_lossage_handler(void)
83 lossage_handler = default_lossage_handler;
87 void print_message(char *fmt, va_list ap)
89 fprintf(stderr, " in SBCL pid %d",getpid());
90 #if defined(LISP_FEATURE_SB_THREAD)
91 fprintf(stderr, "(tid %lu)", (unsigned long) thread_self());
94 fprintf(stderr, ":\n");
95 vfprintf(stderr, fmt, ap);
97 fprintf(stderr, "\n");
101 call_lossage_handler() never_returns;
104 call_lossage_handler()
107 fprintf(stderr, "Argh! lossage_handler() returned, total confusion..\n");
115 /* Block signals to prevent other threads, timers and such from
116 * interfering. If only all threads could be stopped somehow. */
117 block_blockable_signals(0, 0);
118 fprintf(stderr, "fatal error encountered");
120 print_message(fmt, ap);
122 fprintf(stderr, "\n");
124 call_lossage_handler();
127 boolean lose_on_corruption_p = 0;
130 corruption_warning_and_maybe_lose(char *fmt, ...)
133 #ifndef LISP_FEATURE_WIN32
135 block_blockable_signals(0, &oldset);
137 fprintf(stderr, "CORRUPTION WARNING");
139 print_message(fmt, ap);
141 fprintf(stderr, "The integrity of this image is possibly compromised.\n");
142 if (lose_on_corruption_p)
143 fprintf(stderr, "Exiting.\n");
145 fprintf(stderr, "Continuing with fingers crossed.\n");
147 if (lose_on_corruption_p)
148 call_lossage_handler();
149 #ifndef LISP_FEATURE_WIN32
151 thread_sigmask(SIG_SETMASK,&oldset,0);
155 char *internal_error_descriptions[] = {INTERNAL_ERROR_NAMES};
156 /* internal error handler for when the Lisp error system doesn't exist
158 * FIXME: Shouldn't error output go to stderr instead of stdout? (Alas,
159 * this'd require changes in a number of things like brief_print(..),
160 * or I'd have changed it immediately.) */
162 describe_internal_error(os_context_t *context)
164 unsigned char *ptr = arch_internal_error_arguments(context);
165 int len, scoffset, sc, offset, ch;
168 printf("internal error #%d (%s)\n", *ptr,
169 internal_error_descriptions[*ptr]);
175 if (scoffset == 253) {
179 else if (scoffset == 254) {
180 scoffset = ptr[0] + ptr[1]*256;
184 else if (scoffset == 255) {
185 scoffset = ptr[0] + (ptr[1]<<8) + (ptr[2]<<16) + (ptr[3]<<24);
189 sc = scoffset & 0x1f;
190 offset = scoffset >> 5;
192 printf(" SC: %d, Offset: %d", sc, offset);
195 case sc_DescriptorReg:
197 brief_print(*os_context_register_addr(context, offset));
200 case sc_CharacterReg:
201 ch = *os_context_register_addr(context, offset);
202 #ifdef LISP_FEATURE_X86
208 case '\n': printf("\t'\\n'\n"); break;
209 case '\b': printf("\t'\\b'\n"); break;
210 case '\t': printf("\t'\\t'\n"); break;
211 case '\r': printf("\t'\\r'\n"); break;
213 if (ch < 32 || ch > 127)
214 printf("\\%03o", ch);
216 printf("\t'%c'\n", ch);
221 #ifdef sc_WordPointerReg
222 case sc_WordPointerReg:
224 printf("\t0x%08lx\n", (unsigned long) *os_context_register_addr(context, offset));
227 printf("\t%ld\n", (long) *os_context_register_addr(context, offset));
230 printf("\t%lu\n", (unsigned long) *os_context_register_addr(context, offset));
232 #ifdef sc_SingleFloatReg
233 case sc_SingleFloatReg:
234 printf("\t%g\n", *(float *)&context->sc_fpregs[offset]);
237 #ifdef sc_DoubleFloatReg
238 case sc_DoubleFloatReg:
239 printf("\t%g\n", *(double *)&context->sc_fpregs[offset]);
249 /* utility routines used by miscellaneous pieces of code */
251 lispobj debug_print(lispobj string)
253 /* This is a kludge. It's not actually safe - in general - to use
254 %primitive print on the alpha, because it skips half of the
255 number stack setup that should usually be done on a function
256 call, so the called routine (i.e. this one) ends up being able
257 to overwrite local variables in the caller. Rather than fix
258 this everywhere that %primitive print is used (it's only a
259 debugging aid anyway) we just guarantee our safety by putting
260 an unused buffer on the stack before doing anything else
263 fprintf(stderr, "%s\n",
264 (char *)(((struct vector *)native_pointer(string))->data));
265 /* shut GCC up about not using this, because that's the point.. */