Skip to content

Commit 2443eb4

Browse files
authored
Rollup merge of #69122 - dtolnay:backtrace, r=cramertj
Backtrace Debug tweaks - Change Debug representation of disabled and unsupported backtraces to use \<placeholder\> style, same as what we do for debug printing locked mutexes and mutably borrowed refcells; ```diff - Error { msg: "...", backtrace: disabled backtrace } + Error { msg: "...", backtrace: <disabled> } ``` - Remove quotes around unresolved symbol names; ```diff - Backtrace [{ fn: "<unknown>" }] + Backtrace [{ fn: <unknown> }] ``` - Add quotes around file paths; ```diff - Backtrace [{ fn: "krate::main", file: /path/to/main.rs, line: 10 }] + Backtrace [{ fn: "krate::main", file: "/path/to/main.rs", line: 10 }] ``` - Add test.
2 parents 59b0058 + a2364dc commit 2443eb4

File tree

1 file changed

+84
-7
lines changed

1 file changed

+84
-7
lines changed

src/libstd/backtrace.rs

+84-7
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
// a backtrace or actually symbolizing it.
9393

9494
use crate::env;
95+
use crate::ffi::c_void;
9596
use crate::fmt;
9697
use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
9798
use crate::sync::Mutex;
@@ -144,10 +145,16 @@ fn _assert_send_sync() {
144145
}
145146

146147
struct BacktraceFrame {
147-
frame: backtrace::Frame,
148+
frame: RawFrame,
148149
symbols: Vec<BacktraceSymbol>,
149150
}
150151

152+
enum RawFrame {
153+
Actual(backtrace::Frame),
154+
#[cfg(test)]
155+
Fake,
156+
}
157+
151158
struct BacktraceSymbol {
152159
name: Option<Vec<u8>>,
153160
filename: Option<BytesOrWide>,
@@ -162,8 +169,8 @@ enum BytesOrWide {
162169
impl fmt::Debug for Backtrace {
163170
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
164171
let mut capture = match &self.inner {
165-
Inner::Unsupported => return fmt.write_str("unsupported backtrace"),
166-
Inner::Disabled => return fmt.write_str("disabled backtrace"),
172+
Inner::Unsupported => return fmt.write_str("<unsupported>"),
173+
Inner::Disabled => return fmt.write_str("<disabled>"),
167174
Inner::Captured(c) => c.lock().unwrap(),
168175
};
169176
capture.resolve();
@@ -193,11 +200,11 @@ impl fmt::Debug for BacktraceSymbol {
193200
if let Some(fn_name) = self.name.as_ref().map(|b| backtrace::SymbolName::new(b)) {
194201
write!(fmt, "fn: \"{:#}\"", fn_name)?;
195202
} else {
196-
write!(fmt, "fn: \"<unknown>\"")?;
203+
write!(fmt, "fn: <unknown>")?;
197204
}
198205

199206
if let Some(fname) = self.filename.as_ref() {
200-
write!(fmt, ", file: {:?}", fname)?;
207+
write!(fmt, ", file: \"{:?}\"", fname)?;
201208
}
202209

203210
if let Some(line) = self.lineno.as_ref() {
@@ -293,7 +300,10 @@ impl Backtrace {
293300
let mut actual_start = None;
294301
unsafe {
295302
backtrace::trace_unsynchronized(|frame| {
296-
frames.push(BacktraceFrame { frame: frame.clone(), symbols: Vec::new() });
303+
frames.push(BacktraceFrame {
304+
frame: RawFrame::Actual(frame.clone()),
305+
symbols: Vec::new(),
306+
});
297307
if frame.symbol_address() as usize == ip && actual_start.is_none() {
298308
actual_start = Some(frames.len());
299309
}
@@ -393,8 +403,13 @@ impl Capture {
393403
let _lock = lock();
394404
for frame in self.frames.iter_mut() {
395405
let symbols = &mut frame.symbols;
406+
let frame = match &frame.frame {
407+
RawFrame::Actual(frame) => frame,
408+
#[cfg(test)]
409+
RawFrame::Fake => unimplemented!(),
410+
};
396411
unsafe {
397-
backtrace::resolve_frame_unsynchronized(&frame.frame, |symbol| {
412+
backtrace::resolve_frame_unsynchronized(frame, |symbol| {
398413
symbols.push(BacktraceSymbol {
399414
name: symbol.name().map(|m| m.as_bytes().to_vec()),
400415
filename: symbol.filename_raw().map(|b| match b {
@@ -408,3 +423,65 @@ impl Capture {
408423
}
409424
}
410425
}
426+
427+
impl RawFrame {
428+
fn ip(&self) -> *mut c_void {
429+
match self {
430+
RawFrame::Actual(frame) => frame.ip(),
431+
#[cfg(test)]
432+
RawFrame::Fake => 1 as *mut c_void,
433+
}
434+
}
435+
}
436+
437+
#[test]
438+
fn test_debug() {
439+
let backtrace = Backtrace {
440+
inner: Inner::Captured(Mutex::new(Capture {
441+
actual_start: 1,
442+
resolved: true,
443+
frames: vec![
444+
BacktraceFrame {
445+
frame: RawFrame::Fake,
446+
symbols: vec![BacktraceSymbol {
447+
name: Some(b"std::backtrace::Backtrace::create".to_vec()),
448+
filename: Some(BytesOrWide::Bytes(b"rust/backtrace.rs".to_vec())),
449+
lineno: Some(100),
450+
}],
451+
},
452+
BacktraceFrame {
453+
frame: RawFrame::Fake,
454+
symbols: vec![BacktraceSymbol {
455+
name: Some(b"__rust_maybe_catch_panic".to_vec()),
456+
filename: None,
457+
lineno: None,
458+
}],
459+
},
460+
BacktraceFrame {
461+
frame: RawFrame::Fake,
462+
symbols: vec![
463+
BacktraceSymbol {
464+
name: Some(b"std::rt::lang_start_internal".to_vec()),
465+
filename: Some(BytesOrWide::Bytes(b"rust/rt.rs".to_vec())),
466+
lineno: Some(300),
467+
},
468+
BacktraceSymbol {
469+
name: Some(b"std::rt::lang_start".to_vec()),
470+
filename: Some(BytesOrWide::Bytes(b"rust/rt.rs".to_vec())),
471+
lineno: Some(400),
472+
},
473+
],
474+
},
475+
],
476+
})),
477+
};
478+
479+
#[rustfmt::skip]
480+
let expected = "Backtrace [\
481+
\n { fn: \"__rust_maybe_catch_panic\" },\
482+
\n { fn: \"std::rt::lang_start_internal\", file: \"rust/rt.rs\", line: 300 },\
483+
\n { fn: \"std::rt::lang_start\", file: \"rust/rt.rs\", line: 400 },\
484+
\n]";
485+
486+
assert_eq!(format!("{:#?}", backtrace), expected);
487+
}

0 commit comments

Comments
 (0)