*** 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
|
||||
OBJS = stab.o elf.o object.o signal.o segment.o init.o main.o
|
||||
SRCS = default.c stack.c stab.c elf.c object.c init.c segment.c signal.c
|
||||
OBJS = default.o stack.o stab.o elf.o object.o signal.o segment.o init.o main.o
|
||||
INCLUDE = -I../Include
|
||||
|
||||
PYINCLUDE = -I/usr/local/include/python2.0
|
||||
TCLINCLUDE = -I/usr/local/include
|
||||
|
||||
all::
|
||||
CC -Kpic -c $(INCLUDE) main.cxx
|
||||
cc -c $(INCLUDE) $(SRCS)
|
||||
CC -G $(OBJS) -o 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 $(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);
|
||||
wad_object_release(wo1);
|
||||
} 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);
|
||||
return wd;
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ wad_segment_find(wadaddr_t addr) {
|
|||
read_segment = 0;
|
||||
while (1) {
|
||||
n = read(fd,&pmap,sizeof(prmap_t));
|
||||
if (n < 0) break;
|
||||
if (n <= 0) break;
|
||||
offset += n;
|
||||
if ((addr >= (wadaddr_t) pmap.pr_vaddr) && (addr <= (wadaddr_t) (pmap.pr_vaddr + pmap.pr_size))) {
|
||||
strncpy(segment.mapname, pmap.pr_mapname, MAX_PATH);
|
||||
|
|
|
|||
|
|
@ -15,72 +15,6 @@
|
|||
#include <sys/types.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 */
|
||||
|
||||
typedef struct nonlocal {
|
||||
|
|
@ -100,9 +34,9 @@ void wad_set_return(char *name, long value) {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -117,6 +51,11 @@ static int nlr_levels = 0;
|
|||
static int *volatile nlr_p = &nlr_levels;
|
||||
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() {
|
||||
long a;
|
||||
|
||||
|
|
@ -147,37 +86,19 @@ static void nonlocalret() {
|
|||
}
|
||||
|
||||
void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
||||
int current;
|
||||
greg_t *pc;
|
||||
greg_t *npc;
|
||||
greg_t *ret;
|
||||
greg_t *sp;
|
||||
int i;
|
||||
unsigned long *user_fp;
|
||||
unsigned long *addr;
|
||||
unsigned long addr;
|
||||
ucontext_t *context;
|
||||
unsigned long *p_sp; /* process stack pointer */
|
||||
unsigned long *p_pc; /* Process program counter */
|
||||
WadSegment *ws;
|
||||
WadObject *wo;
|
||||
int nlevels;
|
||||
unsigned long p_sp; /* process stack pointer */
|
||||
unsigned long p_pc; /* Process program counter */
|
||||
int nlevels = 0;
|
||||
int found = 0;
|
||||
void _returnsignal();
|
||||
int n = 0;
|
||||
char framefile[256];
|
||||
int ffile;
|
||||
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);
|
||||
}
|
||||
WadFrame *frame, *origframe;
|
||||
char *framedata;
|
||||
char *retname = 0;
|
||||
|
||||
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]);
|
||||
npc = &((context->uc_mcontext).gregs[REG_nPC]);
|
||||
sp = &((context->uc_mcontext).gregs[REG_SP]);
|
||||
ret = &((context->uc_mcontext).gregs[REG_O7]);
|
||||
|
||||
/* 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 */
|
||||
nlevels = 0;
|
||||
p_pc = (unsigned long *) (*pc);
|
||||
p_sp = (unsigned long *) (*sp);
|
||||
|
||||
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;
|
||||
frame = wad_stack_trace(p_pc, p_sp, 0);
|
||||
origframe =frame;
|
||||
if (!frame) {
|
||||
/* We're really hosed here */
|
||||
return;
|
||||
}
|
||||
/* Write terminator */
|
||||
frame.size = 0;
|
||||
write(ffile,&frame,sizeof(WadFrame));
|
||||
close(ffile);
|
||||
|
||||
/* Walk the exception frames and try to find a return point */
|
||||
|
||||
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) {
|
||||
nlr_levels = nlevels - 1;
|
||||
|
|
@ -289,44 +151,20 @@ void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) {
|
|||
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) {
|
||||
(*sig_callback)(sig,framedata);
|
||||
(*sig_callback)(sig,origframe,retname);
|
||||
} else {
|
||||
/* 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
|
||||
an alternative piece of code that unwinds the stack and
|
||||
initiates a non-local return. */
|
||||
|
||||
munmap(framedata,fsize);
|
||||
close(ffile);
|
||||
unlink(framefile);
|
||||
if (nlr_levels > 0) {
|
||||
*(pc) = (greg_t) _returnsignal;
|
||||
*(npc) = *(pc) + 4;
|
||||
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)) {
|
||||
infunc = 1;
|
||||
debug.found = 1;
|
||||
debug.nargs = 0;
|
||||
} else {
|
||||
infunc = 0;
|
||||
}
|
||||
} else if (debug.found && (s->n_type == 0x44) && (infunc)) {
|
||||
|
||||
/* Line number location */
|
||||
|
||||
if (s->n_value <= offset) {
|
||||
debug.line_number = s->n_desc;
|
||||
} 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;
|
||||
|
|
|
|||
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