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);
|
||||
}
|
||||
|
||||
void init_signals()
|
||||
void factor_vm::init_signals()
|
||||
{
|
||||
unix_init_signals();
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@ namespace factor
|
|||
#define VM_C_API extern "C"
|
||||
#define NULL_DLL NULL
|
||||
|
||||
void c_to_factor_toplevel(cell quot);
|
||||
void init_signals();
|
||||
void early_init();
|
||||
const char *vm_executable_path();
|
||||
const char *default_image_path();
|
||||
|
|
|
@ -5,14 +5,11 @@ namespace factor
|
|||
#define FACTOR_OS_STRING "macosx"
|
||||
#define NULL_DLL "libfactor.dylib"
|
||||
|
||||
void init_signals();
|
||||
void early_init();
|
||||
|
||||
const char *vm_executable_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_TYPE void*
|
||||
|
|
|
@ -70,7 +70,7 @@ const char *default_image_path(void)
|
|||
return [returnVal UTF8String];
|
||||
}
|
||||
|
||||
void init_signals(void)
|
||||
void factor_vm::init_signals(void)
|
||||
{
|
||||
unix_init_signals();
|
||||
mach_initialize();
|
||||
|
@ -87,11 +87,9 @@ Protocol *objc_getProtocol(char *name)
|
|||
|
||||
u64 nano_count()
|
||||
{
|
||||
u64 t;
|
||||
u64 t = mach_absolute_time();
|
||||
mach_timebase_info_data_t info;
|
||||
kern_return_t ret;
|
||||
t = mach_absolute_time();
|
||||
ret = mach_timebase_info(&info);
|
||||
kern_return_t ret = mach_timebase_info(&info);
|
||||
if(ret != 0)
|
||||
fatal_error("mach_timebase_info failed",ret);
|
||||
return t * (info.numer/info.denom);
|
||||
|
|
|
@ -13,7 +13,7 @@ THREADHANDLE start_thread(void *(*start_routine)(void *),void *args)
|
|||
fatal_error("pthread_attr_setdetachstate() failed",0);
|
||||
if (pthread_create (&thread, &attr, start_routine, args) != 0)
|
||||
fatal_error("pthread_create() failed",0);
|
||||
pthread_attr_destroy (&attr);
|
||||
pthread_attr_destroy(&attr);
|
||||
return thread;
|
||||
}
|
||||
|
||||
|
@ -21,9 +21,8 @@ pthread_key_t current_vm_tls_key = 0;
|
|||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 misc_sigaction;
|
||||
struct sigaction fpe_sigaction;
|
||||
|
@ -197,7 +206,7 @@ void unix_init_signals()
|
|||
memset(&memory_sigaction,0,sizeof(struct sigaction));
|
||||
sigemptyset(&memory_sigaction.sa_mask);
|
||||
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(SIGSEGV,&memory_sigaction,NULL);
|
||||
|
@ -205,14 +214,14 @@ void unix_init_signals()
|
|||
memset(&fpe_sigaction,0,sizeof(struct sigaction));
|
||||
sigemptyset(&fpe_sigaction.sa_mask);
|
||||
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);
|
||||
|
||||
memset(&misc_sigaction,0,sizeof(struct sigaction));
|
||||
sigemptyset(&misc_sigaction.sa_mask);
|
||||
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(SIGILL,&misc_sigaction,NULL);
|
||||
|
|
|
@ -39,7 +39,6 @@ typedef pthread_t THREADHANDLE;
|
|||
THREADHANDLE start_thread(void *(*start_routine)(void *),void *args);
|
||||
inline static THREADHANDLE thread_id() { return pthread_self(); }
|
||||
|
||||
void unix_init_signals();
|
||||
void signal_handler(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);
|
||||
}
|
||||
|
||||
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 */
|
||||
#define EPOCH_OFFSET 0x019db1ded53e8000LL
|
||||
|
||||
inline static void init_signals() {}
|
||||
inline static void early_init() {}
|
||||
|
||||
u64 system_micros();
|
||||
|
|
|
@ -13,7 +13,8 @@ factor_vm::factor_vm() :
|
|||
gc_events(NULL),
|
||||
fep_disabled(false),
|
||||
full_output(false),
|
||||
last_nano_count(0)
|
||||
last_nano_count(0),
|
||||
signal_callstack_seg(NULL)
|
||||
{
|
||||
primitive_reset_dispatch_stats();
|
||||
}
|
||||
|
@ -21,6 +22,11 @@ factor_vm::factor_vm() :
|
|||
factor_vm::~factor_vm()
|
||||
{
|
||||
delete_contexts();
|
||||
if(signal_callstack_seg)
|
||||
{
|
||||
delete signal_callstack_seg;
|
||||
signal_callstack_seg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
45
vm/vm.hpp
45
vm/vm.hpp
|
@ -107,6 +107,9 @@ struct factor_vm
|
|||
decrease */
|
||||
u64 last_nano_count;
|
||||
|
||||
/* Stack for signal handlers, only used on Unix */
|
||||
segment *signal_callstack_seg;
|
||||
|
||||
// contexts
|
||||
context *new_context();
|
||||
void delete_context(context *old_context);
|
||||
|
@ -339,7 +342,7 @@ struct factor_vm
|
|||
template<typename Array> bool reallot_array_in_place_p(Array *array, cell capacity);
|
||||
template<typename Array> Array *reallot_array(Array *array_, cell capacity);
|
||||
|
||||
//debug
|
||||
// debug
|
||||
void print_chars(string* str);
|
||||
void print_word(word* word, cell nesting);
|
||||
void print_factor_string(string* str);
|
||||
|
@ -362,7 +365,7 @@ struct factor_vm
|
|||
void factorbug();
|
||||
void primitive_die();
|
||||
|
||||
//arrays
|
||||
// arrays
|
||||
inline void set_array_nth(array *array, cell slot, cell value);
|
||||
array *allot_array(cell capacity, cell fill_);
|
||||
void primitive_array();
|
||||
|
@ -372,7 +375,7 @@ struct factor_vm
|
|||
void primitive_resize_array();
|
||||
cell std_vector_to_array(std::vector<cell> &elements);
|
||||
|
||||
//strings
|
||||
// strings
|
||||
cell string_nth(const string *str, cell index);
|
||||
void set_string_nth_fast(string *str, cell index, cell ch);
|
||||
void set_string_nth_slow(string *str_, cell index, cell ch);
|
||||
|
@ -388,13 +391,13 @@ struct factor_vm
|
|||
void primitive_set_string_nth_fast();
|
||||
void primitive_set_string_nth_slow();
|
||||
|
||||
//booleans
|
||||
// booleans
|
||||
cell tag_boolean(cell untagged)
|
||||
{
|
||||
return (untagged ? true_object : false_object);
|
||||
}
|
||||
|
||||
//byte arrays
|
||||
// byte arrays
|
||||
byte_array *allot_byte_array(cell size);
|
||||
void primitive_byte_array();
|
||||
void primitive_uninitialized_byte_array();
|
||||
|
@ -402,11 +405,11 @@ struct factor_vm
|
|||
|
||||
template<typename Type> byte_array *byte_array_from_value(Type *value);
|
||||
|
||||
//tuples
|
||||
// tuples
|
||||
void primitive_tuple();
|
||||
void primitive_tuple_boa();
|
||||
|
||||
//words
|
||||
// words
|
||||
word *allot_word(cell name_, cell vocab_, cell hashcode_);
|
||||
void primitive_word();
|
||||
void primitive_word_code();
|
||||
|
@ -417,7 +420,7 @@ struct factor_vm
|
|||
cell find_all_words();
|
||||
void compile_all_words();
|
||||
|
||||
//math
|
||||
// math
|
||||
void primitive_bignum_to_fixnum();
|
||||
void primitive_float_to_fixnum();
|
||||
void primitive_fixnum_divint();
|
||||
|
@ -503,7 +506,7 @@ struct factor_vm
|
|||
// tagged
|
||||
template<typename Type> Type *untag_check(cell value);
|
||||
|
||||
//io
|
||||
// io
|
||||
void init_c_io();
|
||||
void io_error();
|
||||
FILE* safe_fopen(char *filename, char *mode);
|
||||
|
@ -526,7 +529,7 @@ struct factor_vm
|
|||
void primitive_fflush();
|
||||
void primitive_fclose();
|
||||
|
||||
//code_block
|
||||
// code_block
|
||||
cell compute_entry_point_address(cell obj);
|
||||
cell compute_entry_point_pic_address(word *w, cell tagged_quot);
|
||||
cell compute_entry_point_pic_address(cell w_);
|
||||
|
@ -563,11 +566,11 @@ struct factor_vm
|
|||
cell code_blocks();
|
||||
void primitive_code_blocks();
|
||||
|
||||
//callbacks
|
||||
// callbacks
|
||||
void init_callbacks(cell size);
|
||||
void primitive_callback();
|
||||
|
||||
//image
|
||||
// image
|
||||
void init_objects(image_header *h);
|
||||
void load_data_heap(FILE *file, image_header *h, vm_parameters *p);
|
||||
void load_code_heap(FILE *file, image_header *h, vm_parameters *p);
|
||||
|
@ -578,7 +581,7 @@ struct factor_vm
|
|||
void fixup_code(cell data_offset, cell code_offset);
|
||||
void load_image(vm_parameters *p);
|
||||
|
||||
//callstack
|
||||
// callstack
|
||||
template<typename Iterator> void iterate_callstack_object(callstack *stack_, Iterator &iterator);
|
||||
void check_frame(stack_frame *frame);
|
||||
callstack *allot_callstack(cell size);
|
||||
|
@ -598,7 +601,7 @@ struct factor_vm
|
|||
void primitive_set_innermost_stack_frame_quot();
|
||||
template<typename Iterator> void iterate_callstack(context *ctx, Iterator &iterator);
|
||||
|
||||
//alien
|
||||
// alien
|
||||
char *pinned_alien_offset(cell obj);
|
||||
cell allot_alien(cell delegate_, cell displacement);
|
||||
cell allot_alien(void *address);
|
||||
|
@ -615,7 +618,7 @@ struct factor_vm
|
|||
cell from_small_struct(cell x, cell y, cell size);
|
||||
cell from_medium_struct(cell x1, cell x2, cell x3, cell x4, cell size);
|
||||
|
||||
//quotations
|
||||
// quotations
|
||||
void primitive_jit_compile();
|
||||
code_block *lazy_jit_compile_block();
|
||||
void primitive_array_to_quotation();
|
||||
|
@ -630,7 +633,7 @@ struct factor_vm
|
|||
cell find_all_quotations();
|
||||
void initialize_all_quotations();
|
||||
|
||||
//dispatch
|
||||
// dispatch
|
||||
cell search_lookup_alist(cell table, cell klass);
|
||||
cell search_lookup_hash(cell table, cell klass, cell hashcode);
|
||||
cell nth_superclass(tuple_layout *layout, fixnum echelon);
|
||||
|
@ -645,7 +648,7 @@ struct factor_vm
|
|||
void primitive_reset_dispatch_stats();
|
||||
void primitive_dispatch_stats();
|
||||
|
||||
//inline cache
|
||||
// inline cache
|
||||
void init_inline_caching(int max_size);
|
||||
void deallocate_inline_cache(cell return_address);
|
||||
cell determine_inline_cache_type(array *cache_entries);
|
||||
|
@ -657,11 +660,11 @@ struct factor_vm
|
|||
void update_pic_transitions(cell pic_size);
|
||||
void *inline_cache_miss(cell return_address);
|
||||
|
||||
//entry points
|
||||
// entry points
|
||||
void c_to_factor(cell quot);
|
||||
void unwind_native_frames(cell quot, stack_frame *to);
|
||||
|
||||
//factor
|
||||
// factor
|
||||
void default_parameters(vm_parameters *p);
|
||||
bool factor_arg(const vm_char *str, const vm_char *arg, cell *value);
|
||||
void init_parameters_from_args(vm_parameters *p, int argc, vm_char **argv);
|
||||
|
@ -685,6 +688,7 @@ struct factor_vm
|
|||
void *ffi_dlsym(dll *dll, symbol_char *symbol);
|
||||
void ffi_dlclose(dll *dll);
|
||||
void c_to_factor_toplevel(cell quot);
|
||||
void init_signals();
|
||||
|
||||
// os-windows
|
||||
#if defined(WINDOWS)
|
||||
|
@ -697,8 +701,10 @@ struct factor_vm
|
|||
void open_console();
|
||||
LONG exception_handler(PEXCEPTION_POINTERS pe);
|
||||
#endif
|
||||
|
||||
#else // UNIX
|
||||
void dispatch_signal(void *uap, void (handler)());
|
||||
void unix_init_signals();
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
@ -707,7 +713,6 @@ struct factor_vm
|
|||
|
||||
factor_vm();
|
||||
~factor_vm();
|
||||
|
||||
};
|
||||
|
||||
extern std::map<THREADHANDLE, factor_vm *> thread_vms;
|
||||
|
|
Loading…
Reference in New Issue