Skip to content

Commit 2325966

Browse files
in42tmandry
authored andcommitted
Implement printing of stack traces on LLVM segfaults and aborts
1 parent 138fd56 commit 2325966

File tree

1 file changed

+45
-0
lines changed
  • compiler/rustc_driver/src

1 file changed

+45
-0
lines changed

compiler/rustc_driver/src/lib.rs

+45
Original file line numberDiff line numberDiff line change
@@ -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+
13151359
pub 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

Comments
 (0)