*** empty log message ***
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@936 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
e8d40d8f09
commit
8cd58c6cf1
9 changed files with 956 additions and 216 deletions
|
|
@ -1,14 +1,34 @@
|
||||||
|
|
||||||
SRCS = stab.c elf.c object.c init.c segment.c signal.c
|
SRCS = default.c stack.c stab.c elf.c object.c init.c segment.c signal.c
|
||||||
OBJS = stab.o elf.o object.o signal.o segment.o init.o main.o
|
OBJS = default.o stack.o stab.o elf.o object.o signal.o segment.o init.o main.o
|
||||||
INCLUDE = -I../Include
|
INCLUDE = -I../Include
|
||||||
|
|
||||||
|
PYINCLUDE = -I/usr/local/include/python2.0
|
||||||
|
TCLINCLUDE = -I/usr/local/include
|
||||||
|
|
||||||
all::
|
all::
|
||||||
CC -Kpic -c $(INCLUDE) main.cxx
|
CC -Kpic -c $(INCLUDE) main.cxx
|
||||||
cc -c $(INCLUDE) $(SRCS)
|
cc -c $(INCLUDE) $(SRCS)
|
||||||
CC -G $(OBJS) -o libwad.so
|
CC -G $(OBJS) -o libwad.so
|
||||||
cp libwad.so ..
|
cp libwad.so ..
|
||||||
|
|
||||||
|
python::
|
||||||
|
cc -c $(INCLUDE) $(SRCS)
|
||||||
|
CC -Kpic -c $(INCLUDE) $(PYINCLUDE) wadpy.cxx
|
||||||
|
CC -G $(OBJS) wadpy.o -o wadmodule.so
|
||||||
|
cp wadmodule.so libwadpy.so
|
||||||
|
cp libwadpy.so ..
|
||||||
|
|
||||||
|
tcl::
|
||||||
|
cc -c $(INCLUDE) $(SRCS)
|
||||||
|
CC -Kpic -c $(INCLUDE) $(TCLINCLUDE) wadtcl.cxx
|
||||||
|
CC -G $(OBJS) wadtcl.o -o wad.so
|
||||||
|
cp wad.so libwadtcl.so
|
||||||
|
cp libwadtcl.so ..
|
||||||
|
|
||||||
|
debug::
|
||||||
|
cc -g debug.c $(INCLUDE) -L. -R. -lwad
|
||||||
|
|
||||||
wc::
|
wc::
|
||||||
wc $(SRCS)
|
wc $(SRCS)
|
||||||
|
|
||||||
|
|
|
||||||
237
SWIG/Tools/WAD/Wad/default.c
Normal file
237
SWIG/Tools/WAD/Wad/default.c
Normal file
|
|
@ -0,0 +1,237 @@
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* default.c
|
||||||
|
*
|
||||||
|
* Default signal handler. Just prints a stack trace and returns.
|
||||||
|
*
|
||||||
|
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000. The University of Chicago
|
||||||
|
* See the file LICENSE for information on usage and redistribution.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include "wad.h"
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* This function tries to produce some kind of sensible argument
|
||||||
|
string for a stack frame. If no debugging information is available,
|
||||||
|
we'll just dump the %i0-%i5 registers in hex. If debugging information
|
||||||
|
is available, we'll try to do something a little more sensible */
|
||||||
|
|
||||||
|
char *wad_arg_string(WadFrame *frame) {
|
||||||
|
static char str[1024];
|
||||||
|
static char temp[64];
|
||||||
|
WadParm *wp;
|
||||||
|
long *stack;
|
||||||
|
long *nextstack;
|
||||||
|
int i;
|
||||||
|
WadFrame *nf;
|
||||||
|
|
||||||
|
if (frame->size)
|
||||||
|
nf = (WadFrame *) (((char *) frame) + frame->size);
|
||||||
|
else
|
||||||
|
nf = 0;
|
||||||
|
|
||||||
|
if (nf)
|
||||||
|
nextstack = STACK(nf);
|
||||||
|
else
|
||||||
|
nextstack = 0;
|
||||||
|
|
||||||
|
str[0] = 0;
|
||||||
|
stack = STACK(frame);
|
||||||
|
|
||||||
|
if (frame->nargs < 0) {
|
||||||
|
/* No argument information is available. In this case
|
||||||
|
we will simply dump the %in registers. (assuming we can
|
||||||
|
find them) */
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++) {
|
||||||
|
sprintf(temp,"0x%x", stack[8+i]);
|
||||||
|
strcat(str,temp);
|
||||||
|
if (i < 5)
|
||||||
|
strcat(str,",");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* We were able to get some argument information out the debugging table */
|
||||||
|
wp = ARGUMENTS(frame);
|
||||||
|
for (i = 0; i < frame->nargs; i++, wp++) {
|
||||||
|
strcat(str,wp->name);
|
||||||
|
strcat(str,"=");
|
||||||
|
|
||||||
|
/* Try to figure out where the value is */
|
||||||
|
if ((wp->loc == PARM_STACK) && nf) {
|
||||||
|
/* Parameter is located on the call stack */
|
||||||
|
unsigned long argloc = wp->value; /* Location relative to frame pointer */
|
||||||
|
if ((argloc & 0x3) == 0) {
|
||||||
|
/* Is word aligned, make some kind of attempt to print this out */
|
||||||
|
unsigned long *p = (unsigned long *) (((char *) nextstack) + argloc);
|
||||||
|
sprintf(temp,"0x%x", *p);
|
||||||
|
strcat(str,temp);
|
||||||
|
}
|
||||||
|
} else if (wp->loc == PARM_REGISTER) {
|
||||||
|
if ((wp->value >= 24) && (wp->value < 32)) {
|
||||||
|
/* Value is located in the %in registers */
|
||||||
|
sprintf(temp,"0x%x", stack[wp->value - 16]);
|
||||||
|
strcat(str,temp);
|
||||||
|
} else if ((wp->value >= 8) && (wp->value < 16)) {
|
||||||
|
/* Value is located in the %on registers */
|
||||||
|
sprintf(temp,"0x%x", frame->regs[wp->value]);
|
||||||
|
strcat(str,temp);
|
||||||
|
} else if ((wp->value >= 16) && (wp->value < 24)) {
|
||||||
|
/* Value has been placed in the %ln registers */
|
||||||
|
sprintf(temp,"0x%x", frame->regs[wp->value - 16]);
|
||||||
|
strcat(str,temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i < (frame->nargs-1)) strcat(str,",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *wad_strip_dir(char *name) {
|
||||||
|
char *c;
|
||||||
|
c = name + strlen(name);
|
||||||
|
while (c != name) {
|
||||||
|
if (*c == '/') {
|
||||||
|
c++;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
c--;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *src_file = 0;
|
||||||
|
static int src_len = 0;
|
||||||
|
|
||||||
|
/* Opens up a source file and tries to locate a specific line number */
|
||||||
|
|
||||||
|
char *wad_load_source(char *path, int line) {
|
||||||
|
int fd;
|
||||||
|
char *c;
|
||||||
|
char *start;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
fd = open(path, O_RDONLY);
|
||||||
|
if (fd < 0) return 0;
|
||||||
|
src_len = lseek(fd, 0, SEEK_END);
|
||||||
|
lseek(fd,0,SEEK_SET);
|
||||||
|
src_file = (char *)mmap(NULL,src_len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||||
|
if (src_file == MAP_FAILED) {
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
n = 0;
|
||||||
|
start = src_file;
|
||||||
|
c = src_file;
|
||||||
|
while (n < src_len) {
|
||||||
|
if (*c == '\n') {
|
||||||
|
line--;
|
||||||
|
if (line == 0) {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
start = c+1;
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
munmap(src_file,src_len);
|
||||||
|
src_file = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wad_release_source() {
|
||||||
|
if (src_file)
|
||||||
|
munmap(src_file,src_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* Default callback
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void wad_default_callback(int signo, WadFrame *framedata, char *ret) {
|
||||||
|
char *fd;
|
||||||
|
WadFrame *f;
|
||||||
|
WadFrame *fline = 0;
|
||||||
|
|
||||||
|
switch(signo) {
|
||||||
|
case SIGSEGV:
|
||||||
|
printf("Segmentation fault.\n");
|
||||||
|
break;
|
||||||
|
case SIGBUS:
|
||||||
|
printf("Bus error.\n");
|
||||||
|
break;
|
||||||
|
case SIGABRT:
|
||||||
|
printf("Abort.\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Signal %d\n", signo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fd = (char *) framedata;
|
||||||
|
f = (WadFrame *) fd;
|
||||||
|
|
||||||
|
/* Find the last exception frame */
|
||||||
|
|
||||||
|
while (!f->last) {
|
||||||
|
fd = fd + f->size;
|
||||||
|
f = (WadFrame *) fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now work backwards */
|
||||||
|
fd = fd - f->lastsize;
|
||||||
|
f = (WadFrame *) fd;
|
||||||
|
while (1) {
|
||||||
|
printf("#%-3d 0x%08x in %s(%s)", f->frameno, f->pc, *(fd + f->sym_off) ? fd+f->sym_off : "?",
|
||||||
|
wad_arg_string(f));
|
||||||
|
if (strlen(fd+f->src_off)) {
|
||||||
|
printf(" in '%s'", wad_strip_dir(fd+f->src_off));
|
||||||
|
if (f->line_number > 0) {
|
||||||
|
printf(", line %d", f->line_number);
|
||||||
|
fline = f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (strlen(fd+f->obj_off)) {
|
||||||
|
printf(" from '%s'", fd+f->obj_off);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
if (!f->lastsize) break;
|
||||||
|
fd = fd - f->lastsize;
|
||||||
|
f = (WadFrame *) fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fline) {
|
||||||
|
int first;
|
||||||
|
int last;
|
||||||
|
char *line, *c;
|
||||||
|
int i;
|
||||||
|
first = fline->line_number - 2;
|
||||||
|
last = fline->line_number + 2;
|
||||||
|
if (first < 1) first = 1;
|
||||||
|
|
||||||
|
line = wad_load_source(SRCFILE(fline),first);
|
||||||
|
if (line) {
|
||||||
|
printf("\n%s, line %d\n\n", SRCFILE(fline),fline->line_number);
|
||||||
|
for (i = first; i <= last; i++) {
|
||||||
|
if (i == fline->line_number) printf(" => ");
|
||||||
|
else printf(" ");
|
||||||
|
c = strchr(line,'\n');
|
||||||
|
if (c) {
|
||||||
|
*c = 0;
|
||||||
|
printf("%s\n",line);
|
||||||
|
*c = '\n';
|
||||||
|
} else {
|
||||||
|
printf("%s\n",line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
line = c+1;
|
||||||
|
}
|
||||||
|
wad_release_source();
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wad_release_trace();
|
||||||
|
}
|
||||||
|
|
@ -307,7 +307,7 @@ wad_elf_debug_info(WadObject *wo, char *symbol, unsigned long offset) {
|
||||||
wd = wad_debug_info(wo1,symbol,offset);
|
wd = wad_debug_info(wo1,symbol,offset);
|
||||||
wad_object_release(wo1);
|
wad_object_release(wo1);
|
||||||
} else {
|
} else {
|
||||||
printf("couldn't load %s\n", objfile);
|
/* printf("couldn't load %s\n", objfile); */
|
||||||
}
|
}
|
||||||
if (!wd) return wad_search_stab(stab,stabsize,stabstr,symbol,offset);
|
if (!wd) return wad_search_stab(stab,stabsize,stabstr,symbol,offset);
|
||||||
return wd;
|
return wd;
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ wad_segment_find(wadaddr_t addr) {
|
||||||
read_segment = 0;
|
read_segment = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
n = read(fd,&pmap,sizeof(prmap_t));
|
n = read(fd,&pmap,sizeof(prmap_t));
|
||||||
if (n < 0) break;
|
if (n <= 0) break;
|
||||||
offset += n;
|
offset += n;
|
||||||
if ((addr >= (wadaddr_t) pmap.pr_vaddr) && (addr <= (wadaddr_t) (pmap.pr_vaddr + pmap.pr_size))) {
|
if ((addr >= (wadaddr_t) pmap.pr_vaddr) && (addr <= (wadaddr_t) (pmap.pr_vaddr + pmap.pr_size))) {
|
||||||
strncpy(segment.mapname, pmap.pr_mapname, MAX_PATH);
|
strncpy(segment.mapname, pmap.pr_mapname, MAX_PATH);
|
||||||
|
|
|
||||||
|
|
@ -15,72 +15,6 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
static char *strip_dir(char *name) {
|
|
||||||
char *c;
|
|
||||||
c = name + strlen(name);
|
|
||||||
while (c != name) {
|
|
||||||
if (*c == '/') {
|
|
||||||
c++;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
c--;
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
|
||||||
* Default callback
|
|
||||||
* ----------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
void wad_default_callback(int signo, void *framedata) {
|
|
||||||
char *fd;
|
|
||||||
WadFrame *f;
|
|
||||||
switch(signo) {
|
|
||||||
case SIGSEGV:
|
|
||||||
printf("Segmentation fault.\n");
|
|
||||||
break;
|
|
||||||
case SIGBUS:
|
|
||||||
printf("Bus error.\n");
|
|
||||||
break;
|
|
||||||
case SIGABRT:
|
|
||||||
printf("Abort.\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("Signal %d\n", signo);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fd = (char *) framedata;
|
|
||||||
f = (WadFrame *) fd;
|
|
||||||
while (f->size) {
|
|
||||||
printf("#%-3d 0x%08x in %s()", f->frameno, f->pc, *(fd + f->sym_off) ? fd+f->sym_off : "?");
|
|
||||||
if (strlen(fd+f->src_off)) {
|
|
||||||
printf(" in '%s'", strip_dir(fd+f->src_off));
|
|
||||||
if (f->line_number >= 0) {
|
|
||||||
printf(", line %d", f->line_number);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (strlen(fd+f->obj_off)) {
|
|
||||||
printf(" from '%s'", fd+f->obj_off);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
fd = fd + f->size;
|
|
||||||
f = (WadFrame *) fd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Perform one level of stack unwinding */
|
|
||||||
unsigned long *stack_unwind(unsigned long *sp) {
|
|
||||||
unsigned long *new_sp;
|
|
||||||
unsigned long ret_addr;
|
|
||||||
int i;
|
|
||||||
new_sp = (unsigned long *) *(sp+14);
|
|
||||||
ret_addr = *(sp+15);
|
|
||||||
return (unsigned long *) new_sp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Data structures for containing information about non-local returns */
|
/* Data structures for containing information about non-local returns */
|
||||||
|
|
||||||
typedef struct nonlocal {
|
typedef struct nonlocal {
|
||||||
|
|
@ -100,9 +34,9 @@ void wad_set_return(char *name, long value) {
|
||||||
return_points = nl;
|
return_points = nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void (*sig_callback)(int signo, void *data) = 0;
|
static void (*sig_callback)(int signo, WadFrame *data, char *ret) = 0;
|
||||||
|
|
||||||
void wad_set_callback(void (*s)(int,void *)) {
|
void wad_set_callback(void (*s)(int,WadFrame *,char *ret)) {
|
||||||
sig_callback = s;
|
sig_callback = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,6 +51,11 @@ static int nlr_levels = 0;
|
||||||
static int *volatile nlr_p = &nlr_levels;
|
static int *volatile nlr_p = &nlr_levels;
|
||||||
static long nlr_value = 0;
|
static long nlr_value = 0;
|
||||||
|
|
||||||
|
/* Set the return value from another module */
|
||||||
|
void wad_set_return_value(long value) {
|
||||||
|
nlr_value = value;
|
||||||
|
}
|
||||||
|
|
||||||
static void nonlocalret() {
|
static void nonlocalret() {
|
||||||
long a;
|
long a;
|
||||||
|
|
||||||
|
|
@ -147,37 +86,19 @@ static void nonlocalret() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
||||||
int current;
|
|
||||||
greg_t *pc;
|
greg_t *pc;
|
||||||
greg_t *npc;
|
greg_t *npc;
|
||||||
greg_t *ret;
|
|
||||||
greg_t *sp;
|
greg_t *sp;
|
||||||
int i;
|
unsigned long addr;
|
||||||
unsigned long *user_fp;
|
|
||||||
unsigned long *addr;
|
|
||||||
ucontext_t *context;
|
ucontext_t *context;
|
||||||
unsigned long *p_sp; /* process stack pointer */
|
unsigned long p_sp; /* process stack pointer */
|
||||||
unsigned long *p_pc; /* Process program counter */
|
unsigned long p_pc; /* Process program counter */
|
||||||
WadSegment *ws;
|
int nlevels = 0;
|
||||||
WadObject *wo;
|
|
||||||
int nlevels;
|
|
||||||
int found = 0;
|
int found = 0;
|
||||||
void _returnsignal();
|
void _returnsignal();
|
||||||
int n = 0;
|
WadFrame *frame, *origframe;
|
||||||
char framefile[256];
|
char *framedata;
|
||||||
int ffile;
|
char *retname = 0;
|
||||||
WadFrame frame;
|
|
||||||
void *framedata;
|
|
||||||
int fsize = 0; /* Total frame size */
|
|
||||||
sprintf(framefile,"/tmp/wad.%d", getpid());
|
|
||||||
|
|
||||||
/* Open the output file for the traceback */
|
|
||||||
|
|
||||||
ffile = open(framefile, O_CREAT | O_TRUNC | O_WRONLY, 0644);
|
|
||||||
|
|
||||||
if (ffile < 0) {
|
|
||||||
printf("can't open %s\n", framefile);
|
|
||||||
}
|
|
||||||
|
|
||||||
context = (ucontext_t *) vcontext;
|
context = (ucontext_t *) vcontext;
|
||||||
|
|
||||||
|
|
@ -185,103 +106,44 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
||||||
pc = &((context->uc_mcontext).gregs[REG_PC]);
|
pc = &((context->uc_mcontext).gregs[REG_PC]);
|
||||||
npc = &((context->uc_mcontext).gregs[REG_nPC]);
|
npc = &((context->uc_mcontext).gregs[REG_nPC]);
|
||||||
sp = &((context->uc_mcontext).gregs[REG_SP]);
|
sp = &((context->uc_mcontext).gregs[REG_SP]);
|
||||||
ret = &((context->uc_mcontext).gregs[REG_O7]);
|
|
||||||
|
|
||||||
/* Get some information out of the signal handler stack */
|
/* Get some information out of the signal handler stack */
|
||||||
user_fp = (unsigned long *) _get_fp(); /* Current frame pointer */
|
addr = (unsigned long) si->si_addr;
|
||||||
addr = (unsigned long *) si->si_addr;
|
p_pc = (unsigned long) (*pc);
|
||||||
|
p_sp = (unsigned long) (*sp);
|
||||||
|
|
||||||
/* Try to do a stack traceback */
|
frame = wad_stack_trace(p_pc, p_sp, 0);
|
||||||
nlevels = 0;
|
origframe =frame;
|
||||||
p_pc = (unsigned long *) (*pc);
|
if (!frame) {
|
||||||
p_sp = (unsigned long *) (*sp);
|
/* We're really hosed here */
|
||||||
|
return;
|
||||||
while (p_pc) {
|
|
||||||
ws = wad_segment_find((wadaddr_t) p_pc);
|
|
||||||
if (!ws) {
|
|
||||||
printf("No segment found for %x\n", p_pc);
|
|
||||||
} else {
|
|
||||||
WadObject *wo;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
int symsize = 0; /* Symbol size */
|
|
||||||
int srcsize = 0;
|
|
||||||
int objsize = 0;
|
|
||||||
char *srcname = 0;
|
|
||||||
char *objname = 0;
|
|
||||||
char *symname = 0;
|
|
||||||
int pad = 0;
|
|
||||||
|
|
||||||
unsigned long value;
|
|
||||||
wo = wad_object_load(ws->mappath);
|
|
||||||
if (strcmp(ws->mapname,"a.out") == 0) ws->vaddr= 0;
|
|
||||||
name = wad_find_symbol(wo,(void *) p_pc, (unsigned long) ws->vaddr, &value);
|
|
||||||
|
|
||||||
/* Build up some information about the exception frame */
|
|
||||||
frame.frameno = n;
|
|
||||||
frame.pc = (long) p_pc;
|
|
||||||
frame.sp = (long) p_sp;
|
|
||||||
n++;
|
|
||||||
if (name) {
|
|
||||||
nonlocal *nl;
|
|
||||||
symsize = strlen(name)+1;
|
|
||||||
symname = name;
|
|
||||||
nl = return_points;
|
|
||||||
while (nl) {
|
|
||||||
if (strcmp(name,nl->symname) == 0) {
|
|
||||||
found = 1;
|
|
||||||
nlr_value = nl->value;
|
|
||||||
}
|
|
||||||
nl = nl->next;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
WadDebug *wd;
|
|
||||||
wd = wad_debug_info(wo,name, (unsigned long) p_pc - (unsigned long) ws->vaddr - value);
|
|
||||||
if (wd) {
|
|
||||||
srcname = wd->srcfile;
|
|
||||||
srcsize = strlen(srcname)+1;
|
|
||||||
objname = wd->objfile;
|
|
||||||
objsize = strlen(objname)+1;
|
|
||||||
frame.line_number = wd->line_number;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Build up the exception frame object */
|
|
||||||
frame.size = sizeof(WadFrame) + symsize + srcsize + objsize;
|
|
||||||
pad = 8 - (frame.size % 8);
|
|
||||||
frame.size += pad;
|
|
||||||
|
|
||||||
frame.data[0] = 0;
|
|
||||||
frame.data[1] = 0;
|
|
||||||
|
|
||||||
/* Build up the offsets */
|
|
||||||
if (!name) {
|
|
||||||
frame.sym_off = sizeof(WadFrame) - 8;
|
|
||||||
frame.src_off = sizeof(WadFrame) - 8;
|
|
||||||
frame.obj_off = sizeof(WadFrame) - 8;
|
|
||||||
} else {
|
|
||||||
frame.sym_off = sizeof(WadFrame);
|
|
||||||
frame.src_off = sizeof(WadFrame)+symsize;
|
|
||||||
frame.obj_off = sizeof(WadFrame)+symsize+srcsize;
|
|
||||||
}
|
|
||||||
write(ffile,&frame,sizeof(WadFrame));
|
|
||||||
if (symname) {
|
|
||||||
write(ffile,symname,symsize);
|
|
||||||
write(ffile,srcname,srcsize);
|
|
||||||
write(ffile,objname,objsize);
|
|
||||||
}
|
|
||||||
write(ffile,frame.data, pad);
|
|
||||||
wad_object_release(wo);
|
|
||||||
}
|
|
||||||
if (!found) nlevels++;
|
|
||||||
p_pc = (unsigned long *) *(p_sp+15);
|
|
||||||
p_sp = stack_unwind(p_sp);
|
|
||||||
if (found) break;
|
|
||||||
}
|
}
|
||||||
/* Write terminator */
|
|
||||||
frame.size = 0;
|
/* Walk the exception frames and try to find a return point */
|
||||||
write(ffile,&frame,sizeof(WadFrame));
|
|
||||||
close(ffile);
|
framedata = (char *) frame;
|
||||||
|
|
||||||
|
while (frame->size) {
|
||||||
|
nonlocal *nl = return_points;
|
||||||
|
nl = return_points;
|
||||||
|
while (nl) {
|
||||||
|
if (strcmp(framedata + frame->sym_off,nl->symname) == 0) {
|
||||||
|
found = 1;
|
||||||
|
nlr_value = nl->value;
|
||||||
|
retname = nl->symname;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nl = nl->next;
|
||||||
|
}
|
||||||
|
framedata = framedata + frame->size;
|
||||||
|
frame = (WadFrame *) framedata;
|
||||||
|
if (found) {
|
||||||
|
frame->last = 1; /* Cut off top of the stack trace */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nlevels++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
nlr_levels = nlevels - 1;
|
nlr_levels = nlevels - 1;
|
||||||
|
|
@ -289,44 +151,20 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
||||||
nlr_levels = 0;
|
nlr_levels = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Go mmap the debug file */
|
|
||||||
ffile = open(framefile, O_RDONLY, 0644);
|
|
||||||
fsize = lseek(ffile,0,SEEK_END);
|
|
||||||
lseek(ffile,0,SEEK_SET);
|
|
||||||
|
|
||||||
framedata = mmap(NULL, fsize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, ffile, 0);
|
|
||||||
|
|
||||||
if (sig_callback) {
|
if (sig_callback) {
|
||||||
(*sig_callback)(sig,framedata);
|
(*sig_callback)(sig,origframe,retname);
|
||||||
} else {
|
} else {
|
||||||
/* No signal handler defined. Go invoke the default */
|
/* No signal handler defined. Go invoke the default */
|
||||||
wad_default_callback(sig, framedata);
|
wad_default_callback(sig, origframe,retname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we found a function to which we should return, we jump to
|
/* If we found a function to which we should return, we jump to
|
||||||
an alternative piece of code that unwinds the stack and
|
an alternative piece of code that unwinds the stack and
|
||||||
initiates a non-local return. */
|
initiates a non-local return. */
|
||||||
|
|
||||||
munmap(framedata,fsize);
|
|
||||||
close(ffile);
|
|
||||||
unlink(framefile);
|
|
||||||
if (nlr_levels > 0) {
|
if (nlr_levels > 0) {
|
||||||
*(pc) = (greg_t) _returnsignal;
|
*(pc) = (greg_t) _returnsignal;
|
||||||
*(npc) = *(pc) + 4;
|
*(npc) = *(pc) + 4;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
asm_stuff()
|
|
||||||
{
|
|
||||||
asm(" .globl _get_sp");
|
|
||||||
asm("_get_sp:");
|
|
||||||
asm(" retl");
|
|
||||||
asm(" mov %sp, %o0");
|
|
||||||
asm(" .globl _get_fp");
|
|
||||||
asm("_get_fp:");
|
|
||||||
asm(" retl");
|
|
||||||
asm(" mov %fp, %o0");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -113,13 +113,48 @@ wad_search_stab(void *sp, int size, char *stabstr, char *symbol, unsigned long o
|
||||||
if (match_stab_symbol(symbol, stabstr+s->n_strx, slen)) {
|
if (match_stab_symbol(symbol, stabstr+s->n_strx, slen)) {
|
||||||
infunc = 1;
|
infunc = 1;
|
||||||
debug.found = 1;
|
debug.found = 1;
|
||||||
|
debug.nargs = 0;
|
||||||
} else {
|
} else {
|
||||||
infunc = 0;
|
infunc = 0;
|
||||||
}
|
}
|
||||||
} else if (debug.found && (s->n_type == 0x44) && (infunc)) {
|
} else if (debug.found && (s->n_type == 0x44) && (infunc)) {
|
||||||
|
|
||||||
|
/* Line number location */
|
||||||
|
|
||||||
if (s->n_value <= offset) {
|
if (s->n_value <= offset) {
|
||||||
debug.line_number = s->n_desc;
|
debug.line_number = s->n_desc;
|
||||||
} else return &debug;
|
} else return &debug;
|
||||||
|
} else if (debug.found && ((s->n_type == 0xa0) || (s->n_type == 0x40)) && (infunc)) {
|
||||||
|
/* Parameter counting */
|
||||||
|
char *pname;
|
||||||
|
char *c;
|
||||||
|
int len;
|
||||||
|
pname = stabstr+s->n_strx;
|
||||||
|
c = strchr(pname,':');
|
||||||
|
if (c) {
|
||||||
|
len = (c-pname);
|
||||||
|
} else {
|
||||||
|
len = strlen(pname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if already used */
|
||||||
|
/* In this case, the first stab simply identifies an argument. The second
|
||||||
|
one identifies its location for the debugger */
|
||||||
|
|
||||||
|
if (debug.nargs > 0) {
|
||||||
|
if (strcmp(debug.parms[debug.nargs-1].name, pname) == 0)
|
||||||
|
debug.nargs--;
|
||||||
|
}
|
||||||
|
strncpy(debug.parms[debug.nargs].name,pname,len);
|
||||||
|
debug.parms[debug.nargs].name[len] = 0;
|
||||||
|
|
||||||
|
if (s->n_type == 0x40)
|
||||||
|
debug.parms[debug.nargs].loc = PARM_REGISTER;
|
||||||
|
else
|
||||||
|
debug.parms[debug.nargs].loc = PARM_STACK;
|
||||||
|
|
||||||
|
debug.parms[debug.nargs].value = s->n_value;
|
||||||
|
debug.nargs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (debug.found) return &debug;
|
if (debug.found) return &debug;
|
||||||
|
|
|
||||||
281
SWIG/Tools/WAD/Wad/stack.c
Normal file
281
SWIG/Tools/WAD/Wad/stack.c
Normal file
|
|
@ -0,0 +1,281 @@
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* stack.c
|
||||||
|
*
|
||||||
|
* This file is used to unwind the C call stack.
|
||||||
|
*
|
||||||
|
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000. The University of Chicago
|
||||||
|
* See the file LICENSE for information on usage and redistribution.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include "wad.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
/* Given a stack pointer, this function performs a single level of stack
|
||||||
|
unwinding */
|
||||||
|
|
||||||
|
static void
|
||||||
|
stack_unwind(unsigned long *sp, unsigned long *pc) {
|
||||||
|
*pc = *((unsigned long *) *sp+15); /* %i7 - Return address */
|
||||||
|
*sp = *((unsigned long *) *sp+14); /* %i6 - frame pointer */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *trace_addr = 0;
|
||||||
|
static int trace_len = 0;
|
||||||
|
|
||||||
|
/* Perform a stack unwinding given the current value of the pc, stack pointer,
|
||||||
|
and frame pointer. Returns a pointer to a wad exception frame structure
|
||||||
|
which is actually a large memory mapped file. */
|
||||||
|
|
||||||
|
WadFrame *
|
||||||
|
wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) {
|
||||||
|
int i;
|
||||||
|
WadSegment *ws;
|
||||||
|
WadObject *wo;
|
||||||
|
WadFrame frame;
|
||||||
|
WadDebug *wd;
|
||||||
|
int nlevels;
|
||||||
|
char framefile[256];
|
||||||
|
int ffile;
|
||||||
|
unsigned long p_pc;
|
||||||
|
unsigned long p_sp;
|
||||||
|
unsigned long p_lastsp;
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
int lastsize = 0;
|
||||||
|
int firstframe = 1;
|
||||||
|
|
||||||
|
/* Open the frame file for output */
|
||||||
|
sprintf(framefile,"/tmp/wad.%d", getpid());
|
||||||
|
ffile = open(framefile, O_CREAT | O_TRUNC | O_WRONLY, 0644);
|
||||||
|
if (ffile < 0) {
|
||||||
|
printf("can't open %s\n", framefile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to do a stack traceback */
|
||||||
|
nlevels = 0;
|
||||||
|
p_pc = pc;
|
||||||
|
p_sp = sp;
|
||||||
|
|
||||||
|
while (p_sp) {
|
||||||
|
/* Add check for stack validity here */
|
||||||
|
ws = wad_segment_find((wadaddr_t) p_sp);
|
||||||
|
if (!ws) {
|
||||||
|
/* If the stack is bad, we are really hosed here */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ws = wad_segment_find((wadaddr_t) p_pc);
|
||||||
|
{
|
||||||
|
int symsize = 0;
|
||||||
|
int srcsize = 0;
|
||||||
|
int objsize = 0;
|
||||||
|
int stacksize = 0;
|
||||||
|
int argsize = 0;
|
||||||
|
char *srcname = 0;
|
||||||
|
char *objname = 0;
|
||||||
|
char *symname = 0;
|
||||||
|
int pad = 0;
|
||||||
|
unsigned long value;
|
||||||
|
|
||||||
|
/* Try to load the object file for this address */
|
||||||
|
if (ws) {
|
||||||
|
wo = wad_object_load(ws->mappath);
|
||||||
|
/* Special hack needed for base address */
|
||||||
|
if (strcmp(ws->mapname,"a.out") == 0) ws->vaddr= 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wo = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to find the symbol corresponding to this PC */
|
||||||
|
if (wo)
|
||||||
|
symname = wad_find_symbol(wo,(void *) p_pc, (unsigned long) ws->vaddr, &value);
|
||||||
|
else
|
||||||
|
symname = 0;
|
||||||
|
|
||||||
|
/* Build up some information about the exception frame */
|
||||||
|
frame.frameno = n;
|
||||||
|
frame.last = 0;
|
||||||
|
frame.lastsize = lastsize;
|
||||||
|
frame.pc = p_pc;
|
||||||
|
frame.sp = p_sp;
|
||||||
|
frame.nargs = -1;
|
||||||
|
frame.arg_off = 0;
|
||||||
|
n++;
|
||||||
|
if (symname) {
|
||||||
|
symsize = strlen(symname)+1;
|
||||||
|
|
||||||
|
/* Try to gather some debugging information about this symbol */
|
||||||
|
wd = wad_debug_info(wo,symname, p_pc - (unsigned long) ws->vaddr - value);
|
||||||
|
if (wd) {
|
||||||
|
srcname = wd->srcfile;
|
||||||
|
srcsize = strlen(srcname)+1;
|
||||||
|
objname = wd->objfile;
|
||||||
|
objsize = strlen(objname)+1;
|
||||||
|
frame.nargs = wd->nargs;
|
||||||
|
if (wd->nargs > 0) {
|
||||||
|
argsize = sizeof(WadParm)*wd->nargs;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (wd->nargs >=0) {
|
||||||
|
int i;
|
||||||
|
printf("%s\n",symname);
|
||||||
|
for (i = 0; i < wd->nargs; i++) {
|
||||||
|
printf(" [%d] = '%s', %d, %d\n", i, wd->parms[i].name, wd->parms[i].type, wd->parms[i].value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
frame.line_number = wd->line_number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Before unwinding the stack, copy the locals and %o registers from previous frame */
|
||||||
|
if (!firstframe) {
|
||||||
|
int i;
|
||||||
|
long *lsp = (long *) p_lastsp;
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
/* printf("regs[%d] = 0x%x\n", lsp[i]); */
|
||||||
|
frame.regs[i] = lsp[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
firstframe = 0;
|
||||||
|
/* Determine stack frame size */
|
||||||
|
p_lastsp = p_sp;
|
||||||
|
stack_unwind(&p_sp, &p_pc);
|
||||||
|
|
||||||
|
if (p_sp) {
|
||||||
|
stacksize = p_sp - p_lastsp;
|
||||||
|
} else {
|
||||||
|
stacksize = 0xffbf0000 - p_lastsp; /* Sick hack alert. Need to get stack top from somewhere */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the frame pointer and stack size */
|
||||||
|
frame.fp = p_sp;
|
||||||
|
frame.stack_size = stacksize;
|
||||||
|
|
||||||
|
/* Build the exception frame object we'll write */
|
||||||
|
frame.size = sizeof(WadFrame) + symsize + srcsize + objsize + stacksize + argsize;
|
||||||
|
pad = 8 - (frame.size % 8);
|
||||||
|
frame.size += pad;
|
||||||
|
|
||||||
|
frame.data[0] = 0;
|
||||||
|
frame.data[1] = 0;
|
||||||
|
|
||||||
|
/* Build up the offsets */
|
||||||
|
if (!symname) {
|
||||||
|
frame.sym_off = sizeof(WadFrame) - 8;
|
||||||
|
frame.src_off = sizeof(WadFrame) - 8;
|
||||||
|
frame.obj_off = sizeof(WadFrame) - 8;
|
||||||
|
frame.stack_off = sizeof(WadFrame) + argsize;
|
||||||
|
frame.arg_off = 0;
|
||||||
|
} else {
|
||||||
|
frame.arg_off = sizeof(WadFrame);
|
||||||
|
frame.stack_off = sizeof(WadFrame) + argsize;
|
||||||
|
frame.sym_off = frame.stack_off + stacksize;
|
||||||
|
frame.src_off = frame.sym_off + symsize;
|
||||||
|
frame.obj_off = frame.src_off + srcsize;
|
||||||
|
}
|
||||||
|
write(ffile,&frame,sizeof(WadFrame));
|
||||||
|
/* Write the argument data */
|
||||||
|
if (argsize > 0) {
|
||||||
|
write(ffile, (void *) wd->parms, argsize);
|
||||||
|
}
|
||||||
|
/* Write the stack data */
|
||||||
|
if (stacksize > 0) {
|
||||||
|
write(ffile, (void *) p_lastsp, stacksize);
|
||||||
|
}
|
||||||
|
if (symname) {
|
||||||
|
write(ffile,symname,symsize);
|
||||||
|
write(ffile,srcname,srcsize);
|
||||||
|
write(ffile,objname,objsize);
|
||||||
|
}
|
||||||
|
write(ffile,frame.data, pad);
|
||||||
|
lastsize = frame.size;
|
||||||
|
if (wo)
|
||||||
|
wad_object_release(wo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write terminator */
|
||||||
|
frame.size = 0;
|
||||||
|
frame.last = 1;
|
||||||
|
frame.lastsize = lastsize;
|
||||||
|
write(ffile,&frame,sizeof(WadFrame));
|
||||||
|
close(ffile);
|
||||||
|
|
||||||
|
/* mmap the debug file back into memory */
|
||||||
|
|
||||||
|
ffile = open(framefile, O_RDONLY, 0644);
|
||||||
|
trace_len = lseek(ffile,0,SEEK_END);
|
||||||
|
lseek(ffile,0,SEEK_SET);
|
||||||
|
trace_addr = mmap(NULL, trace_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, ffile, 0);
|
||||||
|
close(ffile);
|
||||||
|
return (WadFrame *) trace_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wad_release_trace() {
|
||||||
|
char name[256];
|
||||||
|
munmap(trace_addr, trace_len);
|
||||||
|
sprintf(name,"/tmp/wad.%d", getpid());
|
||||||
|
unlink(name);
|
||||||
|
trace_addr = 0;
|
||||||
|
trace_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function steals an argument out of a frame further up the call stack :-) */
|
||||||
|
|
||||||
|
long wad_steal_arg(WadFrame *f, char *symbol, int argno, int *error) {
|
||||||
|
char *fd;
|
||||||
|
long *regs;
|
||||||
|
WadFrame *lastf = 0;
|
||||||
|
|
||||||
|
fd = (char *) f;
|
||||||
|
|
||||||
|
|
||||||
|
*error = 0;
|
||||||
|
/* Start searching */
|
||||||
|
while (f->size) {
|
||||||
|
if (strcmp(SYMBOL(f),symbol) == 0) {
|
||||||
|
/* Got a match */
|
||||||
|
if (lastf) {
|
||||||
|
regs = STACK(f);
|
||||||
|
return regs[8+argno];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastf = f;
|
||||||
|
fd = fd + f->size;
|
||||||
|
f = (WadFrame *) fd;
|
||||||
|
}
|
||||||
|
*error = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long wad_steal_outarg(WadFrame *f, char *symbol, int argno, int *error) {
|
||||||
|
char *fd;
|
||||||
|
long *regs;
|
||||||
|
WadFrame *lastf = 0;
|
||||||
|
|
||||||
|
fd = (char *) f;
|
||||||
|
|
||||||
|
*error = 0;
|
||||||
|
/* Start searching */
|
||||||
|
while (f->size) {
|
||||||
|
if (strcmp(SYMBOL(f),symbol) == 0) {
|
||||||
|
/* Got a match */
|
||||||
|
if (lastf) {
|
||||||
|
regs = STACK(lastf);
|
||||||
|
return regs[8+argno];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastf = f;
|
||||||
|
fd = fd + f->size;
|
||||||
|
f = (WadFrame *) fd;
|
||||||
|
}
|
||||||
|
*error = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
174
SWIG/Tools/WAD/Wad/wadpy.cxx
Normal file
174
SWIG/Tools/WAD/Wad/wadpy.cxx
Normal file
|
|
@ -0,0 +1,174 @@
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* wadpy.cxx
|
||||||
|
*
|
||||||
|
* Dynamically loadable python module for wad.
|
||||||
|
*
|
||||||
|
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000. The University of Chicago
|
||||||
|
* See the file LICENSE for information on usage and redistribution.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include "Python.h"
|
||||||
|
#include "wad.h"
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
/* These are the python exception objects we will add
|
||||||
|
SegFault, BusError, AbortError */
|
||||||
|
|
||||||
|
static PyObject *segfault_exc = 0;
|
||||||
|
static PyObject *buserror_exc = 0;
|
||||||
|
static PyObject *abort_exc = 0;
|
||||||
|
|
||||||
|
/* Handler function */
|
||||||
|
static void handler(int signo, WadFrame *frame, char *ret) {
|
||||||
|
static char message[65536];
|
||||||
|
static char temp[1024];
|
||||||
|
int len = 0;
|
||||||
|
PyObject *type;
|
||||||
|
char *name;
|
||||||
|
char *fd;
|
||||||
|
WadFrame *f;
|
||||||
|
WadFrame *fline = 0;
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
wad_default_callback(signo, frame, ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(message,"[ C stack trace ]\n\n");
|
||||||
|
switch(signo) {
|
||||||
|
case SIGSEGV:
|
||||||
|
type = segfault_exc;
|
||||||
|
break;
|
||||||
|
case SIGBUS:
|
||||||
|
type = buserror_exc;
|
||||||
|
break;
|
||||||
|
case SIGABRT:
|
||||||
|
type = abort_exc;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = PyExc_RuntimeError;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fd = (char *) frame;
|
||||||
|
f = (WadFrame *) fd;
|
||||||
|
|
||||||
|
/* Find the last exception frame */
|
||||||
|
while (!f->last) {
|
||||||
|
fd = fd + f->size;
|
||||||
|
f = (WadFrame *) fd;
|
||||||
|
}
|
||||||
|
/* Now work backwards */
|
||||||
|
fd = fd - f->lastsize;
|
||||||
|
f = (WadFrame *) fd;
|
||||||
|
while (1) {
|
||||||
|
sprintf(temp,"#%-3d 0x%08x in ", f->frameno, f->pc);
|
||||||
|
strcat(message,temp);
|
||||||
|
strcat(message,*(fd + f->sym_off) ? fd+f->sym_off : "?");
|
||||||
|
strcat(message,"(");
|
||||||
|
strcat(message,wad_arg_string(f));
|
||||||
|
strcat(message,")");
|
||||||
|
if (strlen(SRCFILE(f))) {
|
||||||
|
strcat(message," in '");
|
||||||
|
strcat(message, wad_strip_dir(SRCFILE(f)));
|
||||||
|
strcat(message,"'");
|
||||||
|
if (f->line_number > 0) {
|
||||||
|
sprintf(temp,", line %d", f->line_number);
|
||||||
|
strcat(message,temp);
|
||||||
|
fline = f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (strlen(fd+f->obj_off)) {
|
||||||
|
strcat(message," from '");
|
||||||
|
strcat(message, wad_strip_dir(OBJFILE(f)));
|
||||||
|
strcat(message,"'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcat(message,"\n");
|
||||||
|
if (!f->lastsize) break;
|
||||||
|
fd = fd - f->lastsize;
|
||||||
|
f = (WadFrame *) fd;
|
||||||
|
}
|
||||||
|
if (fline) {
|
||||||
|
int first;
|
||||||
|
int last;
|
||||||
|
char *line, *c;
|
||||||
|
int i;
|
||||||
|
first = fline->line_number - 2;
|
||||||
|
last = fline->line_number + 2;
|
||||||
|
if (first < 1) first = 1;
|
||||||
|
|
||||||
|
line = wad_load_source(SRCFILE(fline),first);
|
||||||
|
if (line) {
|
||||||
|
strcat(message,"\n");
|
||||||
|
strcat(message, SRCFILE(fline));
|
||||||
|
sprintf(temp,", line %d\n\n", fline->line_number);
|
||||||
|
strcat(message, temp);
|
||||||
|
for (i = first; i <= last; i++) {
|
||||||
|
if (i == fline->line_number) strcat(message," => ");
|
||||||
|
else strcat(message," ");
|
||||||
|
c = strchr(line,'\n');
|
||||||
|
if (c) {
|
||||||
|
*c = 0;
|
||||||
|
strcat(message,line);
|
||||||
|
strcat(message,"\n");
|
||||||
|
*c = '\n';
|
||||||
|
} else {
|
||||||
|
strcat(message,line);
|
||||||
|
strcat(message,"\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
line = c+1;
|
||||||
|
}
|
||||||
|
wad_release_source();
|
||||||
|
strcat(message,"\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PyErr_SetString(type, message);
|
||||||
|
wad_release_trace();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pywadinit() {
|
||||||
|
PyObject *d, *m;
|
||||||
|
m = PyImport_ImportModule((char *)"__builtin__");
|
||||||
|
d = PyModule_GetDict(m);
|
||||||
|
printf("WAD Enabled\n");
|
||||||
|
|
||||||
|
segfault_exc = PyErr_NewException((char *)"exceptions.SegFault", NULL, NULL);
|
||||||
|
PyDict_SetItemString(d,(char *)"SegFault",segfault_exc);
|
||||||
|
|
||||||
|
buserror_exc = PyErr_NewException((char *)"exceptions.BusError", NULL, NULL);
|
||||||
|
PyDict_SetItemString(d,(char *)"BusError",buserror_exc);
|
||||||
|
|
||||||
|
abort_exc = PyErr_NewException((char*)"exceptions.AbortError", NULL, NULL);
|
||||||
|
PyDict_SetItemString(d,(char *)"AbortError",abort_exc);
|
||||||
|
|
||||||
|
wad_init();
|
||||||
|
wad_set_callback(handler);
|
||||||
|
wad_set_return((char *)"call_builtin",0);
|
||||||
|
wad_set_return((char *)"_PyImport_LoadDynamicModule",0);
|
||||||
|
wad_set_return((char *)"PyEval_EvalCode",0);
|
||||||
|
wad_set_return((char *)"PyObject_GetAttr",0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This hack is used to auto-initialize wad regardless of whether we are
|
||||||
|
used as an imported module or as a link-library for another module */
|
||||||
|
|
||||||
|
class wadinitializer {
|
||||||
|
public:
|
||||||
|
wadinitializer() {
|
||||||
|
pywadinit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static wadinitializer wi;
|
||||||
|
|
||||||
|
static PyMethodDef wadmethods[] = {
|
||||||
|
{0,0},
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void initwad() {
|
||||||
|
Py_InitModule((char *)"wad",wadmethods);
|
||||||
|
}
|
||||||
155
SWIG/Tools/WAD/Wad/wadtcl.cxx
Normal file
155
SWIG/Tools/WAD/Wad/wadtcl.cxx
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* wadtcl.cxx
|
||||||
|
*
|
||||||
|
* Dynamically loadable Tcl module for wad.
|
||||||
|
*
|
||||||
|
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000. The University of Chicago
|
||||||
|
* See the file LICENSE for information on usage and redistribution.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include <tcl.h>
|
||||||
|
#include "wad.h"
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
/* Handler function */
|
||||||
|
static void handler(int signo, WadFrame *frame, char *ret) {
|
||||||
|
static char message[65536];
|
||||||
|
static char temp[1024];
|
||||||
|
int len = 0;
|
||||||
|
char *name;
|
||||||
|
char *fd;
|
||||||
|
WadFrame *f;
|
||||||
|
WadFrame *fline = 0;
|
||||||
|
Tcl_Interp *interp;
|
||||||
|
int err;
|
||||||
|
char *type;
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
wad_default_callback(signo, frame, ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(message,"[ C stack trace ]\n\n");
|
||||||
|
switch(signo) {
|
||||||
|
case SIGSEGV:
|
||||||
|
type = "Segmentation fault.";
|
||||||
|
break;
|
||||||
|
case SIGBUS:
|
||||||
|
type = "Bus error.";
|
||||||
|
break;
|
||||||
|
case SIGABRT:
|
||||||
|
type = "Abort.";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fd = (char *) frame;
|
||||||
|
f = (WadFrame *) fd;
|
||||||
|
|
||||||
|
/* Find the last exception frame */
|
||||||
|
while (!f->last) {
|
||||||
|
fd = fd + f->size;
|
||||||
|
f = (WadFrame *) fd;
|
||||||
|
}
|
||||||
|
/* Now work backwards */
|
||||||
|
fd = fd - f->lastsize;
|
||||||
|
f = (WadFrame *) fd;
|
||||||
|
while (1) {
|
||||||
|
sprintf(temp,"#%-3d 0x%08x in ", f->frameno, f->pc);
|
||||||
|
strcat(message,temp);
|
||||||
|
strcat(message,*(fd + f->sym_off) ? fd+f->sym_off : "?");
|
||||||
|
strcat(message,"()");
|
||||||
|
if (strlen(SRCFILE(f))) {
|
||||||
|
strcat(message," in '");
|
||||||
|
strcat(message, wad_strip_dir(SRCFILE(f)));
|
||||||
|
strcat(message,"'");
|
||||||
|
if (f->line_number > 0) {
|
||||||
|
sprintf(temp,", line %d", f->line_number);
|
||||||
|
strcat(message,temp);
|
||||||
|
fline = f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (strlen(fd+f->obj_off)) {
|
||||||
|
strcat(message," from '");
|
||||||
|
strcat(message, wad_strip_dir(OBJFILE(f)));
|
||||||
|
strcat(message,"'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcat(message,"\n");
|
||||||
|
if (!f->lastsize) break;
|
||||||
|
fd = fd - f->lastsize;
|
||||||
|
f = (WadFrame *) fd;
|
||||||
|
}
|
||||||
|
if (fline) {
|
||||||
|
int first;
|
||||||
|
int last;
|
||||||
|
char *line, *c;
|
||||||
|
int i;
|
||||||
|
first = fline->line_number - 2;
|
||||||
|
last = fline->line_number + 2;
|
||||||
|
if (first < 1) first = 1;
|
||||||
|
|
||||||
|
line = wad_load_source(SRCFILE(fline),first);
|
||||||
|
if (line) {
|
||||||
|
strcat(message,"\n");
|
||||||
|
strcat(message, SRCFILE(fline));
|
||||||
|
sprintf(temp,", line %d\n\n", fline->line_number);
|
||||||
|
strcat(message, temp);
|
||||||
|
for (i = first; i <= last; i++) {
|
||||||
|
if (i == fline->line_number) strcat(message," => ");
|
||||||
|
else strcat(message," ");
|
||||||
|
c = strchr(line,'\n');
|
||||||
|
if (c) {
|
||||||
|
*c = 0;
|
||||||
|
strcat(message,line);
|
||||||
|
strcat(message,"\n");
|
||||||
|
*c = '\n';
|
||||||
|
} else {
|
||||||
|
strcat(message,line);
|
||||||
|
strcat(message,"\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
line = c+1;
|
||||||
|
}
|
||||||
|
wad_release_source();
|
||||||
|
strcat(message,"\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to get the Tcl interpreter through magic */
|
||||||
|
if (ret) {
|
||||||
|
interp = (Tcl_Interp *) wad_steal_outarg(frame,ret,1,&err);
|
||||||
|
if (err == 0) {
|
||||||
|
Tcl_SetResult(interp,type,TCL_STATIC);
|
||||||
|
Tcl_AddErrorInfo(interp,message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wad_release_trace();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tclwadinit() {
|
||||||
|
printf("WAD Enabled\n");
|
||||||
|
wad_init();
|
||||||
|
wad_set_callback(handler);
|
||||||
|
wad_set_return("TclExecuteByteCode", TCL_ERROR);
|
||||||
|
wad_set_return("EvalObjv", TCL_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This hack is used to auto-initialize wad regardless of whether we are
|
||||||
|
used as an imported module or as a link-library for another module */
|
||||||
|
|
||||||
|
class wadinitializer {
|
||||||
|
public:
|
||||||
|
wadinitializer() {
|
||||||
|
tclwadinit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static wadinitializer wi;
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int Wad_Init(Tcl_Interp *interp) {
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue