diff --git a/gc.c b/gc.c index b0c9041948..b9c1305060 100644 --- a/gc.c +++ b/gc.c @@ -2403,16 +2403,6 @@ Init_heap(void) heap_add_pages(objspace, heap_eden, gc_params.heap_init_slots / HEAP_PAGE_OBJ_LIMIT); init_mark_stack(&objspace->mark_stack); -#ifdef USE_SIGALTSTACK - { - /* altstack of another threads are allocated in another place */ - rb_thread_t *th = GET_THREAD(); - void *tmp = th->altstack; - th->altstack = malloc(rb_sigaltstack_size()); - free(tmp); /* free previously allocated area */ - } -#endif - objspace->profile.invoke_time = getrusage_time(); finalizer_table = st_init_numtable(); } diff --git a/internal.h b/internal.h index e72785be56..3515767b36 100644 --- a/internal.h +++ b/internal.h @@ -1704,7 +1704,6 @@ int rb_match_nth_defined(int nth, VALUE match); /* signal.c */ extern int ruby_enable_coredump; int rb_get_next_signal(void); -int rb_sigaltstack_size(void); /* st.c */ extern void rb_hash_bulk_insert(long, const VALUE *, VALUE); diff --git a/signal.c b/signal.c index 694661457b..5803f8f0b9 100644 --- a/signal.c +++ b/signal.c @@ -554,7 +554,7 @@ typedef RETSIGTYPE ruby_sigaction_t(int); #endif #ifdef USE_SIGALTSTACK -int +static int rb_sigaltstack_size(void) { /* XXX: BSD_vfprintf() uses >1500KiB stack and x86-64 need >5KiB stack. */ @@ -577,19 +577,18 @@ rb_sigaltstack_size(void) } /* alternate stack for SIGSEGV */ -void -rb_register_sigaltstack(rb_thread_t *th) +void * +rb_register_sigaltstack(void) { stack_t newSS, oldSS; - if (!th->altstack) - rb_bug("rb_register_sigaltstack: th->altstack not initialized\n"); - - newSS.ss_sp = th->altstack; newSS.ss_size = rb_sigaltstack_size(); + newSS.ss_sp = xmalloc(newSS.ss_size); newSS.ss_flags = 0; sigaltstack(&newSS, &oldSS); /* ignore error. */ + + return newSS.ss_sp; } #endif /* USE_SIGALTSTACK */ @@ -1532,9 +1531,7 @@ Init_signal(void) install_sighandler(SIGILL, (sighandler_t)sigill); #endif #ifdef SIGSEGV -# ifdef USE_SIGALTSTACK - rb_register_sigaltstack(GET_THREAD()); -# endif + RB_ALTSTACK_INIT(GET_VM()->main_altstack); install_sighandler(SIGSEGV, (sighandler_t)sigsegv); #endif } diff --git a/thread.c b/thread.c index f0ace8326c..5a4726d1ee 100644 --- a/thread.c +++ b/thread.c @@ -652,11 +652,6 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s rb_thread_list_t *join_list; rb_thread_t *main_th; VALUE errinfo = Qnil; -# ifdef USE_SIGALTSTACK - void rb_register_sigaltstack(rb_thread_t *th); - - rb_register_sigaltstack(th); -# endif if (th == th->vm->main_thread) rb_bug("thread_start_func_2 must not be used for main thread"); diff --git a/thread_pthread.c b/thread_pthread.c index 951885ffa0..43766b26ba 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -840,6 +840,7 @@ static void * thread_start_func_1(void *th_ptr) { rb_thread_t *th = th_ptr; + RB_ALTSTACK_INIT(void *altstack); #if USE_THREAD_CACHE thread_start: #endif @@ -868,6 +869,7 @@ thread_start_func_1(void *th_ptr) } } #endif + RB_ALTSTACK_FREE(altstack); return 0; } diff --git a/vm.c b/vm.c index 1a57f2c6d1..dd67062ee5 100644 --- a/vm.c +++ b/vm.c @@ -2216,6 +2216,7 @@ ruby_vm_destruct(rb_vm_t *vm) vm->frozen_strings = 0; } rb_vm_gvl_destroy(vm); + RB_ALTSTACK_FREE(vm->main_altstack); if (objspace) { rb_objspace_free(objspace); } @@ -2473,9 +2474,6 @@ thread_free(void *ptr) RUBY_GC_INFO("main thread\n"); } else { -#ifdef USE_SIGALTSTACK - free(th->altstack); -#endif ruby_xfree(ptr); } @@ -2535,11 +2533,6 @@ th_init(rb_thread_t *th, VALUE self) th->self = self; rb_threadptr_root_fiber_setup(th); - /* allocate thread stack */ -#ifdef USE_SIGALTSTACK - /* altstack of main thread is reallocated in another place */ - th->altstack = malloc(rb_sigaltstack_size()); -#endif { /* vm_stack_size is word number. * th->vm->default_params.thread_vm_stack_size is byte size. */ diff --git a/vm_core.h b/vm_core.h index 5fa11487f7..a5ba1900c1 100644 --- a/vm_core.h +++ b/vm_core.h @@ -101,7 +101,13 @@ #endif #if defined(SIGSEGV) && defined(HAVE_SIGALTSTACK) && defined(SA_SIGINFO) && !defined(__NetBSD__) -#define USE_SIGALTSTACK +# define USE_SIGALTSTACK +void *rb_register_sigaltstack(void); +# define RB_ALTSTACK_INIT(var) var = rb_register_sigaltstack() +# define RB_ALTSTACK_FREE(var) xfree(var) +#else /* noop */ +# define RB_ALTSTACK_INIT(var) +# define RB_ALTSTACK_FREE(var) #endif /*****************/ @@ -538,6 +544,9 @@ typedef struct rb_vm_struct { struct rb_thread_struct *main_thread; struct rb_thread_struct *running_thread; +#ifdef USE_SIGALTSTACK + void *main_altstack; +#endif rb_serial_t fork_gen; struct list_head waiting_fds; /* <=> struct waiting_fd */ @@ -883,9 +892,6 @@ typedef struct rb_thread_struct { /* misc */ unsigned int abort_on_exception: 1; unsigned int report_on_exception: 1; -#ifdef USE_SIGALTSTACK - void *altstack; -#endif uint32_t running_time_us; /* 12500..800000 */ VALUE name; } rb_thread_t;