Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions library/std/src/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ use crate::panic::UnwindSafe;
use crate::sync::LazyLock;
use crate::sync::atomic::Ordering::Relaxed;
use crate::sync::atomic::{Atomic, AtomicU8};
#[unstable(
feature = "short_backtrace_controls",
reason = "to control abbreviation of backtraces",
issue = "none"
)]
#[doc(hidden)]
pub use crate::sys::backtrace::{
__rust_begin_short_backtrace as resume_short_backtrace,
__rust_end_short_backtrace as pause_short_backtrace,
};
use crate::sys::backtrace::{lock, output_filename, set_image_base};
use crate::{env, fmt};

Expand Down
93 changes: 66 additions & 27 deletions library/std/src/sys/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use crate::backtrace_rs::{self, BacktraceFmt, BytesOrWideString, PrintFmt};
use crate::borrow::Cow;
use crate::io::prelude::*;
use crate::mem::{ManuallyDrop, MaybeUninit};
use crate::path::{self, Path, PathBuf};
use crate::sync::{Mutex, MutexGuard, PoisonError};
use crate::{env, fmt, io};
Expand Down Expand Up @@ -81,12 +82,26 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
let frame_ip = frame.ip();
res = writeln!(bt_fmt.formatter(), "{idx:4}: {frame_ip:HEX_WIDTH$?}");
} else {
// `call_with_end_short_backtrace_marker` means we are done hiding symbols
// for now. Print until we see `call_with_begin_short_backtrace_marker`.
if print_fmt == PrintFmt::Short {
let sym = frame.symbol_address();
if sym == call_with_end_short_backtrace_marker as _ {
print = true;
return true;
} else if print && sym == call_with_begin_short_backtrace_marker as _ {
print = false;
return true;
}
}

let mut hit = false;
backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
hit = true;

// `__rust_end_short_backtrace` means we are done hiding symbols
// for now. Print until we see `__rust_begin_short_backtrace`.
// Hide `__rust_[begin|end]_short_backtrace` frames from short backtraces.
// Unfortunately these generic functions have to be matched by name, as we do
// not know their generic parameters.
if print_fmt == PrintFmt::Short {
if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
if sym.contains("__rust_end_short_backtrace") {
Expand Down Expand Up @@ -155,36 +170,60 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
Ok(())
}

/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that
/// this is only inline(never) when backtraces in std are enabled, otherwise
/// it's fine to optimize away.
#[cfg_attr(feature = "backtrace", inline(never))]
pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
where
F: FnOnce() -> T,
{
let result = f();
macro_rules! short_backtrace_controls {
($($adapter:ident => $marker:ident($unique:literal)),* $(,)?) => {$(
/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that
/// this is only inline(never) when backtraces in std are enabled, otherwise
/// it's fine to optimize away.
///
/// It is guaranteed that `f` will be called exactly once, and `unsafe` code may
/// rely on this to be the case.
#[cfg_attr(feature = "backtrace", inline(never))]
fn $marker(f: &mut dyn FnMut()) {
f();

// (Try to) prevent both Identical Code Folding (which might merge the different
// versions of this function, giving them the same address) and Tail Call Optimisation
// (which could remove their frames from the call stack).
crate::hint::black_box($unique);
}

// prevent this frame from being tail-call optimised away
crate::hint::black_box(());
/// Invokes `$marker` with an adaptation of `f`, returning its result.
/// This is a more ergonomic interface for placing the marker frame on the stack than
/// the `$marker` function itself. It can be inlined without problem.
#[doc(hidden)]
#[unstable(
feature = "short_backtrace_controls",
reason = "to control abbreviation of backtraces",
issue = "none"
)]
#[inline(always)]
pub fn $adapter<F, T>(f: F) -> T
where
F: FnOnce() -> T,
{
let mut result = MaybeUninit::<T>::uninit();
let mut f = ManuallyDrop::new(f);

result
}
let mut adapted = || {
// SAFETY: `adapted` is called exactly once, by `$marker`;
// and the `ManuallyDrop` is not otherwise used again.
let f = unsafe { ManuallyDrop::take(&mut f) };
result.write(f());
};

/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that
/// this is only inline(never) when backtraces in std are enabled, otherwise
/// it's fine to optimize away.
#[cfg_attr(feature = "backtrace", inline(never))]
pub fn __rust_end_short_backtrace<F, T>(f: F) -> T
where
F: FnOnce() -> T,
{
let result = f();
$marker(&mut adapted);

// prevent this frame from being tail-call optimised away
crate::hint::black_box(());
// SAFETY: `$marker` guaranteed that it would call `adapted`, which
// initialized `result`.
unsafe { result.assume_init() }
}
)*};
}

result
short_backtrace_controls! {
__rust_begin_short_backtrace => call_with_begin_short_backtrace_marker(0),
__rust_end_short_backtrace => call_with_end_short_backtrace_marker(1),
}

/// Prints the filename of the backtrace frame.
Expand Down
16 changes: 10 additions & 6 deletions src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ LL | crate::process::abort()
= note: stack backtrace:
0: std::alloc::rust_oom::{closure#0}
at RUSTLIB/std/src/alloc.rs:LL:CC
1: std::sys::backtrace::__rust_end_short_backtrace
1: std::backtrace::__rust_end_short_backtrace::{closure#0}
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
2: std::alloc::rust_oom
2: std::sys::backtrace::call_with_end_short_backtrace_marker
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
3: std::backtrace::__rust_end_short_backtrace
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
4: std::alloc::rust_oom
at RUSTLIB/std/src/alloc.rs:LL:CC
3: std::alloc::_::__rust_alloc_error_handler
5: std::alloc::_::__rust_alloc_error_handler
at RUSTLIB/std/src/alloc.rs:LL:CC
4: std::alloc::handle_alloc_error::rt_error
6: std::alloc::handle_alloc_error::rt_error
at RUSTLIB/alloc/src/alloc.rs:LL:CC
5: std::alloc::handle_alloc_error
7: std::alloc::handle_alloc_error
at RUSTLIB/alloc/src/alloc.rs:LL:CC
6: main
8: main
at tests/fail/alloc/alloc_error_handler.rs:LL:CC

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
Expand Down
10 changes: 7 additions & 3 deletions src/tools/miri/tests/fail/panic/panic_abort1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ LL | crate::process::abort();
at RUSTLIB/std/src/panicking.rs:LL:CC
4: std::panicking::panic_handler::{closure#0}
at RUSTLIB/std/src/panicking.rs:LL:CC
5: std::sys::backtrace::__rust_end_short_backtrace
5: std::backtrace::__rust_end_short_backtrace::{closure#0}
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
6: std::panicking::panic_handler
6: std::sys::backtrace::call_with_end_short_backtrace_marker
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
7: std::backtrace::__rust_end_short_backtrace
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
8: std::panicking::panic_handler
at RUSTLIB/std/src/panicking.rs:LL:CC
7: main
9: main
at RUSTLIB/core/src/panic.rs:LL:CC

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
Expand Down
10 changes: 7 additions & 3 deletions src/tools/miri/tests/fail/panic/panic_abort2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ LL | crate::process::abort();
at RUSTLIB/std/src/panicking.rs:LL:CC
4: std::panicking::panic_handler::{closure#0}
at RUSTLIB/std/src/panicking.rs:LL:CC
5: std::sys::backtrace::__rust_end_short_backtrace
5: std::backtrace::__rust_end_short_backtrace::{closure#0}
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
6: std::panicking::panic_handler
6: std::sys::backtrace::call_with_end_short_backtrace_marker
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
7: std::backtrace::__rust_end_short_backtrace
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
8: std::panicking::panic_handler
at RUSTLIB/std/src/panicking.rs:LL:CC
7: main
9: main
at RUSTLIB/core/src/panic.rs:LL:CC

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
Expand Down
10 changes: 7 additions & 3 deletions src/tools/miri/tests/fail/panic/panic_abort3.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ LL | crate::process::abort();
at RUSTLIB/std/src/panicking.rs:LL:CC
4: std::panicking::panic_handler::{closure#0}
at RUSTLIB/std/src/panicking.rs:LL:CC
5: std::sys::backtrace::__rust_end_short_backtrace
5: std::backtrace::__rust_end_short_backtrace::{closure#0}
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
6: std::panicking::panic_handler
6: std::sys::backtrace::call_with_end_short_backtrace_marker
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
7: std::backtrace::__rust_end_short_backtrace
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
8: std::panicking::panic_handler
at RUSTLIB/std/src/panicking.rs:LL:CC
7: main
9: main
at RUSTLIB/core/src/panic.rs:LL:CC

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
Expand Down
10 changes: 7 additions & 3 deletions src/tools/miri/tests/fail/panic/panic_abort4.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ LL | crate::process::abort();
at RUSTLIB/std/src/panicking.rs:LL:CC
4: std::panicking::panic_handler::{closure#0}
at RUSTLIB/std/src/panicking.rs:LL:CC
5: std::sys::backtrace::__rust_end_short_backtrace
5: std::backtrace::__rust_end_short_backtrace::{closure#0}
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
6: std::panicking::panic_handler
6: std::sys::backtrace::call_with_end_short_backtrace_marker
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
7: std::backtrace::__rust_end_short_backtrace
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
8: std::panicking::panic_handler
at RUSTLIB/std/src/panicking.rs:LL:CC
7: main
9: main
at RUSTLIB/core/src/panic.rs:LL:CC

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
Expand Down
28 changes: 16 additions & 12 deletions src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,33 @@ LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
= note: stack backtrace:
0: <fn() as std::ops::FnOnce<()>>::call_once - shim(fn())
at RUSTLIB/core/src/ops/function.rs:LL:CC
1: std::sys::backtrace::__rust_begin_short_backtrace
1: std::backtrace::__rust_begin_short_backtrace::{closure#0}
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
2: std::rt::lang_start::{closure#0}
2: std::sys::backtrace::call_with_begin_short_backtrace_marker
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
3: std::backtrace::__rust_begin_short_backtrace
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
4: std::rt::lang_start::{closure#0}
at RUSTLIB/std/src/rt.rs:LL:CC
3: std::ops::function::impls::call_once
5: std::ops::function::impls::call_once
at RUSTLIB/core/src/ops/function.rs:LL:CC
4: std::panicking::catch_unwind::do_call
6: std::panicking::catch_unwind::do_call
at RUSTLIB/std/src/panicking.rs:LL:CC
5: std::panicking::catch_unwind
7: std::panicking::catch_unwind
at RUSTLIB/std/src/panicking.rs:LL:CC
6: std::panic::catch_unwind
8: std::panic::catch_unwind
at RUSTLIB/std/src/panic.rs:LL:CC
7: std::rt::lang_start_internal::{closure#0}
9: std::rt::lang_start_internal::{closure#0}
at RUSTLIB/std/src/rt.rs:LL:CC
8: std::panicking::catch_unwind::do_call
10: std::panicking::catch_unwind::do_call
at RUSTLIB/std/src/panicking.rs:LL:CC
9: std::panicking::catch_unwind
11: std::panicking::catch_unwind
at RUSTLIB/std/src/panicking.rs:LL:CC
10: std::panic::catch_unwind
12: std::panic::catch_unwind
at RUSTLIB/std/src/panic.rs:LL:CC
11: std::rt::lang_start_internal
13: std::rt::lang_start_internal
at RUSTLIB/std/src/rt.rs:LL:CC
12: std::rt::lang_start
14: std::rt::lang_start
at RUSTLIB/std/src/rt.rs:LL:CC

error: aborting due to 1 previous error
Expand Down
4 changes: 3 additions & 1 deletion src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ tests/pass/backtrace/backtrace-api-v1.rs:LL:CC (func_b)
tests/pass/backtrace/backtrace-api-v1.rs:LL:CC (func_a)
tests/pass/backtrace/backtrace-api-v1.rs:LL:CC (main)
RUSTLIB/core/src/ops/function.rs:LL:CC (<fn() as std::ops::FnOnce<()>>::call_once - shim(fn()))
RUSTLIB/std/src/sys/backtrace.rs:LL:CC (std::sys::backtrace::__rust_begin_short_backtrace)
RUSTLIB/std/src/sys/backtrace.rs:LL:CC (std::backtrace::__rust_begin_short_backtrace::{closure#0})
RUSTLIB/std/src/sys/backtrace.rs:LL:CC (std::sys::backtrace::call_with_begin_short_backtrace_marker)
RUSTLIB/std/src/sys/backtrace.rs:LL:CC (std::backtrace::__rust_begin_short_backtrace)
RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start::{closure#0})
RUSTLIB/core/src/ops/function.rs:LL:CC (std::ops::function::impls::call_once)
RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::catch_unwind::do_call)
Expand Down
28 changes: 16 additions & 12 deletions src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,31 @@
at tests/pass/backtrace/backtrace-global-alloc.rs:LL:CC
1: <fn() as std::ops::FnOnce<()>>::call_once - shim(fn())
at RUSTLIB/core/src/ops/function.rs:LL:CC
2: std::sys::backtrace::__rust_begin_short_backtrace
2: std::backtrace::__rust_begin_short_backtrace::{closure#0}
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
3: std::rt::lang_start::{closure#0}
3: std::sys::backtrace::call_with_begin_short_backtrace_marker
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
4: std::backtrace::__rust_begin_short_backtrace
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
5: std::rt::lang_start::{closure#0}
at RUSTLIB/std/src/rt.rs:LL:CC
4: std::ops::function::impls::call_once
6: std::ops::function::impls::call_once
at RUSTLIB/core/src/ops/function.rs:LL:CC
5: std::panicking::catch_unwind::do_call
7: std::panicking::catch_unwind::do_call
at RUSTLIB/std/src/panicking.rs:LL:CC
6: std::panicking::catch_unwind
8: std::panicking::catch_unwind
at RUSTLIB/std/src/panicking.rs:LL:CC
7: std::panic::catch_unwind
9: std::panic::catch_unwind
at RUSTLIB/std/src/panic.rs:LL:CC
8: std::rt::lang_start_internal::{closure#0}
10: std::rt::lang_start_internal::{closure#0}
at RUSTLIB/std/src/rt.rs:LL:CC
9: std::panicking::catch_unwind::do_call
11: std::panicking::catch_unwind::do_call
at RUSTLIB/std/src/panicking.rs:LL:CC
10: std::panicking::catch_unwind
12: std::panicking::catch_unwind
at RUSTLIB/std/src/panicking.rs:LL:CC
11: std::panic::catch_unwind
13: std::panic::catch_unwind
at RUSTLIB/std/src/panic.rs:LL:CC
12: std::rt::lang_start_internal
14: std::rt::lang_start_internal
at RUSTLIB/std/src/rt.rs:LL:CC
13: std::rt::lang_start
15: std::rt::lang_start
at RUSTLIB/std/src/rt.rs:LL:CC
28 changes: 16 additions & 12 deletions src/tools/miri/tests/pass/backtrace/backtrace-std.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,31 @@
at tests/pass/backtrace/backtrace-std.rs:LL:CC
5: <fn() as std::ops::FnOnce<()>>::call_once - shim(fn())
at RUSTLIB/core/src/ops/function.rs:LL:CC
6: std::sys::backtrace::__rust_begin_short_backtrace
6: std::backtrace::__rust_begin_short_backtrace::{closure#0}
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
7: std::rt::lang_start::{closure#0}
7: std::sys::backtrace::call_with_begin_short_backtrace_marker
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
8: std::backtrace::__rust_begin_short_backtrace
at RUSTLIB/std/src/sys/backtrace.rs:LL:CC
9: std::rt::lang_start::{closure#0}
at RUSTLIB/std/src/rt.rs:LL:CC
8: std::ops::function::impls::call_once
10: std::ops::function::impls::call_once
at RUSTLIB/core/src/ops/function.rs:LL:CC
9: std::panicking::catch_unwind::do_call
11: std::panicking::catch_unwind::do_call
at RUSTLIB/std/src/panicking.rs:LL:CC
10: std::panicking::catch_unwind
12: std::panicking::catch_unwind
at RUSTLIB/std/src/panicking.rs:LL:CC
11: std::panic::catch_unwind
13: std::panic::catch_unwind
at RUSTLIB/std/src/panic.rs:LL:CC
12: std::rt::lang_start_internal::{closure#0}
14: std::rt::lang_start_internal::{closure#0}
at RUSTLIB/std/src/rt.rs:LL:CC
13: std::panicking::catch_unwind::do_call
15: std::panicking::catch_unwind::do_call
at RUSTLIB/std/src/panicking.rs:LL:CC
14: std::panicking::catch_unwind
16: std::panicking::catch_unwind
at RUSTLIB/std/src/panicking.rs:LL:CC
15: std::panic::catch_unwind
17: std::panic::catch_unwind
at RUSTLIB/std/src/panic.rs:LL:CC
16: std::rt::lang_start_internal
18: std::rt::lang_start_internal
at RUSTLIB/std/src/rt.rs:LL:CC
17: std::rt::lang_start
19: std::rt::lang_start
at RUSTLIB/std/src/rt.rs:LL:CC
Loading
Loading