2 * simple backtrace facility
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.
26 #include "interrupt.h"
31 /* KLUDGE: Sigh ... I know what the call frame looks like and it had
32 * better not change. */
36 struct call_frame *old_cont;
42 lispobj other_state[5];
47 struct call_frame *frame;
58 int pc; /* Note: this is the trace file offset, not the actual pc. */
61 #define HEADER_LENGTH(header) ((header)>>8)
63 static int previous_info(struct call_info *info);
66 code_pointer(lispobj object)
68 lispobj *headerp, header;
71 headerp = (lispobj *) PTR(object);
73 type = TypeOf(header);
78 case type_ReturnPcHeader:
79 case type_FunctionHeader:
80 case type_ClosureFunctionHeader:
81 len = HEADER_LENGTH(header);
91 return (struct code *) headerp;
95 cs_valid_pointer_p(struct call_frame *pointer)
97 return (((char *) control_stack <= (char *) pointer) &&
98 ((char *) pointer < (char *) current_control_stack_pointer));
102 call_info_from_lisp_state(struct call_info *info)
104 info->frame = (struct call_frame *)current_control_frame_pointer;
105 info->interrupted = 0;
114 call_info_from_context(struct call_info *info, os_context_t *context)
118 info->interrupted = 1;
119 if (LowtagOf(*os_context_register_addr(context, reg_CODE))
120 == type_FunctionPointer) {
121 /* We tried to call a function, but crapped out before $CODE could
122 * be fixed up. Probably an undefined function. */
124 (struct call_frame *)(*os_context_register_addr(context,
126 info->lra = (lispobj)(*os_context_register_addr(context, reg_LRA));
127 info->code = code_pointer(info->lra);
128 pc = (unsigned long)PTR(info->lra);
132 (struct call_frame *)(*os_context_register_addr(context, reg_CFP));
134 code_pointer(*os_context_register_addr(context, reg_CODE));
136 pc = *os_context_pc_addr(context);
138 if (info->code != NULL)
139 info->pc = pc - (unsigned long) info->code -
141 (HEADER_LENGTH(info->code->header) * sizeof(lispobj));
143 (HEADER_LENGTH(((struct code *)info->code)->header) * sizeof(lispobj));
150 previous_info(struct call_info *info)
152 struct call_frame *this_frame;
155 if (!cs_valid_pointer_p(info->frame)) {
156 printf("Bogus callee value (0x%08x).\n", (unsigned long)info->frame);
160 this_frame = info->frame;
161 info->lra = this_frame->saved_lra;
162 info->frame = this_frame->old_cont;
163 info->interrupted = 0;
165 if (info->frame == NULL || info->frame == this_frame)
168 if (info->lra == NIL) {
169 /* We were interrupted. Find the correct signal context. */
170 free = SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX)>>2;
172 os_context_t *context =
173 lisp_interrupt_contexts[free];
174 if ((struct call_frame *)(*os_context_register_addr(context,
177 call_info_from_context(info, context);
183 info->code = code_pointer(info->lra);
184 if (info->code != NULL)
185 info->pc = (unsigned long)PTR(info->lra) -
186 (unsigned long)info->code -
188 (HEADER_LENGTH(info->code->header) * sizeof(lispobj));
190 (HEADER_LENGTH(((struct code *)info->code)->header) * sizeof(lispobj));
200 backtrace(int nframes)
202 struct call_info info;
204 call_info_from_lisp_state(&info);
207 printf("<Frame 0x%08x%s, ", (unsigned long) info.frame,
208 info.interrupted ? " [interrupted]" : "");
210 if (info.code != (struct code *) 0) {
213 printf("CODE: 0x%08X, ", (unsigned long) info.code | type_OtherPointer);
216 function = info.code->entry_points;
218 function = ((struct code *)info.code)->entry_points;
220 while (function != NIL) {
221 struct function *header;
224 header = (struct function *) PTR(function);
227 if (LowtagOf(name) == type_OtherPointer) {
230 object = (lispobj *) PTR(name);
232 if (TypeOf(*object) == type_SymbolHeader) {
233 struct symbol *symbol;
235 symbol = (struct symbol *) object;
236 object = (lispobj *) PTR(symbol->name);
238 if (TypeOf(*object) == type_SimpleString) {
239 struct vector *string;
241 string = (struct vector *) object;
242 printf("%s, ", (char *) string->data);
244 printf("(Not simple string??\?), ");
246 printf("(Not other pointer??\?), ");
249 function = header->next;
253 printf("CODE: ???, ");
256 printf("LRA: 0x%08x, ", (unsigned long)info.lra);
258 printf("<no LRA>, ");
261 printf("PC: 0x%x>\n", info.pc);
263 printf("PC: ??\?>\n");
265 } while (--nframes > 0 && previous_info(&info));
271 backtrace(int nframes)
273 printf("Can't backtrace on this hardware platform.\n");