diff --git a/src/libstd/sys_common/util.rs b/src/libstd/sys_common/util.rs index a373e980b970d..c70d8ac15d31a 100644 --- a/src/libstd/sys_common/util.rs +++ b/src/libstd/sys_common/util.rs @@ -13,6 +13,9 @@ use io::prelude::*; use sys::stdio::{Stderr, stderr_prints_nothing}; use thread; +#[cfg(feature = "backtrace")] +use sys_common::backtrace; + pub fn dumb_print(args: fmt::Arguments) { if stderr_prints_nothing() { return @@ -34,4 +37,21 @@ pub fn abort(args: fmt::Arguments) -> ! { pub unsafe fn report_overflow() { dumb_print(format_args!("\nthread '{}' has overflowed its stack\n", thread::current().name().unwrap_or(""))); + + #[cfg(feature = "backtrace")] + { + let log_backtrace = backtrace::log_enabled(); + + use sync::atomic::{AtomicBool, Ordering}; + + static FIRST_OVERFLOW: AtomicBool = AtomicBool::new(true); + + if let Some(format) = log_backtrace { + if let Ok(mut stderr) = Stderr::new() { + let _ = backtrace::print(&mut stderr, format); + } + } else if FIRST_OVERFLOW.compare_and_swap(true, false, Ordering::SeqCst) { + dumb_print(format_args!("note: Run with `RUST_BACKTRACE=1` for a backtrace.")); + } + } } diff --git a/src/test/run-pass/stack-probes.rs b/src/test/run-pass/stack-probes.rs index c93dcf019397b..6ca51620adcfc 100644 --- a/src/test/run-pass/stack-probes.rs +++ b/src/test/run-pass/stack-probes.rs @@ -73,4 +73,5 @@ fn assert_overflow(cmd: &mut Command) { println!("stderr: {}", stderr); assert!(stdout.is_empty()); assert!(stderr.contains("has overflowed its stack\n")); + assert!(stderr.contains("::")); }