Skip to content

Commit f39c4c8

Browse files
committed
Stop backtracing if the stack pointer gets stuck
1 parent b605c65 commit f39c4c8

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

library/std/src/sys/backtrace.rs

+13
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,21 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
5858
let mut res = Ok(());
5959
let mut omitted_count: usize = 0;
6060
let mut first_omit = true;
61+
let mut last_sp = core::ptr::null_mut();
62+
let mut sp_stuck = false;
6163
// If we're using a short backtrace, ignore all frames until we're told to start printing.
6264
let mut print = print_fmt != PrintFmt::Short;
6365
set_image_base();
6466
// SAFETY: we roll our own locking in this town
6567
unsafe {
6668
backtrace_rs::trace_unsynchronized(|frame| {
69+
// Break if the stack pointer does not move (see #135717).
70+
// Make sure to skip the first frame to handle the case where the frame pointer is omitted.
71+
if frame.sp() == last_sp && !frame.sp().is_null() && idx > 1 {
72+
sp_stuck = true;
73+
return false;
74+
}
75+
6776
if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES {
6877
return false;
6978
}
@@ -126,11 +135,15 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
126135
}
127136

128137
idx += 1;
138+
last_sp = frame.sp();
129139
res.is_ok()
130140
})
131141
};
132142
res?;
133143
bt_fmt.finish()?;
144+
if sp_stuck {
145+
writeln!(fmt, "note: stack pointer stuck, further frames are omitted")?;
146+
}
134147
if print_fmt == PrintFmt::Short {
135148
writeln!(
136149
fmt,

0 commit comments

Comments
 (0)