vm: use sigaltstack to handle callstack overflow properly

release
Slava Pestov 2010-03-28 11:37:28 -04:00
parent e859a32096
commit 9ffe0a69d1
10 changed files with 54 additions and 41 deletions

View File

@ -9,7 +9,7 @@ void factor_vm::c_to_factor_toplevel(cell quot)
c_to_factor(quot); c_to_factor(quot);
} }
void init_signals() void factor_vm::init_signals()
{ {
unix_init_signals(); unix_init_signals();
} }

View File

@ -4,8 +4,6 @@ namespace factor
#define VM_C_API extern "C" #define VM_C_API extern "C"
#define NULL_DLL NULL #define NULL_DLL NULL
void c_to_factor_toplevel(cell quot);
void init_signals();
void early_init(); void early_init();
const char *vm_executable_path(); const char *vm_executable_path();
const char *default_image_path(); const char *default_image_path();

View File

@ -5,14 +5,11 @@ namespace factor
#define FACTOR_OS_STRING "macosx" #define FACTOR_OS_STRING "macosx"
#define NULL_DLL "libfactor.dylib" #define NULL_DLL "libfactor.dylib"
void init_signals();
void early_init(); void early_init();
const char *vm_executable_path(); const char *vm_executable_path();
const char *default_image_path(); const char *default_image_path();
void c_to_factor_toplevel(cell quot);
#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_stack.ss_sp) #define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_stack.ss_sp)
#define UAP_STACK_POINTER_TYPE void* #define UAP_STACK_POINTER_TYPE void*

View File

@ -70,7 +70,7 @@ const char *default_image_path(void)
return [returnVal UTF8String]; return [returnVal UTF8String];
} }
void init_signals(void) void factor_vm::init_signals(void)
{ {
unix_init_signals(); unix_init_signals();
mach_initialize(); mach_initialize();
@ -87,11 +87,9 @@ Protocol *objc_getProtocol(char *name)
u64 nano_count() u64 nano_count()
{ {
u64 t; u64 t = mach_absolute_time();
mach_timebase_info_data_t info; mach_timebase_info_data_t info;
kern_return_t ret; kern_return_t ret = mach_timebase_info(&info);
t = mach_absolute_time();
ret = mach_timebase_info(&info);
if(ret != 0) if(ret != 0)
fatal_error("mach_timebase_info failed",ret); fatal_error("mach_timebase_info failed",ret);
return t * (info.numer/info.denom); return t * (info.numer/info.denom);

View File

@ -23,7 +23,6 @@ void init_platform_globals()
{ {
if(pthread_key_create(&current_vm_tls_key, NULL) != 0) if(pthread_key_create(&current_vm_tls_key, NULL) != 0)
fatal_error("pthread_key_create() failed",0); fatal_error("pthread_key_create() failed",0);
} }
void register_vm_with_thread(factor_vm *vm) void register_vm_with_thread(factor_vm *vm)
@ -187,8 +186,18 @@ static void sigaction_safe(int signum, const struct sigaction *act, struct sigac
fatal_error("sigaction failed", 0); fatal_error("sigaction failed", 0);
} }
void unix_init_signals() void factor_vm::unix_init_signals()
{ {
signal_callstack_seg = new segment(callstack_size,false);
stack_t signal_callstack;
signal_callstack.ss_sp = (void *)signal_callstack_seg->start;
signal_callstack.ss_size = signal_callstack_seg->size;
signal_callstack.ss_flags = 0;
if(sigaltstack(&signal_callstack,(stack_t *)NULL) < 0)
fatal_error("sigaltstack() failed",0);
struct sigaction memory_sigaction; struct sigaction memory_sigaction;
struct sigaction misc_sigaction; struct sigaction misc_sigaction;
struct sigaction fpe_sigaction; struct sigaction fpe_sigaction;
@ -197,7 +206,7 @@ void unix_init_signals()
memset(&memory_sigaction,0,sizeof(struct sigaction)); memset(&memory_sigaction,0,sizeof(struct sigaction));
sigemptyset(&memory_sigaction.sa_mask); sigemptyset(&memory_sigaction.sa_mask);
memory_sigaction.sa_sigaction = memory_signal_handler; memory_sigaction.sa_sigaction = memory_signal_handler;
memory_sigaction.sa_flags = SA_SIGINFO; memory_sigaction.sa_flags = SA_SIGINFO | SA_ONSTACK;
sigaction_safe(SIGBUS,&memory_sigaction,NULL); sigaction_safe(SIGBUS,&memory_sigaction,NULL);
sigaction_safe(SIGSEGV,&memory_sigaction,NULL); sigaction_safe(SIGSEGV,&memory_sigaction,NULL);
@ -205,14 +214,14 @@ void unix_init_signals()
memset(&fpe_sigaction,0,sizeof(struct sigaction)); memset(&fpe_sigaction,0,sizeof(struct sigaction));
sigemptyset(&fpe_sigaction.sa_mask); sigemptyset(&fpe_sigaction.sa_mask);
fpe_sigaction.sa_sigaction = fpe_signal_handler; fpe_sigaction.sa_sigaction = fpe_signal_handler;
fpe_sigaction.sa_flags = SA_SIGINFO; fpe_sigaction.sa_flags = SA_SIGINFO | SA_ONSTACK;
sigaction_safe(SIGFPE,&fpe_sigaction,NULL); sigaction_safe(SIGFPE,&fpe_sigaction,NULL);
memset(&misc_sigaction,0,sizeof(struct sigaction)); memset(&misc_sigaction,0,sizeof(struct sigaction));
sigemptyset(&misc_sigaction.sa_mask); sigemptyset(&misc_sigaction.sa_mask);
misc_sigaction.sa_sigaction = misc_signal_handler; misc_sigaction.sa_sigaction = misc_signal_handler;
misc_sigaction.sa_flags = SA_SIGINFO; misc_sigaction.sa_flags = SA_SIGINFO | SA_ONSTACK;
sigaction_safe(SIGQUIT,&misc_sigaction,NULL); sigaction_safe(SIGQUIT,&misc_sigaction,NULL);
sigaction_safe(SIGILL,&misc_sigaction,NULL); sigaction_safe(SIGILL,&misc_sigaction,NULL);

View File

@ -39,7 +39,6 @@ typedef pthread_t THREADHANDLE;
THREADHANDLE start_thread(void *(*start_routine)(void *),void *args); THREADHANDLE start_thread(void *(*start_routine)(void *),void *args);
inline static THREADHANDLE thread_id() { return pthread_self(); } inline static THREADHANDLE thread_id() { return pthread_self(); }
void unix_init_signals();
void signal_handler(int signal, siginfo_t* siginfo, void* uap); void signal_handler(int signal, siginfo_t* siginfo, void* uap);
void dump_stack_signal(int signal, siginfo_t* siginfo, void* uap); void dump_stack_signal(int signal, siginfo_t* siginfo, void* uap);

View File

@ -143,4 +143,6 @@ void factor_vm::move_file(const vm_char *path1, const vm_char *path2)
general_error(ERROR_IO,tag_fixnum(GetLastError()),false_object); general_error(ERROR_IO,tag_fixnum(GetLastError()),false_object);
} }
void factor_vm::init_signals() {}
} }

View File

@ -43,7 +43,6 @@ typedef wchar_t vm_char;
/* Difference between Jan 1 00:00:00 1601 and Jan 1 00:00:00 1970 */ /* Difference between Jan 1 00:00:00 1601 and Jan 1 00:00:00 1970 */
#define EPOCH_OFFSET 0x019db1ded53e8000LL #define EPOCH_OFFSET 0x019db1ded53e8000LL
inline static void init_signals() {}
inline static void early_init() {} inline static void early_init() {}
u64 system_micros(); u64 system_micros();

View File

@ -13,7 +13,8 @@ factor_vm::factor_vm() :
gc_events(NULL), gc_events(NULL),
fep_disabled(false), fep_disabled(false),
full_output(false), full_output(false),
last_nano_count(0) last_nano_count(0),
signal_callstack_seg(NULL)
{ {
primitive_reset_dispatch_stats(); primitive_reset_dispatch_stats();
} }
@ -21,6 +22,11 @@ factor_vm::factor_vm() :
factor_vm::~factor_vm() factor_vm::~factor_vm()
{ {
delete_contexts(); delete_contexts();
if(signal_callstack_seg)
{
delete signal_callstack_seg;
signal_callstack_seg = NULL;
}
} }
} }

View File

@ -107,6 +107,9 @@ struct factor_vm
decrease */ decrease */
u64 last_nano_count; u64 last_nano_count;
/* Stack for signal handlers, only used on Unix */
segment *signal_callstack_seg;
// contexts // contexts
context *new_context(); context *new_context();
void delete_context(context *old_context); void delete_context(context *old_context);
@ -685,6 +688,7 @@ struct factor_vm
void *ffi_dlsym(dll *dll, symbol_char *symbol); void *ffi_dlsym(dll *dll, symbol_char *symbol);
void ffi_dlclose(dll *dll); void ffi_dlclose(dll *dll);
void c_to_factor_toplevel(cell quot); void c_to_factor_toplevel(cell quot);
void init_signals();
// os-windows // os-windows
#if defined(WINDOWS) #if defined(WINDOWS)
@ -697,8 +701,10 @@ struct factor_vm
void open_console(); void open_console();
LONG exception_handler(PEXCEPTION_POINTERS pe); LONG exception_handler(PEXCEPTION_POINTERS pe);
#endif #endif
#else // UNIX #else // UNIX
void dispatch_signal(void *uap, void (handler)()); void dispatch_signal(void *uap, void (handler)());
void unix_init_signals();
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
@ -707,7 +713,6 @@ struct factor_vm
factor_vm(); factor_vm();
~factor_vm(); ~factor_vm();
}; };
extern std::map<THREADHANDLE, factor_vm *> thread_vms; extern std::map<THREADHANDLE, factor_vm *> thread_vms;