@@ -6,6 +6,15 @@ use std::{fmt, mem, ptr, slice};
66
77use  rustc_interface:: util:: { DEFAULT_STACK_SIZE ,  STACK_SIZE } ; 
88
9+ /// Signals that represent that we have a bug, and our prompt termination has 
10+ /// been ordered. 
11+ #[ rustfmt:: skip]  
12+ const  KILL_SIGNALS :  [ ( libc:: c_int ,  & str ) ;  3 ]  = [ 
13+     ( libc:: SIGILL ,  "SIGILL" ) , 
14+     ( libc:: SIGBUS ,  "SIGBUS" ) , 
15+     ( libc:: SIGSEGV ,  "SIGSEGV" ) 
16+ ] ; 
17+ 
918unsafe  extern  "C"  { 
1019    fn  backtrace_symbols_fd ( buffer :  * const  * mut  libc:: c_void ,  size :  libc:: c_int ,  fd :  libc:: c_int ) ; 
1120} 
@@ -39,8 +48,19 @@ macro raw_errln($tokens:tt) {
3948/// # Safety 
4049/// 
4150/// Caller must ensure that this function is not re-entered. 
42- unsafe  extern  "C"  fn  print_stack_trace ( _ :  libc:: c_int )  { 
51+ unsafe  extern  "C"  fn  print_stack_trace ( signum :  libc:: c_int )  { 
4352    const  MAX_FRAMES :  usize  = 256 ; 
53+ 
54+     let  signame = { 
55+         let  mut  signame = "<unknown>" ; 
56+         for  sig in  KILL_SIGNALS  { 
57+             if  sig. 0  == signum { 
58+                 signame = sig. 1 ; 
59+             } 
60+         } 
61+         signame
62+     } ; 
63+ 
4464    let  stack = unsafe  { 
4565        // Reserve data segment so we don't have to malloc in a signal handler, which might fail 
4666        // in incredibly undesirable and unexpected ways due to e.g. the allocator deadlocking 
@@ -54,7 +74,8 @@ unsafe extern "C" fn print_stack_trace(_: libc::c_int) {
5474    } ; 
5575
5676    // Just a stack trace is cryptic. Explain what we're doing. 
57-     raw_errln ! ( "error: rustc interrupted by SIGSEGV, printing backtrace\n " ) ; 
77+     raw_errln ! ( "error: rustc interrupted by {signame}, printing backtrace\n " ) ; 
78+ 
5879    let  mut  written = 1 ; 
5980    let  mut  consumed = 0 ; 
6081    // Begin elaborating return addrs into symbols and writing them directly to stderr 
@@ -94,7 +115,7 @@ unsafe extern "C" fn print_stack_trace(_: libc::c_int) {
94115    written += rem. len ( )  + 1 ; 
95116
96117    let  random_depth = || 8  *  16 ;  // chosen by random diceroll (2d20) 
97-     if  cyclic || stack. len ( )  > random_depth ( )  { 
118+     if  ( cyclic || stack. len ( )  > random_depth ( ) )  && signum == libc :: SIGSEGV  { 
98119        // technically speculation, but assert it with confidence anyway. 
99120        // rustc only arrived in this signal handler because bad things happened 
100121        // and this message is for explaining it's not the programmer's fault 
@@ -106,17 +127,22 @@ unsafe extern "C" fn print_stack_trace(_: libc::c_int) {
106127        written += 1 ; 
107128    } 
108129    raw_errln ! ( "note: we would appreciate a report at https://github.com/rust-lang/rust" ) ; 
109-     // get the current stack size WITHOUT blocking and double it 
110-     let  new_size = STACK_SIZE . get ( ) . copied ( ) . unwrap_or ( DEFAULT_STACK_SIZE )  *  2 ; 
111-     raw_errln ! ( "help: you can increase rustc's stack size by setting RUST_MIN_STACK={new_size}" ) ; 
112-     written += 2 ; 
130+     written += 1 ; 
131+     if  signum == libc:: SIGSEGV  { 
132+         // get the current stack size WITHOUT blocking and double it 
133+         let  new_size = STACK_SIZE . get ( ) . copied ( ) . unwrap_or ( DEFAULT_STACK_SIZE )  *  2 ; 
134+         raw_errln ! ( 
135+             "help: you can increase rustc's stack size by setting RUST_MIN_STACK={new_size}" 
136+         ) ; 
137+         written += 1 ; 
138+     } 
113139    if  written > 24  { 
114-         // We probably just scrolled the earlier "we got SIGSEGV " message off the terminal 
115-         raw_errln ! ( "note: backtrace dumped due to SIGSEGV ! resuming signal" ) ; 
140+         // We probably just scrolled the earlier "interrupted by {signame} " message off the terminal 
141+         raw_errln ! ( "note: backtrace dumped due to {signame} ! resuming signal" ) ; 
116142    } ; 
117143} 
118144
119- /// When SIGSEGV  is delivered to the process, print a stack trace and then exit. 
145+ /// When one of the KILL signals  is delivered to the process, print a stack trace and then exit. 
120146pub ( super )  fn  install ( )  { 
121147    unsafe  { 
122148        let  alt_stack_size:  usize  = min_sigstack_size ( )  + 64  *  1024 ; 
@@ -129,7 +155,9 @@ pub(super) fn install() {
129155        sa. sa_sigaction  = print_stack_trace as  libc:: sighandler_t ; 
130156        sa. sa_flags  = libc:: SA_NODEFER  | libc:: SA_RESETHAND  | libc:: SA_ONSTACK ; 
131157        libc:: sigemptyset ( & mut  sa. sa_mask ) ; 
132-         libc:: sigaction ( libc:: SIGSEGV ,  & sa,  ptr:: null_mut ( ) ) ; 
158+         for  ( signum,  _signame)  in  KILL_SIGNALS  { 
159+             libc:: sigaction ( signum,  & sa,  ptr:: null_mut ( ) ) ; 
160+         } 
133161    } 
134162} 
135163
0 commit comments