Skip to content

Commit d8cb0c6

Browse files
Start/stop backtraces
1 parent cd53efc commit d8cb0c6

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

library/std/src/panicking.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,9 @@ pub fn begin_panic<M: Any + Send>(msg: M) -> ! {
453453
intrinsics::abort()
454454
}
455455

456-
rust_panic_with_hook(&mut PanicPayload::new(msg), None, Location::caller());
456+
return crate::sys_common::backtrace::__rust_end_short_backtrace(move || {
457+
rust_panic_with_hook(&mut PanicPayload::new(msg), None, Location::caller())
458+
});
457459

458460
struct PanicPayload<A> {
459461
inner: Option<A>,

library/std/src/rt.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ fn lang_start_internal(
4848
sys::args::init(argc, argv);
4949

5050
// Let's run some code!
51-
let exit_code = panic::catch_unwind(|| {
52-
sys_common::backtrace::__rust_begin_short_backtrace(move || main())
53-
});
51+
let exit_code = panic::catch_unwind(main);
5452

5553
sys_common::cleanup();
5654
exit_code.unwrap_or(101) as isize
@@ -64,5 +62,9 @@ fn lang_start<T: crate::process::Termination + 'static>(
6462
argc: isize,
6563
argv: *const *const u8,
6664
) -> isize {
67-
lang_start_internal(&move || main().report(), argc, argv)
65+
lang_start_internal(
66+
&move || crate::sys_common::backtrace::__rust_begin_short_backtrace(main).report(),
67+
argc,
68+
argv,
69+
)
6870
}

library/std/src/sys_common/backtrace.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
7474
bt_fmt.add_context()?;
7575
let mut idx = 0;
7676
let mut res = Ok(());
77+
// Start immediately if we're not using a short backtrace.
78+
let mut start = print_fmt != PrintFmt::Short;
7779
backtrace_rs::trace_unsynchronized(|frame| {
7880
if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES {
7981
return false;
@@ -89,16 +91,24 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
8991
stop = true;
9092
return;
9193
}
94+
if sym.contains("__rust_end_short_backtrace") {
95+
start = true;
96+
return;
97+
}
9298
}
9399
}
94100

95-
res = bt_fmt.frame().symbol(frame, symbol);
101+
if start {
102+
res = bt_fmt.frame().symbol(frame, symbol);
103+
}
96104
});
97105
if stop {
98106
return false;
99107
}
100108
if !hit {
101-
res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
109+
if start {
110+
res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
111+
}
102112
}
103113

104114
idx += 1;
@@ -123,8 +133,22 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
123133
pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
124134
where
125135
F: FnOnce() -> T,
126-
F: Send,
127-
T: Send,
136+
{
137+
let result = f();
138+
139+
// prevent this frame from being tail-call optimised away
140+
crate::hint::black_box(());
141+
142+
result
143+
}
144+
145+
/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that
146+
/// this is only inline(never) when backtraces in libstd are enabled, otherwise
147+
/// it's fine to optimize away.
148+
#[cfg_attr(feature = "backtrace", inline(never))]
149+
pub fn __rust_end_short_backtrace<F, T>(f: F) -> T
150+
where
151+
F: FnOnce() -> T,
128152
{
129153
let result = f();
130154

0 commit comments

Comments
 (0)