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"
32 /* the way that we shut down the system on a fatal error */
35 default_lossage_handler(void)
39 static void (*lossage_handler)(void) = default_lossage_handler;
41 set_lossage_handler(void handler(void))
43 lossage_handler = handler;
50 fprintf(stderr, "fatal error encountered in SBCL pid %d",getpid());
51 /* freeze all the other threads, so we have a chance of debugging them
54 struct thread *th1,*th=arch_os_get_current_thread();
55 for_each_thread(th1) {
56 if(th1!=th) kill(th1->pid,SIGSTOP);
61 fprintf(stderr, ":\n");
63 vfprintf(stderr, fmt, ap);
66 fprintf(stderr, "\n");
69 fprintf(stderr, "Argh! lossage_handler() returned, total confusion..\n");
73 /* internal error handler for when the Lisp error system doesn't exist
75 * FIXME: Shouldn't error output go to stderr instead of stdout? (Alas,
76 * this'd require changes in a number of things like brief_print(..),
77 * or I'd have changed it immediately.) */
79 describe_internal_error(os_context_t *context)
81 unsigned char *ptr = arch_internal_error_arguments(context);
82 int len, scoffset, sc, offset, ch;
85 printf("internal error #%d\n", *ptr++);
90 if (scoffset == 253) {
94 else if (scoffset == 254) {
95 scoffset = ptr[0] + ptr[1]*256;
99 else if (scoffset == 255) {
100 scoffset = ptr[0] + (ptr[1]<<8) + (ptr[2]<<16) + (ptr[3]<<24);
104 sc = scoffset & 0x1f;
105 offset = scoffset >> 5;
107 printf(" SC: %d, Offset: %d", sc, offset);
110 case sc_DescriptorReg:
112 brief_print(*os_context_register_addr(context, offset));
116 ch = *os_context_register_addr(context, offset);
117 #ifdef LISP_FEATURE_X86
123 case '\n': printf("\t'\\n'\n"); break;
124 case '\b': printf("\t'\\b'\n"); break;
125 case '\t': printf("\t'\\t'\n"); break;
126 case '\r': printf("\t'\\r'\n"); break;
128 if (ch < 32 || ch > 127)
129 printf("\\%03o", ch);
131 printf("\t'%c'\n", ch);
136 #ifdef sc_WordPointerReg
137 case sc_WordPointerReg:
139 printf("\t0x%08lx\n", *os_context_register_addr(context, offset));
142 printf("\t%ld\n", *os_context_register_addr(context, offset));
145 printf("\t%lu\n", *os_context_register_addr(context, offset));
147 #ifdef sc_SingleFloatReg
148 case sc_SingleFloatReg:
149 printf("\t%g\n", *(float *)&context->sc_fpregs[offset]);
152 #ifdef sc_DoubleFloatReg
153 case sc_DoubleFloatReg:
154 printf("\t%g\n", *(double *)&context->sc_fpregs[offset]);
164 /* utility routines used by miscellaneous pieces of code */
166 lispobj debug_print(lispobj string)
168 /* This is a kludge. It's not actually safe - in general - to use
169 %primitive print on the alpha, because it skips half of the
170 number stack setup that should usually be done on a function call,
171 so the called routine (i.e. this one) ends up being able to overwrite
172 local variables in the caller. Rather than fix this everywhere
173 that %primitive print is used (it's only a debugging aid anyway)
174 we just put guarantee our safety by putting an unused buffer on
175 the stack before doing anything else here */
176 char untouched[32]; /* GCC warns about not using this, but that's the point.. */
177 fprintf(stderr, "%s\n",
178 (char *)(((struct vector *)native_pointer(string))->data),untouched);