@@ -1453,13 +1453,13 @@ mod signal_handler {
1453
1453
/// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the
1454
1454
/// process, print a stack trace and then exit.
1455
1455
pub ( super ) fn install ( ) {
1456
+ use std:: alloc:: { alloc, Layout } ;
1457
+
1456
1458
unsafe {
1457
- const ALT_STACK_SIZE : usize = libc :: MINSIGSTKSZ + 64 * 1024 ;
1459
+ let alt_stack_size : usize = min_sigstack_size ( ) + 64 * 1024 ;
1458
1460
let mut alt_stack: libc:: stack_t = std:: mem:: zeroed ( ) ;
1459
- alt_stack. ss_sp =
1460
- std:: alloc:: alloc ( std:: alloc:: Layout :: from_size_align ( ALT_STACK_SIZE , 1 ) . unwrap ( ) )
1461
- as * mut libc:: c_void ;
1462
- alt_stack. ss_size = ALT_STACK_SIZE ;
1461
+ alt_stack. ss_sp = alloc ( Layout :: from_size_align ( alt_stack_size, 1 ) . unwrap ( ) ) . cast ( ) ;
1462
+ alt_stack. ss_size = alt_stack_size;
1463
1463
libc:: sigaltstack ( & alt_stack, std:: ptr:: null_mut ( ) ) ;
1464
1464
1465
1465
let mut sa: libc:: sigaction = std:: mem:: zeroed ( ) ;
@@ -1469,6 +1469,23 @@ mod signal_handler {
1469
1469
libc:: sigaction ( libc:: SIGSEGV , & sa, std:: ptr:: null_mut ( ) ) ;
1470
1470
}
1471
1471
}
1472
+
1473
+ /// Modern kernels on modern hardware can have dynamic signal stack sizes.
1474
+ #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
1475
+ fn min_sigstack_size ( ) -> usize {
1476
+ const AT_MINSIGSTKSZ : core:: ffi:: c_ulong = 51 ;
1477
+ let dynamic_sigstksz = unsafe { libc:: getauxval ( AT_MINSIGSTKSZ ) } ;
1478
+ // If getauxval couldn't find the entry, it returns 0,
1479
+ // so take the higher of the "constant" and auxval.
1480
+ // This transparently supports older kernels which don't provide AT_MINSIGSTKSZ
1481
+ libc:: MINSIGSTKSZ . max ( dynamic_sigstksz as _ )
1482
+ }
1483
+
1484
+ /// Not all OS support hardware where this is needed.
1485
+ #[ cfg( not( any( target_os = "linux" , target_os = "android" ) ) ) ]
1486
+ fn min_sigstack_size ( ) -> usize {
1487
+ libc:: MINSIGSTKSZ
1488
+ }
1472
1489
}
1473
1490
1474
1491
#[ cfg( not( all( unix, any( target_env = "gnu" , target_os = "macos" ) ) ) ) ]
0 commit comments