Skip to content
Snippets Groups Projects
Commit fd790e77 authored by wlott's avatar wlott
Browse files

Random fixes: find the initial CONT from the signal context instead of

assuming that CSP and CONT are the same.

Deal correctly with functions terminating both by calling the undefined
function and hitting error traps.

Print info from same frame on same line instead of mixing frames.
parent df560ee3
No related branches found
No related tags found
No related merge requests found
/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/ldb/Attic/backtrace.c,v 1.1 1990/04/04 18:26:27 ch Exp $
/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/ldb/Attic/backtrace.c,v 1.2 1990/04/05 00:45:06 wlott Exp $
*
* Simple backtrace facility. More or less from Rob's lisp version.
*/
#include <stdio.h>
#include <signal.h>
#include "ldb.h"
#include "lisp.h"
#include "globals.h"
#include "interrupt.h"
#include "lispregs.h"
/* Sigh ... I know what the call frame looks like and it had
better not change. */
......@@ -16,6 +20,13 @@ struct call_frame {
lispobj other_state[6];
};
struct call_info {
struct call_frame *frame;
struct code *code;
lispobj lra;
int pc; /* Note: this is the trace file offset, not the actual pc. */
};
#define HEADER_LENGTH(header) ((header)>>8)
static struct code *
......@@ -23,7 +34,7 @@ code_pointer(object)
lispobj object;
{
lispobj *headerp, header;
int type;
int type, len;
headerp = (lispobj *) PTR(object);
header = *headerp;
......@@ -35,10 +46,14 @@ lispobj object;
case type_ReturnPcHeader:
case type_FunctionHeader:
case type_ClosureFunctionHeader:
headerp -= HEADER_LENGTH(header);
len = HEADER_LENGTH(header);
if (len == 0)
headerp = NULL;
else
headerp -= len;
break;
default:
return (struct code *) 0;
headerp = NULL;
}
return (struct code *) headerp;
......@@ -48,7 +63,23 @@ static
struct call_frame *
current_cont()
{
return ((struct call_frame *) current_control_stack_pointer) - 1;
int free;
free = SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX)>>2;
if (free == 0)
return NULL;
else {
struct sigcontext *csp;
struct call_frame *cont;
csp = lisp_interrupt_contexts[free-1];
cont = (struct call_frame *)csp->sc_regs[CONT];
if ((lispobj *)cont == current_control_stack_pointer)
/* We were attempting to call an undefined function. */
;
return cont;
}
}
static
......@@ -59,71 +90,114 @@ struct call_frame *pointer;
((char *) pointer < (char *) current_control_stack_pointer));
}
static void
info_from_sigcontext(info, csp)
struct call_info *info;
struct sigcontext *csp;
{
unsigned long pc;
if (csp->sc_regs[CONT] == csp->sc_regs[CSP]) {
/* We were attempting to call an undefined function. */
info->frame = (struct call_frame *)csp->sc_regs[OLDCONT];
info->lra = (lispobj)csp->sc_regs[LRA];
info->code = code_pointer(info->lra);
pc = (unsigned long)PTR(info->lra);
}
else {
info->frame = (struct call_frame *)csp->sc_regs[CONT];
info->code = code_pointer(csp->sc_regs[CODE]);
info->lra = 0;
pc = csp->sc_pc;
}
info->pc = (pc - (unsigned long) info->code) / sizeof(lispobj) - HEADER_LENGTH(info->code->header);
}
static int
previous_info(info)
struct call_info *info;
{
if (!cs_valid_pointer_p(info->frame)) {
printf("Bogus callee value (0x%08x).\n", (unsigned long)info->frame);
return 0;
}
info->lra = info->frame->saved_lra;
info->frame = info->frame->old_cont;
if (info->frame == NULL)
return 0;
info->code = code_pointer(info->lra);
info->pc = ((unsigned long)PTR(info->lra) - (unsigned long) info->code) / sizeof(lispobj) - HEADER_LENGTH(info->code->header);
return 1;
}
void
backtrace(nframes)
int nframes;
{
struct call_frame *callee;
callee = current_cont();
while ((callee != (struct call_frame *) 0) && (nframes-- > 0)) {
struct call_frame *caller;
lispobj lra;
struct code *code;
if (!cs_valid_pointer_p(callee)) {
printf("Bogus callee value (0x%08x).\n",
(unsigned long) callee);
return;
}
if (callee->old_cont == (struct call_frame *) 0)
return;
lra = callee->saved_lra;
code = code_pointer(lra);
printf("<Frame 0x%08x, CODE: 0x%08x, ",
(unsigned long) callee, (unsigned long) code);
if (code != (struct code *) 0) {
lispobj function;
function = code->entry_points;
while (function != NIL) {
struct function_header *header;
lispobj name;
header = (struct function_header *) PTR(function);
name = header->name;
if (LowtagOf(name) == type_OtherPointer) {
lispobj *object;
object = (lispobj *) PTR(name);
if (TypeOf(*object) == type_SymbolHeader) {
struct symbol *symbol;
symbol = (struct symbol *) object;
object = (lispobj *) PTR(symbol->name);
}
if (TypeOf(*object) == type_SimpleString) {
struct vector *string;
string = (struct vector *) object;
printf("%s, ", (char *) string->data);
} else
printf("(Not simple string???), ");
} else
printf("(Not other pointer???), ");
function = header->next;
}
}
printf("LRA: 0x%08x, PC: 0x%04x>\n",
lra, (PTR(lra) - (lispobj) code) / sizeof(lispobj));
callee = callee->old_cont;
}
struct call_info info;
int free;
free = SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX)>>2;
if (free == 0) {
printf("Nothing to backtrace.\n");
return;
}
info_from_sigcontext(&info, lisp_interrupt_contexts[free-1]);
do {
printf("<Frame 0x%08x, CODE: 0x%08x, ",
(unsigned long) info.frame,
(unsigned long) info.code);
if (info.code != (struct code *) 0) {
lispobj function;
function = info.code->entry_points;
while (function != NIL) {
struct function_header *header;
lispobj name;
header = (struct function_header *) PTR(function);
name = header->name;
if (LowtagOf(name) == type_OtherPointer) {
lispobj *object;
object = (lispobj *) PTR(name);
if (TypeOf(*object) == type_SymbolHeader) {
struct symbol *symbol;
symbol = (struct symbol *) object;
object = (lispobj *) PTR(symbol->name);
}
if (TypeOf(*object) == type_SimpleString) {
struct vector *string;
string = (struct vector *) object;
printf("%s, ", (char *) string->data);
} else
printf("(Not simple string???), ");
} else
printf("(Not other pointer???), ");
function = header->next;
}
}
if (info.lra != 0)
printf("LRA: 0x%08x, ", (unsigned long)info.lra);
else
printf("<no LRA>, ");
printf("PC: %d\n", info.pc);
} while (--nframes > 0 && previous_info(&info));
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment