about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-05-10 11:37:22 +0000
committerbors <bors@rust-lang.org>2017-05-10 11:37:22 +0000
commit25a161765fb90f2bfc78bda8fef944048e72bd26 (patch)
tree0dc21722451293bbedf2367b1fea0fa06c112bb7 /src/libstd
parent2b97174ada7fb1854269558ed2cf3b089e58beee (diff)
parentca8b75466cef854d30fdf7614c2358b1eb46816e (diff)
downloadrust-25a161765fb90f2bfc78bda8fef944048e72bd26.tar.gz
rust-25a161765fb90f2bfc78bda8fef944048e72bd26.zip
Auto merge of #41815 - Yamakaky:improve-backtrace-bottom, r=alexcrichton
Improve cleaning of the bottom of the backtrace

Following https://github.com/rust-lang/rust/pull/40264. It only cleans the bottom of the trace (after the main). It handles correctly the normal main, tests, benchmarks and threads.

I kept `skipped_before` since it will be used later for the cleaning of the top.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/rt.rs7
-rw-r--r--src/libstd/sys_common/backtrace.rs44
-rw-r--r--src/libstd/thread/mod.rs4
3 files changed, 47 insertions, 8 deletions
diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs
index 6c791cd336d..acff7faf8a7 100644
--- a/src/libstd/rt.rs
+++ b/src/libstd/rt.rs
@@ -29,8 +29,7 @@ pub use panicking::{begin_panic, begin_panic_fmt, update_panic_count};
 
 #[cfg(not(test))]
 #[lang = "start"]
-fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
-    use mem;
+fn lang_start(main: fn(), argc: isize, argv: *const *const u8) -> isize {
     use panic;
     use sys;
     use sys_common;
@@ -54,7 +53,9 @@ fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
         sys::args::init(argc, argv);
 
         // Let's run some code!
-        let res = panic::catch_unwind(mem::transmute::<_, fn()>(main));
+        let res = panic::catch_unwind(|| {
+            ::sys_common::backtrace::__rust_begin_short_backtrace(main)
+        });
         sys_common::cleanup();
         res.is_err()
     };
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index 04fe5f78b03..617218fe7a5 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -93,11 +93,47 @@ fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
     Ok(())
 }
 
-fn filter_frames(_frames: &[Frame],
-                 _format: PrintFormat,
-                 _context: &BacktraceContext) -> (usize, usize)
+/// Returns a number of frames to remove at the beginning and at the end of the
+/// backtrace, according to the backtrace format.
+fn filter_frames(frames: &[Frame],
+                 format: PrintFormat,
+                 context: &BacktraceContext) -> (usize, usize)
 {
-    (0, 0)
+    if format == PrintFormat::Full {
+        return (0, 0);
+    }
+
+    let skipped_before = 0;
+
+    let skipped_after = frames.len() - frames.iter().position(|frame| {
+        let mut is_marker = false;
+        let _ = resolve_symname(*frame, |symname| {
+            if let Some(mangled_symbol_name) = symname {
+                // Use grep to find the concerned functions
+                if mangled_symbol_name.contains("__rust_begin_short_backtrace") {
+                    is_marker = true;
+                }
+            }
+            Ok(())
+        }, context);
+        is_marker
+    }).unwrap_or(frames.len());
+
+    if skipped_before + skipped_after >= frames.len() {
+        // Avoid showing completely empty backtraces
+        return (0, 0);
+    }
+
+    (skipped_before, skipped_after)
+}
+
+
+/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
+#[inline(never)]
+pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
+    where F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
+{
+    f()
 }
 
 /// Controls how the backtrace should be formated.
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 1bb0d9f3bab..4432f898e04 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -365,7 +365,9 @@ impl Builder {
             }
             unsafe {
                 thread_info::set(imp::guard::current(), their_thread);
-                let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f));
+                let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
+                    ::sys_common::backtrace::__rust_begin_short_backtrace(f)
+                }));
                 *their_packet.get() = Some(try_result);
             }
         };