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"
30 #include "genesis/code.h"
33 #include "breakpoint.h"
35 /* the way that we shut down the system on a fatal error */
38 default_lossage_handler(void)
42 static void (*lossage_handler
)(void) = default_lossage_handler
;
46 configurable_lossage_handler()
48 void lisp_backtrace(int frames
);
50 if (dyndebug_config
.dyndebug_backtrace_when_lost
) {
51 fprintf(stderr
, "lose: backtrace follows as requested\n");
55 if (dyndebug_config
.dyndebug_sleep_when_lost
) {
57 "The system is too badly corrupted or confused to continue at the Lisp.\n"
58 "level. The monitor was enabled, but you requested `sleep_when_lost'\n"
59 "behaviour though dyndebug. To help with your debugging effort, this\n"
60 "thread will not enter the monitor, and instead proceed immediately to an\n"
61 "infinite sleep call, maximizing your chances that the thread's current\n"
62 "state can be preserved until you attach an external debugger. Good luck!\n");
64 # ifdef LISP_FEATURE_WIN32
71 monitor_or_something();
75 void enable_lossage_handler(void)
78 lossage_handler
= configurable_lossage_handler
;
80 lossage_handler
= monitor_or_something
;
83 void disable_lossage_handler(void)
85 lossage_handler
= default_lossage_handler
;
89 void print_message(char *fmt
, va_list ap
)
91 fprintf(stderr
, " in SBCL pid %d",getpid());
92 #if defined(LISP_FEATURE_SB_THREAD)
93 fprintf(stderr
, "(tid %lu)", (uword_t
) thread_self());
96 fprintf(stderr
, ":\n");
97 vfprintf(stderr
, fmt
, ap
);
99 fprintf(stderr
, "\n");
103 call_lossage_handler() never_returns
;
106 call_lossage_handler()
109 fprintf(stderr
, "Argh! lossage_handler() returned, total confusion..\n");
117 /* Block signals to prevent other threads, timers and such from
118 * interfering. If only all threads could be stopped somehow. */
119 block_blockable_signals(0);
120 fprintf(stderr
, "fatal error encountered");
122 print_message(fmt
, ap
);
124 fprintf(stderr
, "\n");
126 call_lossage_handler();
129 boolean lose_on_corruption_p
= 0;
132 corruption_warning_and_maybe_lose(char *fmt
, ...)
135 #ifndef LISP_FEATURE_WIN32
137 block_blockable_signals(&oldset
);
139 fprintf(stderr
, "CORRUPTION WARNING");
141 print_message(fmt
, ap
);
143 fprintf(stderr
, "The integrity of this image is possibly compromised.\n");
144 if (lose_on_corruption_p
)
145 fprintf(stderr
, "Exiting.\n");
147 fprintf(stderr
, "Continuing with fingers crossed.\n");
149 if (lose_on_corruption_p
)
150 call_lossage_handler();
151 #ifndef LISP_FEATURE_WIN32
153 thread_sigmask(SIG_SETMASK
,&oldset
,0);
157 void print_constant(os_context_t
*context
, int offset
) {
158 lispobj code
= find_code(context
);
160 struct code
*codeptr
= (struct code
*)native_pointer(code
);
161 int length
= HeaderValue(codeptr
->header
);
163 if (offset
>= length
) {
164 printf("Constant offset %d out of bounds for the code object of length %d.\n",
167 brief_print(codeptr
->constants
[offset
-
168 (offsetof(struct code
, constants
) >> WORD_SHIFT
)]);
173 char *internal_error_descriptions
[] = {INTERNAL_ERROR_NAMES
};
174 /* internal error handler for when the Lisp error system doesn't exist
176 * FIXME: Shouldn't error output go to stderr instead of stdout? (Alas,
177 * this'd require changes in a number of things like brief_print(..),
178 * or I'd have changed it immediately.) */
180 describe_internal_error(os_context_t
*context
)
182 unsigned char *ptr
= arch_internal_error_arguments(context
);
183 int len
, scoffset
, sc
, offset
, ch
;
185 #ifdef LISP_FEATURE_ARM64
186 u32 trap_instruction
= *(u32
*)ptr
;
187 unsigned code
= trap_instruction
>> 13 & 0xFF;
188 printf("Internal error #%d \"%s\" at %p\n", code
,
189 internal_error_descriptions
[code
],
190 (void*)*os_context_pc_addr(context
));
195 printf("Internal error #%d \"%s\" at %p\n", *ptr
,
196 internal_error_descriptions
[*ptr
],
197 (void*)*os_context_pc_addr(context
));
205 if (scoffset
== 253) {
209 else if (scoffset
== 254) {
210 scoffset
= ptr
[0] + ptr
[1]*256;
214 else if (scoffset
== 255) {
215 scoffset
= ptr
[0] + (ptr
[1]<<8) + (ptr
[2]<<16) + (ptr
[3]<<24);
219 sc
= scoffset
& 0x3F;
220 offset
= scoffset
>> 6;
222 printf(" SC: %d, Offset: %d", sc
, offset
);
225 case sc_DescriptorReg
:
227 brief_print(*os_context_register_addr(context
, offset
));
230 case sc_CharacterReg
:
231 ch
= *os_context_register_addr(context
, offset
);
232 #ifdef LISP_FEATURE_X86
238 case '\n': printf("\t'\\n'\n"); break;
239 case '\b': printf("\t'\\b'\n"); break;
240 case '\t': printf("\t'\\t'\n"); break;
241 case '\r': printf("\t'\\r'\n"); break;
243 if (ch
< 32 || ch
> 127)
244 printf("\\%03o", ch
);
246 printf("\t'%c'\n", ch
);
251 #ifdef sc_WordPointerReg
252 case sc_WordPointerReg
:
254 printf("\t0x%08lx\n", (unsigned long) *os_context_register_addr(context
, offset
));
257 printf("\t%ld\n", (long) *os_context_register_addr(context
, offset
));
260 printf("\t%lu\n", (unsigned long) *os_context_register_addr(context
, offset
));
262 #ifdef sc_SingleFloatReg
263 case sc_SingleFloatReg
:
264 printf("\t%g\n", *(float *)&context
->sc_fpregs
[offset
]);
267 #ifdef sc_DoubleFloatReg
268 case sc_DoubleFloatReg
:
269 printf("\t%g\n", *(double *)&context
->sc_fpregs
[offset
]);
273 print_constant(context
, offset
);
282 /* utility routines used by miscellaneous pieces of code */
284 lispobj
debug_print(lispobj string
)
286 /* This is a kludge. It's not actually safe - in general - to use
287 %primitive print on the alpha, because it skips half of the
288 number stack setup that should usually be done on a function
289 call, so the called routine (i.e. this one) ends up being able
290 to overwrite local variables in the caller. Rather than fix
291 this everywhere that %primitive print is used (it's only a
292 debugging aid anyway) we just guarantee our safety by putting
293 an unused buffer on the stack before doing anything else
296 fprintf(stderr
, "%s\n",
297 (char *)(((struct vector
*)native_pointer(string
))->data
));
298 /* shut GCC up about not using this, because that's the point.. */