@@ -6,6 +6,15 @@ use std::{fmt, mem, ptr, slice};
6
6
7
7
use rustc_interface:: util:: { DEFAULT_STACK_SIZE , STACK_SIZE } ;
8
8
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
+
9
18
unsafe extern "C" {
10
19
fn backtrace_symbols_fd ( buffer : * const * mut libc:: c_void , size : libc:: c_int , fd : libc:: c_int ) ;
11
20
}
@@ -39,8 +48,19 @@ macro raw_errln($tokens:tt) {
39
48
/// # Safety
40
49
///
41
50
/// 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 ) {
43
52
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
+
44
64
let stack = unsafe {
45
65
// Reserve data segment so we don't have to malloc in a signal handler, which might fail
46
66
// 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) {
54
74
} ;
55
75
56
76
// 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
+
58
79
let mut written = 1 ;
59
80
let mut consumed = 0 ;
60
81
// Begin elaborating return addrs into symbols and writing them directly to stderr
@@ -106,13 +127,18 @@ unsafe extern "C" fn print_stack_trace(_: libc::c_int) {
106
127
written += 1 ;
107
128
}
108
129
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
+ }
113
139
if written > 24 {
114
140
// We probably just scrolled the earlier "we got SIGSEGV" message off the terminal
115
- raw_errln ! ( "note: backtrace dumped due to SIGSEGV ! resuming signal" ) ;
141
+ raw_errln ! ( "note: backtrace dumped due to {signame} ! resuming signal" ) ;
116
142
} ;
117
143
}
118
144
@@ -129,7 +155,9 @@ pub(super) fn install() {
129
155
sa. sa_sigaction = print_stack_trace as libc:: sighandler_t ;
130
156
sa. sa_flags = libc:: SA_NODEFER | libc:: SA_RESETHAND | libc:: SA_ONSTACK ;
131
157
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
+ }
133
161
}
134
162
}
135
163
0 commit comments