From 3ba89e87503e25aece0318a9851f8dba5ccd94a2 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Feb 2020 00:11:16 -0800 Subject: [PATCH 1/6] Remove quotes around unknown fn placeholder in backtrace --- src/libstd/backtrace.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs index 97db0ff3791d7..b14486471ffd7 100644 --- a/src/libstd/backtrace.rs +++ b/src/libstd/backtrace.rs @@ -193,7 +193,7 @@ impl fmt::Debug for BacktraceSymbol { if let Some(fn_name) = self.name.as_ref().map(|b| backtrace::SymbolName::new(b)) { write!(fmt, "fn: \"{:#}\"", fn_name)?; } else { - write!(fmt, "fn: \"\"")?; + write!(fmt, "fn: ")?; } if let Some(fname) = self.filename.as_ref() { From db75b6a91f67008ec789d9934f8a73e09fd0d472 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Feb 2020 00:11:52 -0800 Subject: [PATCH 2/6] Add quotes around filename in Backtrace debug --- src/libstd/backtrace.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs index b14486471ffd7..cc842ebd5894c 100644 --- a/src/libstd/backtrace.rs +++ b/src/libstd/backtrace.rs @@ -197,7 +197,7 @@ impl fmt::Debug for BacktraceSymbol { } if let Some(fname) = self.filename.as_ref() { - write!(fmt, ", file: {:?}", fname)?; + write!(fmt, ", file: \"{:?}\"", fname)?; } if let Some(line) = self.lineno.as_ref() { From 1f1ca877b7002e3ac45916df5415fde1584775ab Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Feb 2020 00:12:26 -0800 Subject: [PATCH 3/6] Change disabled and unsupported backtraces to print using placeholder style --- src/libstd/backtrace.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs index cc842ebd5894c..c64eb9f8e409b 100644 --- a/src/libstd/backtrace.rs +++ b/src/libstd/backtrace.rs @@ -162,8 +162,8 @@ enum BytesOrWide { impl fmt::Debug for Backtrace { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { let mut capture = match &self.inner { - Inner::Unsupported => return fmt.write_str("unsupported backtrace"), - Inner::Disabled => return fmt.write_str("disabled backtrace"), + Inner::Unsupported => return fmt.write_str(""), + Inner::Disabled => return fmt.write_str(""), Inner::Captured(c) => c.lock().unwrap(), }; capture.resolve(); From a9cc010c4883bafba1304f6fd581343f5b1b3ba2 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Feb 2020 00:13:48 -0800 Subject: [PATCH 4/6] Make it possible to instantiate hardcoded Backtrace from test --- src/libstd/backtrace.rs | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs index c64eb9f8e409b..04fd80ecbdb23 100644 --- a/src/libstd/backtrace.rs +++ b/src/libstd/backtrace.rs @@ -92,6 +92,7 @@ // a backtrace or actually symbolizing it. use crate::env; +use crate::ffi::c_void; use crate::fmt; use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use crate::sync::Mutex; @@ -144,10 +145,16 @@ fn _assert_send_sync() { } struct BacktraceFrame { - frame: backtrace::Frame, + frame: RawFrame, symbols: Vec, } +enum RawFrame { + Actual(backtrace::Frame), + #[cfg(test)] + Fake, +} + struct BacktraceSymbol { name: Option>, filename: Option, @@ -293,7 +300,10 @@ impl Backtrace { let mut actual_start = None; unsafe { backtrace::trace_unsynchronized(|frame| { - frames.push(BacktraceFrame { frame: frame.clone(), symbols: Vec::new() }); + frames.push(BacktraceFrame { + frame: RawFrame::Actual(frame.clone()), + symbols: Vec::new(), + }); if frame.symbol_address() as usize == ip && actual_start.is_none() { actual_start = Some(frames.len()); } @@ -393,8 +403,13 @@ impl Capture { let _lock = lock(); for frame in self.frames.iter_mut() { let symbols = &mut frame.symbols; + let frame = match &frame.frame { + RawFrame::Actual(frame) => frame, + #[cfg(test)] + RawFrame::Fake => unimplemented!(), + }; unsafe { - backtrace::resolve_frame_unsynchronized(&frame.frame, |symbol| { + backtrace::resolve_frame_unsynchronized(frame, |symbol| { symbols.push(BacktraceSymbol { name: symbol.name().map(|m| m.as_bytes().to_vec()), filename: symbol.filename_raw().map(|b| match b { @@ -408,3 +423,13 @@ impl Capture { } } } + +impl RawFrame { + fn ip(&self) -> *mut c_void { + match self { + RawFrame::Actual(frame) => frame.ip(), + #[cfg(test)] + RawFrame::Fake => 1 as *mut c_void, + } + } +} From 33600e4d2d7a61f7dcb1b278bb1ccb8f04690db3 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Feb 2020 00:16:28 -0800 Subject: [PATCH 5/6] Add test of Debug representation of Backtrace --- src/libstd/backtrace.rs | 52 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs index 04fd80ecbdb23..f3dd7a62fcbb8 100644 --- a/src/libstd/backtrace.rs +++ b/src/libstd/backtrace.rs @@ -433,3 +433,55 @@ impl RawFrame { } } } + +#[test] +fn test_debug() { + let backtrace = Backtrace { + inner: Inner::Captured(Mutex::new(Capture { + actual_start: 1, + resolved: true, + frames: vec![ + BacktraceFrame { + frame: RawFrame::Fake, + symbols: vec![BacktraceSymbol { + name: Some(b"std::backtrace::Backtrace::create".to_vec()), + filename: Some(BytesOrWide::Bytes(b"/rust/backtrace.rs".to_vec())), + lineno: Some(100), + }], + }, + BacktraceFrame { + frame: RawFrame::Fake, + symbols: vec![BacktraceSymbol { + name: Some(b"__rust_maybe_catch_panic".to_vec()), + filename: None, + lineno: None, + }], + }, + BacktraceFrame { + frame: RawFrame::Fake, + symbols: vec![ + BacktraceSymbol { + name: Some(b"std::rt::lang_start_internal".to_vec()), + filename: Some(BytesOrWide::Bytes(b"/rust/rt.rs".to_vec())), + lineno: Some(300), + }, + BacktraceSymbol { + name: Some(b"std::rt::lang_start".to_vec()), + filename: Some(BytesOrWide::Bytes(b"/rust/rt.rs".to_vec())), + lineno: Some(400), + }, + ], + }, + ], + })), + }; + + #[rustfmt::skip] + let expected = "Backtrace [\ + \n { fn: \"__rust_maybe_catch_panic\" },\ + \n { fn: \"std::rt::lang_start_internal\", file: \"/rust/rt.rs\", line: 300 },\ + \n { fn: \"std::rt::lang_start\", file: \"/rust/rt.rs\", line: 400 },\ + \n]"; + + assert_eq!(format!("{:#?}", backtrace), expected); +} From a2364dc85fb505487c272988b8c5073a3f6fef2a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 9 Mar 2020 12:23:19 -0700 Subject: [PATCH 6/6] Write backtrace fmt test using relative paths For some reason the absolute paths were formatted differently on the armhf-gnu target. thread '' panicked at 'assertion failed: `(left == right)` left: `"Backtrace [\n { fn: \"__rust_maybe_catch_panic\" },\n { fn: \"std::rt::lang_start_internal\", file: \"./rust/rt.rs\", line: 300 },\n { fn: \"std::rt::lang_start\", file: \"./rust/rt.rs\", line: 400 },\n]"`, right: `"Backtrace [\n { fn: \"__rust_maybe_catch_panic\" },\n { fn: \"std::rt::lang_start_internal\", file: \"/rust/rt.rs\", line: 300 },\n { fn: \"std::rt::lang_start\", file: \"/rust/rt.rs\", line: 400 },\n]"`', src/libstd/backtrace.rs:486:5 --- src/libstd/backtrace.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs index f3dd7a62fcbb8..34317c7a2ee3d 100644 --- a/src/libstd/backtrace.rs +++ b/src/libstd/backtrace.rs @@ -445,7 +445,7 @@ fn test_debug() { frame: RawFrame::Fake, symbols: vec![BacktraceSymbol { name: Some(b"std::backtrace::Backtrace::create".to_vec()), - filename: Some(BytesOrWide::Bytes(b"/rust/backtrace.rs".to_vec())), + filename: Some(BytesOrWide::Bytes(b"rust/backtrace.rs".to_vec())), lineno: Some(100), }], }, @@ -462,12 +462,12 @@ fn test_debug() { symbols: vec![ BacktraceSymbol { name: Some(b"std::rt::lang_start_internal".to_vec()), - filename: Some(BytesOrWide::Bytes(b"/rust/rt.rs".to_vec())), + filename: Some(BytesOrWide::Bytes(b"rust/rt.rs".to_vec())), lineno: Some(300), }, BacktraceSymbol { name: Some(b"std::rt::lang_start".to_vec()), - filename: Some(BytesOrWide::Bytes(b"/rust/rt.rs".to_vec())), + filename: Some(BytesOrWide::Bytes(b"rust/rt.rs".to_vec())), lineno: Some(400), }, ], @@ -479,8 +479,8 @@ fn test_debug() { #[rustfmt::skip] let expected = "Backtrace [\ \n { fn: \"__rust_maybe_catch_panic\" },\ - \n { fn: \"std::rt::lang_start_internal\", file: \"/rust/rt.rs\", line: 300 },\ - \n { fn: \"std::rt::lang_start\", file: \"/rust/rt.rs\", line: 400 },\ + \n { fn: \"std::rt::lang_start_internal\", file: \"rust/rt.rs\", line: 300 },\ + \n { fn: \"std::rt::lang_start\", file: \"rust/rt.rs\", line: 400 },\ \n]"; assert_eq!(format!("{:#?}", backtrace), expected);