0.9.3.17
[sbcl/eslaughter.git] / src / runtime / interr.c
blob4ef3766ee770f9dbde0a1ca7d0410fbdb0e4c9f0
1 /*
2 * stuff to handle internal errors
3 */
5 /*
6 * This software is part of the SBCL system. See the README file for
7 * more information.
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.
16 #include <stdio.h>
17 #include <stdarg.h>
18 #include <stdlib.h>
20 #include "sbcl.h"
21 #include "arch.h"
22 #include "signal.h"
24 #include "runtime.h"
25 #include "interr.h"
26 #include "print.h"
27 #include "lispregs.h"
28 #include "genesis/static-symbols.h"
29 #include "genesis/vector.h"
30 #include "thread.h"
32 /* the way that we shut down the system on a fatal error */
34 static void
35 default_lossage_handler(void)
37 exit(1);
39 static void (*lossage_handler)(void) = default_lossage_handler;
40 void
41 set_lossage_handler(void handler(void))
43 lossage_handler = handler;
46 never_returns
47 lose(char *fmt, ...)
49 va_list ap;
50 fprintf(stderr, "fatal error encountered in SBCL pid %d",getpid());
51 #if defined(LISP_FEATURE_SB_THREAD)
52 fprintf(stderr, "(tid %ld)",thread_self());
53 #endif
54 if (fmt) {
55 fprintf(stderr, ":\n");
56 va_start(ap, fmt);
57 vfprintf(stderr, fmt, ap);
58 va_end(ap);
60 fprintf(stderr, "\n");
61 fflush(stderr);
62 lossage_handler();
63 fprintf(stderr, "Argh! lossage_handler() returned, total confusion..\n");
64 exit(1);
67 /* internal error handler for when the Lisp error system doesn't exist
69 * FIXME: Shouldn't error output go to stderr instead of stdout? (Alas,
70 * this'd require changes in a number of things like brief_print(..),
71 * or I'd have changed it immediately.) */
72 void
73 describe_internal_error(os_context_t *context)
75 unsigned char *ptr = arch_internal_error_arguments(context);
76 int len, scoffset, sc, offset, ch;
78 len = *ptr++;
79 printf("internal error #%d\n", *ptr++);
80 len--;
81 while (len > 0) {
82 scoffset = *ptr++;
83 len--;
84 if (scoffset == 253) {
85 scoffset = *ptr++;
86 len--;
88 else if (scoffset == 254) {
89 scoffset = ptr[0] + ptr[1]*256;
90 ptr += 2;
91 len -= 2;
93 else if (scoffset == 255) {
94 scoffset = ptr[0] + (ptr[1]<<8) + (ptr[2]<<16) + (ptr[3]<<24);
95 ptr += 4;
96 len -= 4;
98 sc = scoffset & 0x1f;
99 offset = scoffset >> 5;
101 printf(" SC: %d, Offset: %d", sc, offset);
102 switch (sc) {
103 case sc_AnyReg:
104 case sc_DescriptorReg:
105 putchar('\t');
106 brief_print(*os_context_register_addr(context, offset));
107 break;
109 case sc_CharacterReg:
110 ch = *os_context_register_addr(context, offset);
111 #ifdef LISP_FEATURE_X86
112 if (offset&1)
113 ch = ch>>8;
114 ch = ch & 0xff;
115 #endif
116 switch (ch) {
117 case '\n': printf("\t'\\n'\n"); break;
118 case '\b': printf("\t'\\b'\n"); break;
119 case '\t': printf("\t'\\t'\n"); break;
120 case '\r': printf("\t'\\r'\n"); break;
121 default:
122 if (ch < 32 || ch > 127)
123 printf("\\%03o", ch);
124 else
125 printf("\t'%c'\n", ch);
126 break;
128 break;
129 case sc_SapReg:
130 #ifdef sc_WordPointerReg
131 case sc_WordPointerReg:
132 #endif
133 printf("\t0x%08lx\n", (unsigned long) *os_context_register_addr(context, offset));
134 break;
135 case sc_SignedReg:
136 printf("\t%ld\n", (long) *os_context_register_addr(context, offset));
137 break;
138 case sc_UnsignedReg:
139 printf("\t%lu\n", (unsigned long) *os_context_register_addr(context, offset));
140 break;
141 #ifdef sc_SingleFloatReg
142 case sc_SingleFloatReg:
143 printf("\t%g\n", *(float *)&context->sc_fpregs[offset]);
144 break;
145 #endif
146 #ifdef sc_DoubleFloatReg
147 case sc_DoubleFloatReg:
148 printf("\t%g\n", *(double *)&context->sc_fpregs[offset]);
149 break;
150 #endif
151 default:
152 printf("\t???\n");
153 break;
158 /* utility routines used by miscellaneous pieces of code */
160 lispobj debug_print(lispobj string)
162 /* This is a kludge. It's not actually safe - in general - to use
163 %primitive print on the alpha, because it skips half of the
164 number stack setup that should usually be done on a function
165 call, so the called routine (i.e. this one) ends up being able
166 to overwrite local variables in the caller. Rather than fix
167 this everywhere that %primitive print is used (it's only a
168 debugging aid anyway) we just guarantee our safety by putting
169 an unused buffer on the stack before doing anything else
170 here */
171 char untouched[32];
172 fprintf(stderr, "%s\n",
173 (char *)(((struct vector *)native_pointer(string))->data));
174 /* shut GCC up about not using this, because that's the point.. */
175 if (untouched);
176 return NIL;