26d2611a679626f23d3f1496653e294ed3dfbb95
[sbcl.git] / src / runtime / interr.c
1 /*
2  * stuff to handle internal errors
3  */
4
5 /*
6  * This software is part of the SBCL system. See the README file for
7  * more information.
8  *
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.
14  */
15
16 /*
17  * $Header$
18  */
19
20 #include <stdio.h>
21 #include <stdarg.h>
22
23 #include "arch.h"
24 #include "signal.h"
25
26 #include "runtime.h"
27 #include "sbcl.h"
28 #include "interr.h"
29 #include "print.h"
30 #include "lispregs.h"
31 \f
32 /* the way that we shut down the system on a fatal error */
33
34 static void
35 default_lossage_handler(void)
36 {
37     exit(1);
38 }
39 static void (*lossage_handler)(void) = default_lossage_handler;
40 void
41 set_lossage_handler(void handler(void))
42 {
43     lossage_handler = handler;
44 }
45
46 void
47 lose(char *fmt, ...)
48 {
49     va_list ap;
50     fprintf(stderr, "fatal error encountered in SBCL runtime system");
51     if (fmt) {
52         fprintf(stderr, ":\n");
53         va_start(ap, fmt);
54         vfprintf(stderr, fmt, ap);
55         va_end(ap);
56     }
57     fprintf(stderr, "\n");
58     fflush(stderr);
59     lossage_handler();
60 }
61 \f
62 /* internal error handler for when the Lisp error system doesn't exist
63  *
64  * FIXME: Shouldn't error output go to stderr instead of stdout? (Alas,
65  * this'd require changes in a number of things like brief_print(..),
66  * or I'd have changed it immediately.) */
67 void
68 describe_internal_error(os_context_t *context)
69 {
70     unsigned char *ptr = arch_internal_error_arguments(context);
71     int len, scoffset, sc, offset, ch;
72
73     len = *ptr++;
74     printf("internal error #%d\n", *ptr++);
75     len--;
76     while (len > 0) {
77         scoffset = *ptr++;
78         len--;
79         if (scoffset == 253) {
80             scoffset = *ptr++;
81             len--;
82         }
83         else if (scoffset == 254) {
84             scoffset = ptr[0] + ptr[1]*256;
85             ptr += 2;
86             len -= 2;
87         }
88         else if (scoffset == 255) {
89             scoffset = ptr[0] + (ptr[1]<<8) + (ptr[2]<<16) + (ptr[3]<<24);
90             ptr += 4;
91             len -= 4;
92         }
93         sc = scoffset & 0x1f;
94         offset = scoffset >> 5;
95                 
96         printf("    SC: %d, Offset: %d", sc, offset);
97         switch (sc) {
98         case sc_AnyReg:
99         case sc_DescriptorReg:
100             putchar('\t');
101             brief_print(*os_context_register_addr(context, offset));
102             break;
103
104         case sc_BaseCharReg:
105             ch = *os_context_register_addr(context, offset);
106 #ifdef __i386__
107             if (offset&1)
108                 ch = ch>>8;
109             ch = ch & 0xff;
110 #endif
111             switch (ch) {
112             case '\n': printf("\t'\\n'\n"); break;
113             case '\b': printf("\t'\\b'\n"); break;
114             case '\t': printf("\t'\\t'\n"); break;
115             case '\r': printf("\t'\\r'\n"); break;
116             default:
117                 if (ch < 32 || ch > 127)
118                     printf("\\%03o", ch);
119                 else
120                     printf("\t'%c'\n", ch);
121                 break;
122             }
123             break;
124         case sc_SapReg:
125 #ifdef sc_WordPointerReg
126         case sc_WordPointerReg:
127 #endif
128             printf("\t0x%08x\n", *os_context_register_addr(context, offset));
129             break;
130         case sc_SignedReg:
131             printf("\t%d\n", *os_context_register_addr(context, offset));
132             break;
133         case sc_UnsignedReg:
134             printf("\t%u\n", *os_context_register_addr(context, offset));
135             break;
136 #ifdef sc_SingleFloatReg
137         case sc_SingleFloatReg:
138             printf("\t%g\n", *(float *)&context->sc_fpregs[offset]);
139             break;
140 #endif
141 #ifdef sc_DoubleFloatReg
142         case sc_DoubleFloatReg:
143             printf("\t%g\n", *(double *)&context->sc_fpregs[offset]);
144             break;
145 #endif
146         default:
147             printf("\t???\n");
148             break;
149         }
150     }
151 }
152 \f
153 /* utility routines used by miscellaneous pieces of code */
154
155 lispobj debug_print(lispobj string)
156 {
157     fprintf(stderr, "%s\n", (char *)(((struct vector *)PTR(string))->data));
158     return NIL;
159 }