Skip to content

Commit 9495da5

Browse files
committed
Install more signal stack trace handlers
1 parent 4229b80 commit 9495da5

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

compiler/rustc_driver_impl/src/signal_handler.rs

+30-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@ use std::{fmt, mem, ptr, slice};
66

77
use 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+
const KILL_SIGNALS: [(libc::c_int, &str); 7] = [
12+
(libc::SIGILL, "SIGILL"),
13+
(libc::SIGTRAP, "SIGTRAP"),
14+
(libc::SIGABRT, "SIGABRT"),
15+
(libc::SIGFPE, "SIGFPE"),
16+
(libc::SIGBUS, "SIGBUS"),
17+
(libc::SIGSEGV, "SIGSEGV"),
18+
(libc::SIGQUIT, "SIGQUIT"),
19+
];
20+
921
unsafe extern "C" {
1022
fn backtrace_symbols_fd(buffer: *const *mut libc::c_void, size: libc::c_int, fd: libc::c_int);
1123
}
@@ -39,8 +51,19 @@ macro raw_errln($tokens:tt) {
3951
/// # Safety
4052
///
4153
/// Caller must ensure that this function is not re-entered.
42-
unsafe extern "C" fn print_stack_trace(_: libc::c_int) {
54+
unsafe extern "C" fn print_stack_trace(signum: libc::c_int) {
4355
const MAX_FRAMES: usize = 256;
56+
57+
let signame = {
58+
let mut signame = "<unknown>";
59+
for sig in KILL_SIGNALS {
60+
if sig.0 == signum {
61+
signame = sig.1;
62+
}
63+
}
64+
signame
65+
};
66+
4467
let stack = unsafe {
4568
// Reserve data segment so we don't have to malloc in a signal handler, which might fail
4669
// in incredibly undesirable and unexpected ways due to e.g. the allocator deadlocking
@@ -54,7 +77,8 @@ unsafe extern "C" fn print_stack_trace(_: libc::c_int) {
5477
};
5578

5679
// Just a stack trace is cryptic. Explain what we're doing.
57-
raw_errln!("error: rustc interrupted by SIGSEGV, printing backtrace\n");
80+
raw_errln!("error: rustc interrupted by {signame}, printing backtrace\n");
81+
5882
let mut written = 1;
5983
let mut consumed = 0;
6084
// Begin elaborating return addrs into symbols and writing them directly to stderr
@@ -112,7 +136,7 @@ unsafe extern "C" fn print_stack_trace(_: libc::c_int) {
112136
written += 2;
113137
if written > 24 {
114138
// We probably just scrolled the earlier "we got SIGSEGV" message off the terminal
115-
raw_errln!("note: backtrace dumped due to SIGSEGV! resuming signal");
139+
raw_errln!("note: backtrace dumped due to {signame}! resuming signal");
116140
};
117141
}
118142

@@ -129,7 +153,9 @@ pub(super) fn install() {
129153
sa.sa_sigaction = print_stack_trace as libc::sighandler_t;
130154
sa.sa_flags = libc::SA_NODEFER | libc::SA_RESETHAND | libc::SA_ONSTACK;
131155
libc::sigemptyset(&mut sa.sa_mask);
132-
libc::sigaction(libc::SIGSEGV, &sa, ptr::null_mut());
156+
for (signum, _signame) in KILL_SIGNALS {
157+
libc::sigaction(signum, &sa, ptr::null_mut());
158+
}
133159
}
134160
}
135161

0 commit comments

Comments
 (0)