about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs93
-rw-r--r--library/std/src/sys_common/backtrace.rs11
-rw-r--r--tests/run-make/short-ice/Makefile9
-rw-r--r--tests/run-make/short-ice/check.sh36
-rw-r--r--tests/run-make/short-ice/src/lib.rs7
-rw-r--r--tests/ui/panics/default-backtrace-ice.stderr2
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames-2.rs61
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr11
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames.rs57
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames.run.stderr12
10 files changed, 259 insertions, 40 deletions
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index 5acfeb47a12..b17db0aa56a 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -488,6 +488,18 @@ macro_rules! expand_if_cached {
     };
 }
 
+/// Don't show the backtrace for query system by default
+/// use `RUST_BACKTRACE=full` to show all the backtraces
+#[inline(never)]
+pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
+where
+    F: FnOnce() -> T,
+{
+    let result = f();
+    std::hint::black_box(());
+    result
+}
+
 // NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros
 // invoked by `rustc_query_append`.
 macro_rules! define_queries {
@@ -498,21 +510,25 @@ macro_rules! define_queries {
             use super::*;
 
             $(
-                #[inline(always)]
-                #[tracing::instrument(level = "trace", skip(tcx))]
-                pub(super) fn $name<'tcx>(
-                    tcx: TyCtxt<'tcx>,
-                    span: Span,
-                    key: query_keys::$name<'tcx>,
-                    mode: QueryMode,
-                ) -> Option<Erase<query_values::$name<'tcx>>> {
-                    get_query_incr(
-                        queries::$name::config(tcx),
-                        QueryCtxt::new(tcx),
-                        span,
-                        key,
-                        mode
-                    )
+                // Adding `__rust_end_short_backtrace` marker to backtraces so that we emit the frames
+                // when `RUST_BACKTRACE=1`, add a new mod with `$name` here is to allow duplicate naming
+                pub mod $name {
+                    use super::*;
+                    #[inline(never)]
+                    pub fn __rust_end_short_backtrace<'tcx>(
+                        tcx: TyCtxt<'tcx>,
+                        span: Span,
+                        key: query_keys::$name<'tcx>,
+                        mode: QueryMode,
+                    ) -> Option<Erase<query_values::$name<'tcx>>> {
+                        get_query_incr(
+                            queries::$name::config(tcx),
+                            QueryCtxt::new(tcx),
+                            span,
+                            key,
+                            mode
+                        )
+                    }
                 }
             )*
         }
@@ -521,20 +537,22 @@ macro_rules! define_queries {
             use super::*;
 
             $(
-                #[inline(always)]
-                #[tracing::instrument(level = "trace", skip(tcx))]
-                pub(super) fn $name<'tcx>(
-                    tcx: TyCtxt<'tcx>,
-                    span: Span,
-                    key: query_keys::$name<'tcx>,
-                    __mode: QueryMode,
-                ) -> Option<Erase<query_values::$name<'tcx>>> {
-                    Some(get_query_non_incr(
-                        queries::$name::config(tcx),
-                        QueryCtxt::new(tcx),
-                        span,
-                        key,
-                    ))
+                pub mod $name {
+                    use super::*;
+                    #[inline(never)]
+                    pub fn __rust_end_short_backtrace<'tcx>(
+                        tcx: TyCtxt<'tcx>,
+                        span: Span,
+                        key: query_keys::$name<'tcx>,
+                        __mode: QueryMode,
+                    ) -> Option<Erase<query_values::$name<'tcx>>> {
+                        Some(get_query_non_incr(
+                            queries::$name::config(tcx),
+                            QueryCtxt::new(tcx),
+                            span,
+                            key,
+                        ))
+                    }
                 }
             )*
         }
@@ -542,11 +560,11 @@ macro_rules! define_queries {
         pub(crate) fn engine(incremental: bool) -> QueryEngine {
             if incremental {
                 QueryEngine {
-                    $($name: get_query_incr::$name,)*
+                    $($name: get_query_incr::$name::__rust_end_short_backtrace,)*
                 }
             } else {
                 QueryEngine {
-                    $($name: get_query_non_incr::$name,)*
+                    $($name: get_query_non_incr::$name::__rust_end_short_backtrace,)*
                 }
             }
         }
@@ -578,10 +596,15 @@ macro_rules! define_queries {
                         query_cache: offset_of!(QueryCaches<'tcx> => $name),
                         cache_on_disk: |tcx, key| ::rustc_middle::query::cached::$name(tcx, key),
                         execute_query: |tcx, key| erase(tcx.$name(key)),
-                        compute: |tcx, key| query_provided_to_value::$name(
-                            tcx,
-                            call_provider!([$($modifiers)*][tcx, $name, key])
-                        ),
+                        compute: |tcx, key| {
+                            use crate::plumbing::__rust_begin_short_backtrace;
+                            __rust_begin_short_backtrace(||
+                                query_provided_to_value::$name(
+                                    tcx,
+                                    call_provider!([$($modifiers)*][tcx, $name, key])
+                                )
+                            )
+                        },
                         can_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] true false),
                         try_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] {
                             |tcx, key, prev_index, index| {
diff --git a/library/std/src/sys_common/backtrace.rs b/library/std/src/sys_common/backtrace.rs
index 8752f46ff81..6f020940df1 100644
--- a/library/std/src/sys_common/backtrace.rs
+++ b/library/std/src/sys_common/backtrace.rs
@@ -68,13 +68,17 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
         }
 
         let mut hit = false;
-        let mut stop = false;
         backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
             hit = true;
+
+            // Any frames between `__rust_begin_short_backtrace` and `__rust_end_short_backtrace`
+            // are omitted from the backtrace in short mode, `__rust_end_short_backtrace` will be
+            // called before the panic hook, so we won't ignore any frames if there is no
+            // invoke of `__rust_begin_short_backtrace`.
             if print_fmt == PrintFmt::Short {
                 if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
                     if start && sym.contains("__rust_begin_short_backtrace") {
-                        stop = true;
+                        start = false;
                         return;
                     }
                     if sym.contains("__rust_end_short_backtrace") {
@@ -88,9 +92,6 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
                 res = bt_fmt.frame().symbol(frame, symbol);
             }
         });
-        if stop {
-            return false;
-        }
         #[cfg(target_os = "nto")]
         if libc::__my_thread_exit as *mut libc::c_void == frame.ip() {
             if !hit && start {
diff --git a/tests/run-make/short-ice/Makefile b/tests/run-make/short-ice/Makefile
new file mode 100644
index 00000000000..4f33d590237
--- /dev/null
+++ b/tests/run-make/short-ice/Makefile
@@ -0,0 +1,9 @@
+include ../tools.mk
+
+# ignore-windows
+
+export RUSTC := $(RUSTC_ORIGINAL)
+export TMPDIR := $(TMPDIR)
+
+all:
+	bash check.sh
diff --git a/tests/run-make/short-ice/check.sh b/tests/run-make/short-ice/check.sh
new file mode 100644
index 00000000000..96cd8fe86bc
--- /dev/null
+++ b/tests/run-make/short-ice/check.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+RUST_BACKTRACE=1 $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-1.log 2>&1
+RUST_BACKTRACE=full $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-2.log 2>&1
+
+short=$(cat $TMPDIR/rust-test-1.log | wc -l)
+full=$(cat $TMPDIR/rust-test-2.log | wc -l)
+rustc_query_count=$(cat $TMPDIR/rust-test-1.log | grep rustc_query_ | wc -l)
+rustc_query_count_full=$(cat $TMPDIR/rust-test-2.log | grep rustc_query_ | wc -l)
+
+begin_count=$(cat $TMPDIR/rust-test-2.log | grep __rust_begin_short_backtrace | wc -l)
+end_count=$(cat $TMPDIR/rust-test-2.log | grep __rust_end_short_backtrace | wc -l)
+
+cat $TMPDIR/rust-test-1.log
+echo "====================="
+cat $TMPDIR/rust-test-2.log
+echo "====================="
+
+echo "short backtrace: $short"
+echo "full  backtrace: $full"
+echo "begin_count: $begin_count"
+echo "end_count  : $end_count"
+echo "rustc_query_count: $rustc_query_count"
+echo "rustc_query_count_full: $rustc_query_count_full"
+
+## backtraces to vary a bit depending on platform and configuration options,
+## here we make sure that the short backtrace of rustc_query is shorter than the full,
+## and marks are in pairs.
+if [ $short -lt $full ] &&
+    [ $begin_count -eq $end_count ] &&
+    [ $(($rustc_query_count + 10)) -lt $rustc_query_count_full ] &&
+    [ $rustc_query_count_full -gt 10 ]; then
+    exit 0
+else
+    exit 1
+fi
diff --git a/tests/run-make/short-ice/src/lib.rs b/tests/run-make/short-ice/src/lib.rs
new file mode 100644
index 00000000000..b23b7f830d7
--- /dev/null
+++ b/tests/run-make/short-ice/src/lib.rs
@@ -0,0 +1,7 @@
+fn func(s: &str) {
+    println!("{}", s);
+}
+
+fn main() {
+    func(1);
+}
diff --git a/tests/ui/panics/default-backtrace-ice.stderr b/tests/ui/panics/default-backtrace-ice.stderr
index ddbfc4e7f3a..815ce4dd015 100644
--- a/tests/ui/panics/default-backtrace-ice.stderr
+++ b/tests/ui/panics/default-backtrace-ice.stderr
@@ -8,6 +8,8 @@ LL | fn main() { missing_ident; }
 stack backtrace:
 (end_short_backtrace)
 (begin_short_backtrace)
+(end_short_backtrace)
+(begin_short_backtrace)
 
 error: the compiler unexpectedly panicked. this is a bug.
 
diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.rs b/tests/ui/panics/short-ice-remove-middle-frames-2.rs
new file mode 100644
index 00000000000..38a80f8b670
--- /dev/null
+++ b/tests/ui/panics/short-ice-remove-middle-frames-2.rs
@@ -0,0 +1,61 @@
+// compile-flags:-Cstrip=none
+// run-fail
+// check-run-results
+// exec-env:RUST_BACKTRACE=1
+// ignore-android FIXME #17520
+// ignore-wasm no panic support
+// ignore-openbsd no support for libbacktrace without filename
+// ignore-emscripten no panic
+// ignore-sgx Backtraces not symbolized
+// ignore-fuchsia Backtraces not symbolized
+// ignore-msvc the `__rust_{begin,end}_short_backtrace` symbols aren't reliable.
+
+/// This test case make sure that we can have multiple pairs of `__rust_{begin,end}_short_backtrace`
+
+#[inline(never)]
+fn __rust_begin_short_backtrace<T, F: FnOnce() -> T>(f: F) -> T {
+    let result = f();
+    std::hint::black_box(result)
+}
+
+#[inline(never)]
+fn __rust_end_short_backtrace<T, F: FnOnce() -> T>(f: F) -> T {
+    let result = f();
+    std::hint::black_box(result)
+}
+
+fn first() {
+    __rust_end_short_backtrace(|| second());
+}
+
+fn second() {
+    third(); // won't show up
+}
+
+fn third() {
+    fourth(); // won't show up
+}
+
+fn fourth() {
+    __rust_begin_short_backtrace(|| fifth());
+}
+
+fn fifth() {
+    __rust_end_short_backtrace(|| sixth());
+}
+
+fn sixth() {
+    seven(); // won't show up
+}
+
+fn seven() {
+    __rust_begin_short_backtrace(|| eight());
+}
+
+fn eight() {
+    panic!("debug!!!");
+}
+
+fn main() {
+    first();
+}
diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
new file mode 100644
index 00000000000..2592b747918
--- /dev/null
+++ b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
@@ -0,0 +1,11 @@
+thread 'main' panicked at 'debug!!!', $DIR/short-ice-remove-middle-frames-2.rs:56:5
+stack backtrace:
+   0: std::panicking::begin_panic
+   1: short_ice_remove_middle_frames_2::eight
+   2: short_ice_remove_middle_frames_2::seven::{{closure}}
+   3: short_ice_remove_middle_frames_2::fifth
+   4: short_ice_remove_middle_frames_2::fourth::{{closure}}
+   5: short_ice_remove_middle_frames_2::first
+   6: short_ice_remove_middle_frames_2::main
+   7: core::ops::function::FnOnce::call_once
+note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
diff --git a/tests/ui/panics/short-ice-remove-middle-frames.rs b/tests/ui/panics/short-ice-remove-middle-frames.rs
new file mode 100644
index 00000000000..c872084f033
--- /dev/null
+++ b/tests/ui/panics/short-ice-remove-middle-frames.rs
@@ -0,0 +1,57 @@
+// compile-flags:-Cstrip=none
+// run-fail
+// check-run-results
+// exec-env:RUST_BACKTRACE=1
+// ignore-android FIXME #17520
+// ignore-wasm no panic support
+// ignore-openbsd no support for libbacktrace without filename
+// ignore-emscripten no panic
+// ignore-sgx Backtraces not symbolized
+// ignore-fuchsia Backtraces not symbolized
+// ignore-msvc the `__rust_{begin,end}_short_backtrace` symbols aren't reliable.
+
+
+#[inline(never)]
+fn __rust_begin_short_backtrace<T, F: FnOnce() -> T>(f: F) -> T {
+    let result = f();
+    std::hint::black_box(result)
+}
+
+#[inline(never)]
+fn __rust_end_short_backtrace<T, F: FnOnce() -> T>(f: F) -> T {
+    let result = f();
+    std::hint::black_box(result)
+}
+
+fn first() {
+    __rust_end_short_backtrace(|| second());
+    // do not take effect since we already has a inner call of __rust_end_short_backtrace
+}
+
+fn second() {
+    __rust_end_short_backtrace(|| third());
+}
+
+fn third() {
+    fourth(); // won't show up in backtrace
+}
+
+fn fourth() {
+    fifth(); // won't show up in backtrace
+}
+
+fn fifth() {
+    __rust_begin_short_backtrace(|| sixth());
+}
+
+fn sixth() {
+    seven();
+}
+
+fn seven() {
+    panic!("debug!!!");
+}
+
+fn main() {
+    first();
+}
diff --git a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr
new file mode 100644
index 00000000000..9c15f2e08fe
--- /dev/null
+++ b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr
@@ -0,0 +1,12 @@
+thread 'main' panicked at 'debug!!!', $DIR/short-ice-remove-middle-frames.rs:52:5
+stack backtrace:
+   0: std::panicking::begin_panic
+   1: short_ice_remove_middle_frames::seven
+   2: short_ice_remove_middle_frames::sixth
+   3: short_ice_remove_middle_frames::fifth::{{closure}}
+   4: short_ice_remove_middle_frames::second
+   5: short_ice_remove_middle_frames::first::{{closure}}
+   6: short_ice_remove_middle_frames::first
+   7: short_ice_remove_middle_frames::main
+   8: core::ops::function::FnOnce::call_once
+note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.