vm: use sigaltstack to handle callstack overflow properly
parent
e859a32096
commit
9ffe0a69d1
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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*
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -23,7 +23,6 @@ void init_platform_globals()
|
||||||
{
|
{
|
||||||
if(pthread_key_create(¤t_vm_tls_key, NULL) != 0)
|
if(pthread_key_create(¤t_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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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() {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue