about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-03-16 13:22:56 +0000
committerbors <bors@rust-lang.org>2020-03-16 13:22:56 +0000
commit59f4ba95045e91a63e921e0d736242d7e1ffabec (patch)
treec094dea10880b240fb45bf36cb8f4905edfdb2fa /src/libstd
parent8e6de3244cd62cbde367c206bc9972daded5281d (diff)
parentd8dbb3c0413afe1cad58515295273c89d82176e5 (diff)
downloadrust-59f4ba95045e91a63e921e0d736242d7e1ffabec.tar.gz
rust-59f4ba95045e91a63e921e0d736242d7e1ffabec.zip
Auto merge of #70040 - Dylan-DPC:rollup-id1k6lz, r=Dylan-DPC
Rollup of 7 pull requests

Successful merges:

 - #67335 (Refactor the `Qualif` trait)
 - #69122 (Backtrace Debug tweaks)
 - #69520 (Make error message clearer about creating new module)
 - #69738 (More Method -> AssocFn renaming)
 - #69867 (Add long error explanation for E0628 )
 - #69989 (resolve/hygiene: `macro_rules` are not "legacy")
 - #70036 (Make article_and_description primarily use def_kind)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/backtrace.rs91
1 files changed, 84 insertions, 7 deletions
diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs
index 97db0ff3791..34317c7a2ee 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<BacktraceSymbol>,
 }
 
+enum RawFrame {
+    Actual(backtrace::Frame),
+    #[cfg(test)]
+    Fake,
+}
+
 struct BacktraceSymbol {
     name: Option<Vec<u8>>,
     filename: Option<BytesOrWide>,
@@ -162,8 +169,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("<unsupported>"),
+            Inner::Disabled => return fmt.write_str("<disabled>"),
             Inner::Captured(c) => c.lock().unwrap(),
         };
         capture.resolve();
@@ -193,11 +200,11 @@ 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: \"<unknown>\"")?;
+            write!(fmt, "fn: <unknown>")?;
         }
 
         if let Some(fname) = self.filename.as_ref() {
-            write!(fmt, ", file: {:?}", fname)?;
+            write!(fmt, ", file: \"{:?}\"", fname)?;
         }
 
         if let Some(line) = self.lineno.as_ref() {
@@ -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,65 @@ 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,
+        }
+    }
+}
+
+#[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);
+}