3737#include "caml/memprof.h"
3838#include "caml/finalise.h"
3939#include "caml/printexc.h"
40+ #ifdef __linux__
41+ #include <sys/auxv.h>
42+ #include <linux/auxvec.h>
43+ #endif
4044
4145/* The set of pending signals (received but not yet processed).
4246 It is represented as a bit vector.
@@ -584,12 +588,37 @@ CAMLexport int caml_rev_convert_signal_number(int signo)
584588 return signo ;
585589}
586590
587- void * caml_init_signal_stack (void )
591+ static size_t max_size_t (size_t a , size_t b )
592+ {
593+ return (a > b ) ? a : b ;
594+ }
595+
596+ void * caml_init_signal_stack (size_t * signal_stack_size )
588597{
589598#ifdef POSIX_SIGNALS
590599 stack_t stk ;
591600 stk .ss_flags = 0 ;
601+
602+ #ifdef __linux__
603+ /* On some systems, e.g. when AMX has been enabled on certain glibc versions,
604+ the dynamic value of MINSIGSTKSZ might be larger than SIGSTKSZ and/or any
605+ compile-time MINSIGSTKSZ. As such we compute our own SIGSTKSZ. The
606+ "4 * " scaling factor matches current glibc behaviour.
607+
608+ If the values the system has provided look sensible, however, we
609+ trust SIGSTKSZ. */
610+ size_t at_minsigstksz = getauxval (AT_MINSIGSTKSZ );
611+
612+ if (at_minsigstksz <= MINSIGSTKSZ && MINSIGSTKSZ <= SIGSTKSZ )
613+ stk .ss_size = SIGSTKSZ ;
614+ else
615+ stk .ss_size = max_size_t (
616+ SIGSTKSZ , 4 * max_size_t (MINSIGSTKSZ , at_minsigstksz ));
617+ #else
618+ /* Preserve existing runtime5 behaviour for now. */
592619 stk .ss_size = SIGSTKSZ ;
620+ #endif
621+
593622 /* The memory used for the alternate signal stack must not free'd before
594623 calling sigaltstack with SS_DISABLE. malloc/mmap is therefore used rather
595624 than caml_stat_alloc_noexc so that if a shutdown path erroneously fails
@@ -602,7 +631,7 @@ void * caml_init_signal_stack(void)
602631 if (stk .ss_sp == MAP_FAILED )
603632 return NULL ;
604633 if (sigaltstack (& stk , NULL ) < 0 ) {
605- munmap (stk .ss_sp , SIGSTKSZ );
634+ munmap (stk .ss_sp , stk . ss_size );
606635 return NULL ;
607636 }
608637#else
@@ -614,19 +643,21 @@ void * caml_init_signal_stack(void)
614643 return NULL ;
615644 }
616645#endif /* USE_MMAP_MAP_STACK */
646+ * signal_stack_size = stk .ss_size ;
617647 return stk .ss_sp ;
618648#else
649+ * signal_stack_size = 0 ;
619650 return NULL ;
620651#endif /* POSIX_SIGNALS */
621652}
622653
623- void caml_free_signal_stack (void * signal_stack )
654+ void caml_free_signal_stack (void * signal_stack , size_t signal_stack_size )
624655{
625656#ifdef POSIX_SIGNALS
626657 stack_t stk , disable ;
627658 disable .ss_flags = SS_DISABLE ;
628659 disable .ss_sp = NULL ; /* not required but avoids a valgrind false alarm */
629- disable .ss_size = SIGSTKSZ ; /* macOS wants a valid size here */
660+ disable .ss_size = signal_stack_size ; /* macOS wants a valid size here */
630661 if (sigaltstack (& disable , & stk ) < 0 ) {
631662 caml_fatal_error ("Failed to reset signal stack (err %d)" , errno );
632663 }
@@ -638,7 +669,7 @@ void caml_free_signal_stack(void * signal_stack)
638669 /* Memory was allocated with malloc/mmap directly (see
639670 caml_init_signal_stack) */
640671#ifdef USE_MMAP_MAP_STACK
641- munmap (signal_stack , SIGSTKSZ );
672+ munmap (signal_stack , signal_stack_size );
642673#else
643674 free (signal_stack );
644675#endif /* USE_MMAP_MAP_STACK */
@@ -648,15 +679,18 @@ void caml_free_signal_stack(void * signal_stack)
648679#ifdef POSIX_SIGNALS
649680/* This is the alternate signal stack block for domain 0 */
650681static void * caml_signal_stack_0 = NULL ;
682+ static size_t caml_signal_stack_0_size = 0 ;
651683#endif
652684
653685void caml_init_signals (void )
654686{
655687 /* Set up alternate signal stack for domain 0 */
656688#ifdef POSIX_SIGNALS
657- caml_signal_stack_0 = caml_init_signal_stack ();
689+ errno = 0 ;
690+ caml_signal_stack_0 = caml_init_signal_stack (& caml_signal_stack_0_size );
658691 if (caml_signal_stack_0 == NULL ) {
659- caml_fatal_error ("Failed to allocate signal stack for domain 0" );
692+ caml_fatal_error ("Failed to allocate signal stack for domain 0 (errno %d)" ,
693+ errno );
660694 }
661695
662696 /* gprof installs a signal handler for SIGPROF.
@@ -679,7 +713,7 @@ void caml_init_signals(void)
679713void caml_terminate_signals (void )
680714{
681715#ifdef POSIX_SIGNALS
682- caml_free_signal_stack (caml_signal_stack_0 );
716+ caml_free_signal_stack (caml_signal_stack_0 , caml_signal_stack_0_size );
683717 caml_signal_stack_0 = NULL ;
684718#endif
685719}
0 commit comments