diff options
| author | Vikram Pal <vikrampal659@gmail.com> | 2020-12-19 08:50:33 +0000 |
|---|---|---|
| committer | Tyler Mandry <tmandry@gmail.com> | 2021-06-16 01:43:20 +0000 |
| commit | 23259660030a583dd78f0d8f263ab5811fc9f75b (patch) | |
| tree | 9ef2a1edc1ac49fb217641c3989b8f59233b86a5 /compiler/rustc_driver/src | |
| parent | 138fd56cf9598b4bf016634c768dca128a83a5d7 (diff) | |
| download | rust-23259660030a583dd78f0d8f263ab5811fc9f75b.tar.gz rust-23259660030a583dd78f0d8f263ab5811fc9f75b.zip | |
Implement printing of stack traces on LLVM segfaults and aborts
Diffstat (limited to 'compiler/rustc_driver/src')
| -rw-r--r-- | compiler/rustc_driver/src/lib.rs | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index c8891734cce..f2206746e26 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1312,10 +1312,55 @@ pub fn init_env_logger(env: &str) { tracing::subscriber::set_global_default(subscriber).unwrap(); } +extern "C" { + // Only available in glibc + fn backtrace_symbols_fd(buffer: *const *mut libc::c_void, size: libc::c_int, fd: libc::c_int); +} + +#[cfg(unix)] +fn print_stack_trace(_: libc::c_int) { + unsafe { + static mut STACK_TRACE: [*mut libc::c_void; 256] = [std::ptr::null_mut(); 256]; + let depth = libc::backtrace(STACK_TRACE.as_mut_ptr(), 256); + if depth == 0 { + return; + } + backtrace_symbols_fd(STACK_TRACE.as_ptr(), depth, 2); + } +} + +#[cfg(unix)] +// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the +// process, print a stack trace and then exit. +fn print_stack_trace_on_error_signal() { + unsafe { + const ALT_STACK_SIZE: usize = libc::MINSIGSTKSZ + 64 * 1024; + let mut alt_stack: libc::stack_t = std::mem::zeroed(); + alt_stack.ss_sp = + std::alloc::alloc(std::alloc::Layout::from_size_align_unchecked(ALT_STACK_SIZE, 1)) + as *mut libc::c_void; + alt_stack.ss_size = ALT_STACK_SIZE; + libc::sigaltstack(&mut alt_stack, std::ptr::null_mut()); + + let mut sa: libc::sigaction = std::mem::zeroed(); + sa.sa_sigaction = + print_stack_trace as fn(libc::c_int) as *mut libc::c_void as libc::sighandler_t; + sa.sa_flags = libc::SA_NODEFER | libc::SA_RESETHAND | libc::SA_ONSTACK; + libc::sigemptyset(&mut sa.sa_mask); + libc::sigaction(libc::SIGSEGV, &sa, std::ptr::null_mut()); + } +} + +#[cfg(windows)] +// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the +// process, print a stack trace and then exit. +fn print_stack_trace_on_error_signal() {} + pub fn main() -> ! { let start_time = Instant::now(); let start_rss = get_resident_set_size(); init_rustc_env_logger(); + print_stack_trace_on_error_signal(); let mut callbacks = TimePassesCallbacks::default(); install_ice_hook(); let exit_code = catch_with_exit_code(|| { |
