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;
42 void enable_lossage_handler(void)
44 lossage_handler = monitor_or_something;
46 void disable_lossage_handler(void)
48 lossage_handler = default_lossage_handler;
52 void print_message(char *fmt, va_list ap)
54 fprintf(stderr, " in SBCL pid %d",getpid());
55 #if defined(LISP_FEATURE_SB_THREAD)
56 fprintf(stderr, "(tid %lu)", (unsigned long) thread_self());
59 fprintf(stderr, ":\n");
60 vfprintf(stderr, fmt, ap);
62 fprintf(stderr, "\n");
66 call_lossage_handler() never_returns;
69 call_lossage_handler()
72 fprintf(stderr, "Argh! lossage_handler() returned, total confusion..\n");
80 /* Block signals to prevent other threads, timers and such from
81 * interfering. If only all threads could be stopped somehow. */
82 block_blockable_signals(0, 0);
83 fprintf(stderr, "fatal error encountered");
85 print_message(fmt, ap);
87 fprintf(stderr, "\n");
89 call_lossage_handler();
92 boolean lose_on_corruption_p = 0;
95 corruption_warning_and_maybe_lose(char *fmt, ...)
98 #ifndef LISP_FEATURE_WIN32
100 block_blockable_signals(0, &oldset);
102 fprintf(stderr, "CORRUPTION WARNING");
104 print_message(fmt, ap);
106 fprintf(stderr, "The integrity of this image is possibly compromised.\n");
107 if (lose_on_corruption_p)
108 fprintf(stderr, "Exiting.\n");
110 fprintf(stderr, "Continuing with fingers crossed.\n");
112 if (lose_on_corruption_p)
113 call_lossage_handler();
114 #ifndef LISP_FEATURE_WIN32
116 thread_sigmask(SIG_SETMASK,&oldset,0);
120 char *internal_error_descriptions[] = {INTERNAL_ERROR_NAMES};
121 /* internal error handler for when the Lisp error system doesn't exist
123 * FIXME: Shouldn't error output go to stderr instead of stdout? (Alas,
124 * this'd require changes in a number of things like brief_print(..),
125 * or I'd have changed it immediately.) */
127 describe_internal_error(os_context_t *context)
129 unsigned char *ptr = arch_internal_error_arguments(context);
130 int len, scoffset, sc, offset, ch;
133 printf("internal error #%d (%s)\n", *ptr,
134 internal_error_descriptions[*ptr]);
140 if (scoffset == 253) {
144 else if (scoffset == 254) {
145 scoffset = ptr[0] + ptr[1]*256;
149 else if (scoffset == 255) {
150 scoffset = ptr[0] + (ptr[1]<<8) + (ptr[2]<<16) + (ptr[3]<<24);
154 sc = scoffset & 0x1f;
155 offset = scoffset >> 5;
157 printf(" SC: %d, Offset: %d", sc, offset);
160 case sc_DescriptorReg:
162 brief_print(*os_context_register_addr(context, offset));
165 case sc_CharacterReg:
166 ch = *os_context_register_addr(context, offset);
167 #ifdef LISP_FEATURE_X86
173 case '\n': printf("\t'\\n'\n"); break;
174 case '\b': printf("\t'\\b'\n"); break;
175 case '\t': printf("\t'\\t'\n"); break;
176 case '\r': printf("\t'\\r'\n"); break;
178 if (ch < 32 || ch > 127)
179 printf("\\%03o", ch);
181 printf("\t'%c'\n", ch);
186 #ifdef sc_WordPointerReg
187 case sc_WordPointerReg:
189 printf("\t0x%08lx\n", (unsigned long) *os_context_register_addr(context, offset));
192 printf("\t%ld\n", (long) *os_context_register_addr(context, offset));
195 printf("\t%lu\n", (unsigned long) *os_context_register_addr(context, offset));
197 #ifdef sc_SingleFloatReg
198 case sc_SingleFloatReg:
199 printf("\t%g\n", *(float *)&context->sc_fpregs[offset]);
202 #ifdef sc_DoubleFloatReg
203 case sc_DoubleFloatReg:
204 printf("\t%g\n", *(double *)&context->sc_fpregs[offset]);
214 /* utility routines used by miscellaneous pieces of code */
216 lispobj debug_print(lispobj string)
218 /* This is a kludge. It's not actually safe - in general - to use
219 %primitive print on the alpha, because it skips half of the
220 number stack setup that should usually be done on a function
221 call, so the called routine (i.e. this one) ends up being able
222 to overwrite local variables in the caller. Rather than fix
223 this everywhere that %primitive print is used (it's only a
224 debugging aid anyway) we just guarantee our safety by putting
225 an unused buffer on the stack before doing anything else
228 fprintf(stderr, "%s\n",
229 (char *)(((struct vector *)native_pointer(string))->data));
230 /* shut GCC up about not using this, because that's the point.. */