Grab native stack pointer from signal handler

darcs
slava 2006-12-18 04:31:38 +00:00
parent 917a42cb4a
commit 756cea6164
14 changed files with 269 additions and 253 deletions

View File

@ -25,10 +25,8 @@
- variable width word wrap - variable width word wrap
- graphical crossref tool - graphical crossref tool
- inspector where slot values can be changed - inspector where slot values can be changed
- compiled call traces: - compiled call traces do not work if the runtime is built with
- should be independent of whenever the runtime was built with -fomit-frame-pointer on ppc
-fomit-frame-pointer on ppc
- we don't know if signal handlers run with the same stack or not
- use crc32 instead of modification date in reload-modules - use crc32 instead of modification date in reload-modules
- models: don't do redundant work - models: don't do redundant work
- top level window positioning on ms windows - top level window positioning on ms windows

View File

@ -30,7 +30,7 @@ void *alien_offset(CELL object)
case ALIEN_TYPE: case ALIEN_TYPE:
alien = untag_alien_fast(object); alien = untag_alien_fast(object);
if(alien->expired) if(alien->expired)
general_error(ERROR_EXPIRED,object,F,true); simple_error(ERROR_EXPIRED,object,F);
return alien_offset(alien->alien) + alien->displacement; return alien_offset(alien->alien) + alien->displacement;
case F_TYPE: case F_TYPE:
return NULL; return NULL;
@ -178,7 +178,7 @@ void primitive_dlsym(void)
{ {
d = untag_dll(dll); d = untag_dll(dll);
if(d->dll == NULL) if(d->dll == NULL)
general_error(ERROR_EXPIRED,dll,F,true); simple_error(ERROR_EXPIRED,dll,F);
} }
box_alien(ffi_dlsym(d,sym,true)); box_alien(ffi_dlsym(d,sym,true));

View File

@ -4,7 +4,7 @@
image load */ image load */
void undefined_symbol(void) void undefined_symbol(void)
{ {
general_error(ERROR_UNDEFINED_SYMBOL,F,F,true); simple_error(ERROR_UNDEFINED_SYMBOL,F,F);
} }
#define CREF(array,i) ((CELL)(array) + CELLS * (i)) #define CREF(array,i) ((CELL)(array) + CELLS * (i))

View File

@ -114,7 +114,7 @@ void primitive_next_object(void)
CELL type; CELL type;
if(!gc_off) if(!gc_off)
general_error(ERROR_HEAP_SCAN,F,F,true); simple_error(ERROR_HEAP_SCAN,F,F);
if(heap_scan_ptr >= tenured.here) if(heap_scan_ptr >= tenured.here)
{ {

View File

@ -235,7 +235,7 @@ void factorbug(void)
fprintf(stderr,"%lx\n",(CELL)CARD_TO_ADDR(card)); fprintf(stderr,"%lx\n",(CELL)CARD_TO_ADDR(card));
} }
else if(strcmp(cmd,"t") == 0) else if(strcmp(cmd,"t") == 0)
general_error(ERROR_USER_INTERRUPT,F,F,true); simple_error(ERROR_USER_INTERRUPT,F,F);
else if(strcmp(cmd,"q") == 0) else if(strcmp(cmd,"q") == 0)
return; return;
else if(strcmp(cmd,"x") == 0) else if(strcmp(cmd,"x") == 0)

View File

@ -21,7 +21,7 @@ void init_c_io(void)
void io_error(void) void io_error(void)
{ {
CELL error = tag_object(from_char_string(strerror(errno))); CELL error = tag_object(from_char_string(strerror(errno)));
general_error(ERROR_IO,error,F,true); simple_error(ERROR_IO,error,F);
} }
void primitive_fopen(void) void primitive_fopen(void)

View File

@ -24,14 +24,14 @@ static mach_port_t our_exception_port;
static void static void
memory_protection_handler (void *fault_addr) memory_protection_handler (void *fault_addr)
{ {
memory_protection_error((CELL)fault_addr,SIGSEGV); memory_protection_error((CELL)fault_addr,SIGSEGV,native_stack_pointer());
abort (); abort ();
} }
static void static void
arithmetic_handler (void *ignore) arithmetic_handler (void *ignore)
{ {
signal_error(SIGFPE); signal_error(SIGFPE,native_stack_pointer());
abort (); abort ();
} }

View File

@ -26,7 +26,7 @@ NS_DURING
{ {
CELL e = error; CELL e = error;
error = F; error = F;
general_error(ERROR_OBJECTIVE_C,e,F,true); simple_error(ERROR_OBJECTIVE_C,e,F);
} }
interpreter_loop(); interpreter_loop();

View File

@ -22,8 +22,8 @@ void ffi_dlopen(F_DLL *dll, bool error)
{ {
if(error) if(error)
{ {
general_error(ERROR_FFI,F, simple_error(ERROR_FFI,F,
tag_object(from_char_string(dlerror())),true); tag_object(from_char_string(dlerror())));
} }
else else
dll->dll = NULL; dll->dll = NULL;
@ -42,9 +42,9 @@ void *ffi_dlsym(F_DLL *dll, char *symbol, bool error)
{ {
if(error) if(error)
{ {
general_error(ERROR_FFI, simple_error(ERROR_FFI,
tag_object(from_char_string(symbol)), tag_object(from_char_string(symbol)),
tag_object(from_char_string(dlerror())),true); tag_object(from_char_string(dlerror())));
} }
return NULL; return NULL;
@ -56,8 +56,8 @@ void ffi_dlclose(F_DLL *dll)
{ {
if(dlclose(dll->dll)) if(dlclose(dll->dll))
{ {
general_error(ERROR_FFI,tag_object( simple_error(ERROR_FFI,tag_object(
from_char_string(dlerror())),F,true); from_char_string(dlerror())),F);
} }
dll->dll = NULL; dll->dll = NULL;
} }
@ -158,14 +158,21 @@ void dealloc_segment(F_SEGMENT *block)
free(block); free(block);
} }
void memory_signal_handler(int signal, siginfo_t* siginfo, void* uap) INLINE F_STACK_FRAME *uap_stack_pointer(void *uap)
{ {
memory_protection_error((CELL)siginfo->si_addr, signal); ucontext_t *ucontext = (ucontext_t *)uap;
return (F_STACK_FRAME *)ucontext->uc_stack.ss_sp;
} }
void misc_signal_handler(int signal, siginfo_t* siginfo, void* uap) void memory_signal_handler(int signal, siginfo_t *siginfo, void *uap)
{ {
signal_error(signal); memory_protection_error((CELL)siginfo->si_addr,signal,
uap_stack_pointer(uap));
}
void misc_signal_handler(int signal, siginfo_t *siginfo, void *uap)
{
signal_error(signal,uap_stack_pointer(uap));
} }
static void sigaction_safe(int signum, const struct sigaction *act, struct sigaction *oldact) static void sigaction_safe(int signum, const struct sigaction *act, struct sigaction *oldact)
@ -174,7 +181,8 @@ static void sigaction_safe(int signum, const struct sigaction *act, struct sigac
do do
{ {
ret = sigaction(signum, act, oldact); ret = sigaction(signum, act, oldact);
} while(ret == -1 && errno == EINTR); }
while(ret == -1 && errno == EINTR);
} }
void unix_init_signals(void) void unix_init_signals(void)

View File

@ -5,6 +5,7 @@
#include <unistd.h> #include <unistd.h>
#include <sys/time.h> #include <sys/time.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <ucontext.h>
#define DLLEXPORT #define DLLEXPORT
#define SETJMP(jmpbuf) sigsetjmp(jmpbuf,1) #define SETJMP(jmpbuf) sigsetjmp(jmpbuf,1)

View File

@ -48,7 +48,8 @@ void ffi_dlopen (F_DLL *dll, bool error)
{ {
dll->dll = NULL; dll->dll = NULL;
if(error) if(error)
general_error(ERROR_FFI, F, tag_object(get_error_message()),true); simple_error(ERROR_FFI,F,
tag_object(get_error_message()));
else else
return; return;
} }
@ -65,9 +66,9 @@ void *ffi_dlsym (F_DLL *dll, char *symbol, bool error)
if (!sym) if (!sym)
{ {
if(error) if(error)
general_error(ERROR_FFI, simple_error(ERROR_FFI,
tag_object(from_char_string(symbol)), tag_object(from_char_string(symbol)),
tag_object(get_error_message()),true); tag_object(get_error_message()));
else else
return NULL; return NULL;
} }
@ -222,7 +223,8 @@ void seh_call(void (*func)(), exception_handler_t *handler)
static long exception_handler(PEXCEPTION_RECORD rec, void *frame, void *ctx, void *dispatch) static long exception_handler(PEXCEPTION_RECORD rec, void *frame, void *ctx, void *dispatch)
{ {
memory_protection_error(rec->ExceptionInformation[1], SIGSEGV); memory_protection_error(rec->ExceptionInformation[1],
SIGSEGV,native_stack_pointer());
return -1; /* unreachable */ return -1; /* unreachable */
} }

View File

@ -75,7 +75,7 @@ void interpreter_loop(void)
if(stack_chain->next) if(stack_chain->next)
return; return;
general_error(ERROR_CS_UNDERFLOW,F,F,false); simple_error(ERROR_CS_UNDERFLOW,F,F);
} }
callframe_end = get(cs); callframe_end = get(cs);
@ -121,7 +121,7 @@ void run_callback(CELL quot)
/* XT of deferred words */ /* XT of deferred words */
void undefined(F_WORD* word) void undefined(F_WORD* word)
{ {
general_error(ERROR_UNDEFINED_WORD,tag_word(word),F,true); simple_error(ERROR_UNDEFINED_WORD,tag_word(word),F);
} }
/* XT of compound definitions */ /* XT of compound definitions */
@ -258,14 +258,13 @@ void early_error(CELL error)
} }
/* allocates memory */ /* allocates memory */
CELL allot_native_stack_trace(void) CELL allot_native_stack_trace(F_STACK_FRAME *stack)
{ {
F_STACK_FRAME *frame = native_stack_pointer();
GROWABLE_ARRAY(array); GROWABLE_ARRAY(array);
while(frame < stack_chain->native_stack_pointer) while(stack < stack_chain->native_stack_pointer)
{ {
CELL return_address = RETURN_ADDRESS(frame); CELL return_address = RETURN_ADDRESS(stack);
if(return_address >= compiling.base if(return_address >= compiling.base
&& return_address <= compiling.limit) && return_address <= compiling.limit)
@ -276,16 +275,16 @@ CELL allot_native_stack_trace(void)
GROWABLE_ADD(array,cell); GROWABLE_ADD(array,cell);
} }
F_STACK_FRAME *prev = PREVIOUS_FRAME(frame); F_STACK_FRAME *prev = PREVIOUS_FRAME(stack);
if(prev <= frame) if(prev <= stack)
{ {
fprintf(stderr,"*** Unusual C stack layout (why?)\n"); fprintf(stderr,"*** Unusual C stack layout (why?)\n");
fflush(stderr); fflush(stderr);
break; break;
} }
frame = prev; stack = prev;
} }
GROWABLE_TRIM(array); GROWABLE_TRIM(array);
@ -293,12 +292,12 @@ CELL allot_native_stack_trace(void)
return tag_object(array); return tag_object(array);
} }
void throw_error(CELL error, bool keep_stacks) void throw_error(CELL error, bool keep_stacks, F_STACK_FRAME *native_stack)
{ {
early_error(error); early_error(error);
REGISTER_ROOT(error); REGISTER_ROOT(error);
thrown_native_stack_trace = allot_native_stack_trace(); thrown_native_stack_trace = allot_native_stack_trace(native_stack);
UNREGISTER_ROOT(error); UNREGISTER_ROOT(error);
throwing = true; throwing = true;
@ -313,7 +312,7 @@ void throw_error(CELL error, bool keep_stacks)
void primitive_throw(void) void primitive_throw(void)
{ {
throw_error(dpop(),true); throw_error(dpop(),true,native_stack_pointer());
} }
void primitive_die(void) void primitive_die(void)
@ -321,51 +320,57 @@ void primitive_die(void)
factorbug(); factorbug();
} }
void general_error(F_ERRORTYPE error, CELL arg1, CELL arg2, bool keep_stacks) void general_error(F_ERRORTYPE error, CELL arg1, CELL arg2,
bool keep_stacks, F_STACK_FRAME *native_stack)
{ {
throw_error(allot_array_4(userenv[ERROR_ENV], throw_error(allot_array_4(userenv[ERROR_ENV],
tag_fixnum(error),arg1,arg2),keep_stacks); tag_fixnum(error),arg1,arg2),keep_stacks,native_stack);
} }
void memory_protection_error(CELL addr, int signal) void simple_error(F_ERRORTYPE error, CELL arg1, CELL arg2)
{
general_error(error,arg1,arg2,true,native_stack_pointer());
}
void memory_protection_error(CELL addr, int signal, F_STACK_FRAME *native_stack)
{ {
gc_off = true; gc_off = true;
if(in_page(addr, ds_bot, 0, -1)) if(in_page(addr, ds_bot, 0, -1))
general_error(ERROR_DS_UNDERFLOW,F,F,false); general_error(ERROR_DS_UNDERFLOW,F,F,false,native_stack);
else if(in_page(addr, ds_bot, ds_size, 0)) else if(in_page(addr, ds_bot, ds_size, 0))
general_error(ERROR_DS_OVERFLOW,F,F,false); general_error(ERROR_DS_OVERFLOW,F,F,false,native_stack);
else if(in_page(addr, rs_bot, 0, -1)) else if(in_page(addr, rs_bot, 0, -1))
general_error(ERROR_RS_UNDERFLOW,F,F,false); general_error(ERROR_RS_UNDERFLOW,F,F,false,native_stack);
else if(in_page(addr, rs_bot, rs_size, 0)) else if(in_page(addr, rs_bot, rs_size, 0))
general_error(ERROR_RS_OVERFLOW,F,F,false); general_error(ERROR_RS_OVERFLOW,F,F,false,native_stack);
else if(in_page(addr, cs_bot, 0, -1)) else if(in_page(addr, cs_bot, 0, -1))
general_error(ERROR_CS_UNDERFLOW,F,F,false); general_error(ERROR_CS_UNDERFLOW,F,F,false,native_stack);
else if(in_page(addr, cs_bot, cs_size, 0)) else if(in_page(addr, cs_bot, cs_size, 0))
general_error(ERROR_CS_OVERFLOW,F,F,false); general_error(ERROR_CS_OVERFLOW,F,F,false,native_stack);
else if(in_page(addr, nursery.limit, 0, 0)) else if(in_page(addr, nursery.limit, 0, 0))
critical_error("Out of memory in allot",0); critical_error("Out of memory in allot",0);
signal_error(signal); signal_error(signal,native_stack);
} }
void signal_error(int signal) void signal_error(int signal, F_STACK_FRAME *native_stack)
{ {
gc_off = true; gc_off = true;
general_error(ERROR_SIGNAL,tag_fixnum(signal),F,false); general_error(ERROR_SIGNAL,tag_fixnum(signal),F,false,native_stack);
} }
void type_error(CELL type, CELL tagged) void type_error(CELL type, CELL tagged)
{ {
general_error(ERROR_TYPE,tag_fixnum(type),tagged,true); simple_error(ERROR_TYPE,tag_fixnum(type),tagged);
} }
void divide_by_zero_error(void) void divide_by_zero_error(void)
{ {
general_error(ERROR_DIVIDE_BY_ZERO,F,F,true); simple_error(ERROR_DIVIDE_BY_ZERO,F,F);
} }
void memory_error(void) void memory_error(void)
{ {
general_error(ERROR_MEMORY,F,F,true); simple_error(ERROR_MEMORY,F,F);
} }

View File

@ -188,11 +188,13 @@ CELL thrown_rs;
void fatal_error(char* msg, CELL tagged); void fatal_error(char* msg, CELL tagged);
void critical_error(char* msg, CELL tagged); void critical_error(char* msg, CELL tagged);
void throw_error(CELL error, bool keep_stacks); void throw_error(CELL error, bool keep_stacks, F_STACK_FRAME *native_stack);
void early_error(CELL error); void early_error(CELL error);
void general_error(F_ERRORTYPE error, CELL arg1, CELL arg2, bool keep_stacks); void general_error(F_ERRORTYPE error, CELL arg1, CELL arg2,
void memory_protection_error(CELL addr, int signal); bool keep_stacks, F_STACK_FRAME *native_stack);
void signal_error(int signal); void simple_error(F_ERRORTYPE error, CELL arg1, CELL arg2);
void memory_protection_error(CELL addr, int signal, F_STACK_FRAME *native_stacks);
void signal_error(int signal, F_STACK_FRAME *native_stack);
void type_error(CELL type, CELL tagged); void type_error(CELL type, CELL tagged);
void divide_by_zero_error(void); void divide_by_zero_error(void);
void memory_error(void); void memory_error(void);

View File

@ -20,7 +20,7 @@ F_ARRAY *allot_array_internal(CELL type, F_FIXNUM capacity)
if(capacity < 0) if(capacity < 0)
{ {
general_error(ERROR_NEGATIVE_ARRAY_SIZE,allot_integer(capacity),F,true); simple_error(ERROR_NEGATIVE_ARRAY_SIZE,allot_integer(capacity),F);
return NULL; return NULL;
} }
else else
@ -48,7 +48,7 @@ F_ARRAY *allot_byte_array(F_FIXNUM size)
{ {
if(size < 0) if(size < 0)
{ {
general_error(ERROR_NEGATIVE_ARRAY_SIZE,allot_integer(size),F,true); simple_error(ERROR_NEGATIVE_ARRAY_SIZE,allot_integer(size),F);
return NULL; return NULL;
} }
@ -144,7 +144,7 @@ F_STRING* allot_string_internal(F_FIXNUM capacity)
if(capacity < 0) if(capacity < 0)
{ {
general_error(ERROR_NEGATIVE_ARRAY_SIZE,allot_integer(capacity),F,true); simple_error(ERROR_NEGATIVE_ARRAY_SIZE,allot_integer(capacity),F);
return NULL; return NULL;
} }
else else
@ -309,7 +309,7 @@ F_ARRAY *allot_c_string(CELL capacity, CELL size)
CELL capacity = string_capacity(s); \ CELL capacity = string_capacity(s); \
F_ARRAY *_c_str; \ F_ARRAY *_c_str; \
if(check && !check_string(s,sizeof(type))) \ if(check && !check_string(s,sizeof(type))) \
general_error(ERROR_C_STRING,tag_object(s),F,true); \ simple_error(ERROR_C_STRING,tag_object(s),F); \
REGISTER_STRING(s); \ REGISTER_STRING(s); \
_c_str = allot_c_string(capacity,sizeof(type)); \ _c_str = allot_c_string(capacity,sizeof(type)); \
UNREGISTER_STRING(s); \ UNREGISTER_STRING(s); \
@ -323,7 +323,7 @@ F_ARRAY *allot_c_string(CELL capacity, CELL size)
if(sizeof(type) == sizeof(u16)) \ if(sizeof(type) == sizeof(u16)) \
{ \ { \
if(check && !check_string(s,sizeof(type))) \ if(check && !check_string(s,sizeof(type))) \
general_error(ERROR_C_STRING,tag_object(s),F,true); \ simple_error(ERROR_C_STRING,tag_object(s),F); \
return (type*)(s + 1); \ return (type*)(s + 1); \
} \ } \
else \ else \