@@ -1305,10 +1305,60 @@ pub fn init_env_logger(env: &str) {
13051305 tracing:: subscriber:: set_global_default ( subscriber) . unwrap ( ) ;
13061306}
13071307
1308+ #[ cfg( all( unix, any( target_env = "gnu" , target_os = "macos" ) ) ) ]
1309+ mod signal_handler {
1310+ extern "C" {
1311+ fn backtrace_symbols_fd (
1312+ buffer : * const * mut libc:: c_void ,
1313+ size : libc:: c_int ,
1314+ fd : libc:: c_int ,
1315+ ) ;
1316+ }
1317+
1318+ extern "C" fn print_stack_trace ( _: libc:: c_int ) {
1319+ const MAX_FRAMES : usize = 256 ;
1320+ static mut STACK_TRACE : [ * mut libc:: c_void ; MAX_FRAMES ] =
1321+ [ std:: ptr:: null_mut ( ) ; MAX_FRAMES ] ;
1322+ unsafe {
1323+ let depth = libc:: backtrace ( STACK_TRACE . as_mut_ptr ( ) , MAX_FRAMES as i32 ) ;
1324+ if depth == 0 {
1325+ return ;
1326+ }
1327+ backtrace_symbols_fd ( STACK_TRACE . as_ptr ( ) , depth, 2 ) ;
1328+ }
1329+ }
1330+
1331+ // When an error signal (such as SIGABRT or SIGSEGV) is delivered to the
1332+ // process, print a stack trace and then exit.
1333+ pub ( super ) fn install ( ) {
1334+ unsafe {
1335+ const ALT_STACK_SIZE : usize = libc:: MINSIGSTKSZ + 64 * 1024 ;
1336+ let mut alt_stack: libc:: stack_t = std:: mem:: zeroed ( ) ;
1337+ alt_stack. ss_sp =
1338+ std:: alloc:: alloc ( std:: alloc:: Layout :: from_size_align ( ALT_STACK_SIZE , 1 ) . unwrap ( ) )
1339+ as * mut libc:: c_void ;
1340+ alt_stack. ss_size = ALT_STACK_SIZE ;
1341+ libc:: sigaltstack ( & mut alt_stack, std:: ptr:: null_mut ( ) ) ;
1342+
1343+ let mut sa: libc:: sigaction = std:: mem:: zeroed ( ) ;
1344+ sa. sa_sigaction = print_stack_trace as libc:: sighandler_t ;
1345+ sa. sa_flags = libc:: SA_NODEFER | libc:: SA_RESETHAND | libc:: SA_ONSTACK ;
1346+ libc:: sigemptyset ( & mut sa. sa_mask ) ;
1347+ libc:: sigaction ( libc:: SIGSEGV , & sa, std:: ptr:: null_mut ( ) ) ;
1348+ }
1349+ }
1350+ }
1351+
1352+ #[ cfg( not( all( unix, any( target_env = "gnu" , target_os = "macos" ) ) ) ) ]
1353+ mod signal_handler {
1354+ pub ( super ) fn install ( ) { }
1355+ }
1356+
13081357pub fn main ( ) -> ! {
13091358 let start_time = Instant :: now ( ) ;
13101359 let start_rss = get_resident_set_size ( ) ;
13111360 init_rustc_env_logger ( ) ;
1361+ signal_handler:: install ( ) ;
13121362 let mut callbacks = TimePassesCallbacks :: default ( ) ;
13131363 install_ice_hook ( ) ;
13141364 let exit_code = catch_with_exit_code ( || {
0 commit comments