@@ -1312,10 +1312,55 @@ pub fn init_env_logger(env: &str) {
13121312 tracing:: subscriber:: set_global_default ( subscriber) . unwrap ( ) ;
13131313}
13141314
1315+ extern "C" {
1316+ // Only available in glibc
1317+ fn backtrace_symbols_fd ( buffer : * const * mut libc:: c_void , size : libc:: c_int , fd : libc:: c_int ) ;
1318+ }
1319+
1320+ #[ cfg( unix) ]
1321+ fn print_stack_trace ( _: libc:: c_int ) {
1322+ unsafe {
1323+ static mut STACK_TRACE : [ * mut libc:: c_void ; 256 ] = [ std:: ptr:: null_mut ( ) ; 256 ] ;
1324+ let depth = libc:: backtrace ( STACK_TRACE . as_mut_ptr ( ) , 256 ) ;
1325+ if depth == 0 {
1326+ return ;
1327+ }
1328+ backtrace_symbols_fd ( STACK_TRACE . as_ptr ( ) , depth, 2 ) ;
1329+ }
1330+ }
1331+
1332+ #[ cfg( unix) ]
1333+ // When an error signal (such as SIGABRT or SIGSEGV) is delivered to the
1334+ // process, print a stack trace and then exit.
1335+ fn print_stack_trace_on_error_signal ( ) {
1336+ unsafe {
1337+ const ALT_STACK_SIZE : usize = libc:: MINSIGSTKSZ + 64 * 1024 ;
1338+ let mut alt_stack: libc:: stack_t = std:: mem:: zeroed ( ) ;
1339+ alt_stack. ss_sp =
1340+ std:: alloc:: alloc ( std:: alloc:: Layout :: from_size_align_unchecked ( ALT_STACK_SIZE , 1 ) )
1341+ as * mut libc:: c_void ;
1342+ alt_stack. ss_size = ALT_STACK_SIZE ;
1343+ libc:: sigaltstack ( & mut alt_stack, std:: ptr:: null_mut ( ) ) ;
1344+
1345+ let mut sa: libc:: sigaction = std:: mem:: zeroed ( ) ;
1346+ sa. sa_sigaction =
1347+ print_stack_trace as fn ( libc:: c_int ) as * mut libc:: c_void as libc:: sighandler_t ;
1348+ sa. sa_flags = libc:: SA_NODEFER | libc:: SA_RESETHAND | libc:: SA_ONSTACK ;
1349+ libc:: sigemptyset ( & mut sa. sa_mask ) ;
1350+ libc:: sigaction ( libc:: SIGSEGV , & sa, std:: ptr:: null_mut ( ) ) ;
1351+ }
1352+ }
1353+
1354+ #[ cfg( windows) ]
1355+ // When an error signal (such as SIGABRT or SIGSEGV) is delivered to the
1356+ // process, print a stack trace and then exit.
1357+ fn print_stack_trace_on_error_signal ( ) { }
1358+
13151359pub fn main ( ) -> ! {
13161360 let start_time = Instant :: now ( ) ;
13171361 let start_rss = get_resident_set_size ( ) ;
13181362 init_rustc_env_logger ( ) ;
1363+ print_stack_trace_on_error_signal ( ) ;
13191364 let mut callbacks = TimePassesCallbacks :: default ( ) ;
13201365 install_ice_hook ( ) ;
13211366 let exit_code = catch_with_exit_code ( || {
0 commit comments