diff options
Diffstat (limited to 'vendor/backtrace/src/capture.rs')
| -rw-r--r-- | vendor/backtrace/src/capture.rs | 621 |
1 files changed, 0 insertions, 621 deletions
diff --git a/vendor/backtrace/src/capture.rs b/vendor/backtrace/src/capture.rs deleted file mode 100644 index eb672593..00000000 --- a/vendor/backtrace/src/capture.rs +++ /dev/null @@ -1,621 +0,0 @@ -#![allow(clippy::from_over_into)] - -#[cfg(feature = "serde")] -use crate::resolve; -use crate::PrintFmt; -use crate::{resolve_frame, trace, BacktraceFmt, Symbol, SymbolName}; -use core::ffi::c_void; -use std::fmt; -use std::path::{Path, PathBuf}; -use std::prelude::v1::*; - -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; - -/// Representation of an owned and self-contained backtrace. -/// -/// This structure can be used to capture a backtrace at various points in a -/// program and later used to inspect what the backtrace was at that time. -/// -/// `Backtrace` supports pretty-printing of backtraces through its `Debug` -/// implementation. -/// -/// # Required features -/// -/// This function requires the `std` feature of the `backtrace` crate to be -/// enabled, and the `std` feature is enabled by default. -#[derive(Clone)] -#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -pub struct Backtrace { - // Frames here are listed from top-to-bottom of the stack - frames: Box<[BacktraceFrame]>, -} - -#[derive(Clone, Copy)] -struct TracePtr(*mut c_void); -/// SAFETY: These pointers are always valid within a process and are not used for mutation. -unsafe impl Send for TracePtr {} -/// SAFETY: These pointers are always valid within a process and are not used for mutation. -unsafe impl Sync for TracePtr {} - -impl TracePtr { - fn into_void(self) -> *mut c_void { - self.0 - } - #[cfg(feature = "serde")] - fn from_addr(addr: usize) -> Self { - TracePtr(addr as *mut c_void) - } -} - -#[cfg(feature = "serde")] -impl<'de> Deserialize<'de> for TracePtr { - #[inline] - fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where - D: serde::Deserializer<'de>, - { - struct PrimitiveVisitor; - - impl<'de> serde::de::Visitor<'de> for PrimitiveVisitor { - type Value = TracePtr; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("usize") - } - - #[inline] - fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E> - where - E: serde::de::Error, - { - Ok(TracePtr(v as usize as *mut c_void)) - } - - #[inline] - fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E> - where - E: serde::de::Error, - { - Ok(TracePtr(v as usize as *mut c_void)) - } - - #[inline] - fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E> - where - E: serde::de::Error, - { - if usize::BITS >= 32 { - Ok(TracePtr(v as usize as *mut c_void)) - } else { - Err(E::invalid_type( - serde::de::Unexpected::Unsigned(v as _), - &self, - )) - } - } - - #[inline] - fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> - where - E: serde::de::Error, - { - if usize::BITS >= 64 { - Ok(TracePtr(v as usize as *mut c_void)) - } else { - Err(E::invalid_type( - serde::de::Unexpected::Unsigned(v as _), - &self, - )) - } - } - } - - deserializer.deserialize_u64(PrimitiveVisitor) - } -} - -#[cfg(feature = "serde")] -impl Serialize for TracePtr { - #[inline] - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where - S: serde::ser::Serializer, - { - serializer.serialize_u64(self.0 as usize as u64) - } -} - -fn _assert_send_sync() { - fn _assert<T: Send + Sync>() {} - _assert::<Backtrace>(); -} - -/// Captured version of a frame in a backtrace. -/// -/// This type is returned as a list from `Backtrace::frames` and represents one -/// stack frame in a captured backtrace. -/// -/// # Required features -/// -/// This function requires the `std` feature of the `backtrace` crate to be -/// enabled, and the `std` feature is enabled by default. -#[derive(Clone)] -pub struct BacktraceFrame { - frame: Frame, - symbols: Option<Box<[BacktraceSymbol]>>, -} - -#[derive(Clone)] -enum Frame { - Raw(crate::Frame), - #[cfg(feature = "serde")] - Deserialized { - ip: TracePtr, - symbol_address: TracePtr, - module_base_address: Option<TracePtr>, - }, -} - -impl Frame { - fn ip(&self) -> *mut c_void { - match *self { - Frame::Raw(ref f) => f.ip(), - #[cfg(feature = "serde")] - Frame::Deserialized { ip, .. } => ip.into_void(), - } - } - - fn symbol_address(&self) -> *mut c_void { - match *self { - Frame::Raw(ref f) => f.symbol_address(), - #[cfg(feature = "serde")] - Frame::Deserialized { symbol_address, .. } => symbol_address.into_void(), - } - } - - fn module_base_address(&self) -> Option<*mut c_void> { - match *self { - Frame::Raw(ref f) => f.module_base_address(), - #[cfg(feature = "serde")] - Frame::Deserialized { - module_base_address, - .. - } => module_base_address.map(|addr| addr.into_void()), - } - } - - /// Resolve all addresses in the frame to their symbolic names. - fn resolve_symbols(&self) -> Box<[BacktraceSymbol]> { - let mut symbols = Vec::new(); - let sym = |symbol: &Symbol| { - symbols.push(BacktraceSymbol { - name: symbol.name().map(|m| m.as_bytes().into()), - addr: symbol.addr().map(TracePtr), - filename: symbol.filename().map(|m| m.to_owned()), - lineno: symbol.lineno(), - colno: symbol.colno(), - }); - }; - match *self { - Frame::Raw(ref f) => resolve_frame(f, sym), - #[cfg(feature = "serde")] - Frame::Deserialized { ip, .. } => { - resolve(ip.into_void(), sym); - } - } - symbols.into_boxed_slice() - } -} - -/// Captured version of a symbol in a backtrace. -/// -/// This type is returned as a list from `BacktraceFrame::symbols` and -/// represents the metadata for a symbol in a backtrace. -/// -/// # Required features -/// -/// This function requires the `std` feature of the `backtrace` crate to be -/// enabled, and the `std` feature is enabled by default. -#[derive(Clone)] -#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -pub struct BacktraceSymbol { - name: Option<Box<[u8]>>, - addr: Option<TracePtr>, - filename: Option<PathBuf>, - lineno: Option<u32>, - colno: Option<u32>, -} - -impl Backtrace { - /// Captures a backtrace at the callsite of this function, returning an - /// owned representation. - /// - /// This function is useful for representing a backtrace as an object in - /// Rust. This returned value can be sent across threads and printed - /// elsewhere, and the purpose of this value is to be entirely self - /// contained. - /// - /// Note that on some platforms acquiring a full backtrace and resolving it - /// can be extremely expensive. If the cost is too much for your application - /// it's recommended to instead use `Backtrace::new_unresolved()` which - /// avoids the symbol resolution step (which typically takes the longest) - /// and allows deferring that to a later date. - /// - /// # Examples - /// - /// ``` - /// use backtrace::Backtrace; - /// - /// let current_backtrace = Backtrace::new(); - /// ``` - /// - /// # Required features - /// - /// This function requires the `std` feature of the `backtrace` crate to be - /// enabled, and the `std` feature is enabled by default. - #[inline(never)] // want to make sure there's a frame here to remove - pub fn new() -> Backtrace { - let mut bt = Self::create(Self::new as usize); - bt.resolve(); - bt - } - - /// Similar to `new` except that this does not resolve any symbols, this - /// simply captures the backtrace as a list of addresses. - /// - /// At a later time the `resolve` function can be called to resolve this - /// backtrace's symbols into readable names. This function exists because - /// the resolution process can sometimes take a significant amount of time - /// whereas any one backtrace may only be rarely printed. - /// - /// # Examples - /// - /// ``` - /// use backtrace::Backtrace; - /// - /// let mut current_backtrace = Backtrace::new_unresolved(); - /// println!("{current_backtrace:?}"); // no symbol names - /// current_backtrace.resolve(); - /// println!("{current_backtrace:?}"); // symbol names now present - /// ``` - /// - /// # Required features - /// - /// This function requires the `std` feature of the `backtrace` crate to be - /// enabled, and the `std` feature is enabled by default. - #[inline(never)] // want to make sure there's a frame here to remove - pub fn new_unresolved() -> Backtrace { - Self::create(Self::new_unresolved as usize) - } - - fn create(ip: usize) -> Backtrace { - let mut frames = Vec::new(); - trace(|frame| { - frames.push(BacktraceFrame { - frame: Frame::Raw(frame.clone()), - symbols: None, - }); - - // clear inner frames, and start with call site. - if frame.symbol_address() as usize == ip { - frames.clear(); - } - - true - }); - frames.shrink_to_fit(); - - Backtrace { - frames: frames.into_boxed_slice(), - } - } - - /// Returns the frames from when this backtrace was captured. - /// - /// The first entry of this slice is likely the function `Backtrace::new`, - /// and the last frame is likely something about how this thread or the main - /// function started. - /// - /// # Required features - /// - /// This function requires the `std` feature of the `backtrace` crate to be - /// enabled, and the `std` feature is enabled by default. - pub fn frames(&self) -> &[BacktraceFrame] { - self.frames.as_ref() - } - - /// If this backtrace was created from `new_unresolved` then this function - /// will resolve all addresses in the backtrace to their symbolic names. - /// - /// If this backtrace has been previously resolved or was created through - /// `new`, this function does nothing. - /// - /// # Required features - /// - /// This function requires the `std` feature of the `backtrace` crate to be - /// enabled, and the `std` feature is enabled by default. - pub fn resolve(&mut self) { - self.frames.iter_mut().for_each(BacktraceFrame::resolve); - } -} - -impl From<Vec<BacktraceFrame>> for Backtrace { - fn from(frames: Vec<BacktraceFrame>) -> Self { - Backtrace { - frames: frames.into_boxed_slice(), - } - } -} - -impl From<crate::Frame> for BacktraceFrame { - fn from(frame: crate::Frame) -> Self { - BacktraceFrame { - frame: Frame::Raw(frame), - symbols: None, - } - } -} - -// we don't want to implement `impl From<Backtrace> for Vec<BacktraceFrame>` on purpose, -// because "... additional directions for Vec<T> can weaken type inference ..." -// more information on https://github.com/rust-lang/backtrace-rs/pull/526 -impl Into<Vec<BacktraceFrame>> for Backtrace { - fn into(self) -> Vec<BacktraceFrame> { - self.frames.into_vec() - } -} - -impl BacktraceFrame { - /// Same as `Frame::ip` - /// - /// # Required features - /// - /// This function requires the `std` feature of the `backtrace` crate to be - /// enabled, and the `std` feature is enabled by default. - pub fn ip(&self) -> *mut c_void { - self.frame.ip() - } - - /// Same as `Frame::symbol_address` - /// - /// # Required features - /// - /// This function requires the `std` feature of the `backtrace` crate to be - /// enabled, and the `std` feature is enabled by default. - pub fn symbol_address(&self) -> *mut c_void { - self.frame.symbol_address() - } - - /// Same as `Frame::module_base_address` - /// - /// # Required features - /// - /// This function requires the `std` feature of the `backtrace` crate to be - /// enabled, and the `std` feature is enabled by default. - pub fn module_base_address(&self) -> Option<*mut c_void> { - self.frame.module_base_address() - } - - /// Returns the list of symbols that this frame corresponds to. - /// - /// Normally there is only one symbol per frame, but sometimes if a number - /// of functions are inlined into one frame then multiple symbols will be - /// returned. The first symbol listed is the "innermost function", whereas - /// the last symbol is the outermost (last caller). - /// - /// Note that if this frame came from an unresolved backtrace then this will - /// return an empty list. - /// - /// # Required features - /// - /// This function requires the `std` feature of the `backtrace` crate to be - /// enabled, and the `std` feature is enabled by default. - pub fn symbols(&self) -> &[BacktraceSymbol] { - self.symbols.as_ref().map(|s| &s[..]).unwrap_or(&[]) - } - - /// Resolve all addresses in this frame to their symbolic names. - /// - /// If this frame has been previously resolved, this function does nothing. - /// - /// # Required features - /// - /// This function requires the `std` feature of the `backtrace` crate to be - /// enabled, and the `std` feature is enabled by default. - pub fn resolve(&mut self) { - if self.symbols.is_none() { - self.symbols = Some(self.frame.resolve_symbols()); - } - } -} - -impl BacktraceSymbol { - /// Same as `Symbol::name` - /// - /// # Required features - /// - /// This function requires the `std` feature of the `backtrace` crate to be - /// enabled, and the `std` feature is enabled by default. - pub fn name(&self) -> Option<SymbolName<'_>> { - self.name.as_ref().map(|s| SymbolName::new(s)) - } - - /// Same as `Symbol::addr` - /// - /// # Required features - /// - /// This function requires the `std` feature of the `backtrace` crate to be - /// enabled, and the `std` feature is enabled by default. - pub fn addr(&self) -> Option<*mut c_void> { - self.addr.map(|s| s.into_void()) - } - - /// Same as `Symbol::filename` - /// - /// # Required features - /// - /// This function requires the `std` feature of the `backtrace` crate to be - /// enabled, and the `std` feature is enabled by default. - pub fn filename(&self) -> Option<&Path> { - self.filename.as_deref() - } - - /// Same as `Symbol::lineno` - /// - /// # Required features - /// - /// This function requires the `std` feature of the `backtrace` crate to be - /// enabled, and the `std` feature is enabled by default. - pub fn lineno(&self) -> Option<u32> { - self.lineno - } - - /// Same as `Symbol::colno` - /// - /// # Required features - /// - /// This function requires the `std` feature of the `backtrace` crate to be - /// enabled, and the `std` feature is enabled by default. - pub fn colno(&self) -> Option<u32> { - self.colno - } -} - -impl fmt::Debug for Backtrace { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let style = if fmt.alternate() { - PrintFmt::Full - } else { - PrintFmt::Short - }; - - // When printing paths we try to strip the cwd if it exists, otherwise - // we just print the path as-is. Note that we also only do this for the - // short format, because if it's full we presumably want to print - // everything. - let cwd = std::env::current_dir(); - let mut print_path = - move |fmt: &mut fmt::Formatter<'_>, path: crate::BytesOrWideString<'_>| { - let path = path.into_path_buf(); - if style == PrintFmt::Full { - if let Ok(cwd) = &cwd { - if let Ok(suffix) = path.strip_prefix(cwd) { - return fmt::Display::fmt(&suffix.display(), fmt); - } - } - } - fmt::Display::fmt(&path.display(), fmt) - }; - - let mut f = BacktraceFmt::new(fmt, style, &mut print_path); - f.add_context()?; - for frame in &self.frames { - f.frame().backtrace_frame(frame)?; - } - f.finish()?; - Ok(()) - } -} - -impl Default for Backtrace { - fn default() -> Backtrace { - Backtrace::new() - } -} - -impl fmt::Debug for BacktraceFrame { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_struct("BacktraceFrame") - .field("ip", &self.ip()) - .field("symbol_address", &self.symbol_address()) - .finish() - } -} - -impl fmt::Debug for BacktraceSymbol { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_struct("BacktraceSymbol") - .field("name", &self.name()) - .field("addr", &self.addr()) - .field("filename", &self.filename()) - .field("lineno", &self.lineno()) - .field("colno", &self.colno()) - .finish() - } -} - -#[cfg(feature = "serde")] -mod serde_impls { - use super::*; - use serde::de::Deserializer; - use serde::ser::Serializer; - use serde::{Deserialize, Serialize}; - - #[derive(Serialize, Deserialize)] - struct SerializedFrame { - ip: usize, - symbol_address: usize, - module_base_address: Option<usize>, - symbols: Option<Box<[BacktraceSymbol]>>, - } - - impl Serialize for BacktraceFrame { - fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error> - where - S: Serializer, - { - let BacktraceFrame { frame, symbols } = self; - SerializedFrame { - ip: frame.ip() as usize, - symbol_address: frame.symbol_address() as usize, - module_base_address: frame.module_base_address().map(|sym_a| sym_a as usize), - symbols: symbols.clone(), - } - .serialize(s) - } - } - - impl<'a> Deserialize<'a> for BacktraceFrame { - fn deserialize<D>(d: D) -> Result<Self, D::Error> - where - D: Deserializer<'a>, - { - let frame: SerializedFrame = SerializedFrame::deserialize(d)?; - Ok(BacktraceFrame { - frame: Frame::Deserialized { - ip: TracePtr::from_addr(frame.ip), - symbol_address: TracePtr::from_addr(frame.symbol_address), - module_base_address: frame.module_base_address.map(TracePtr::from_addr), - }, - symbols: frame.symbols, - }) - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_frame_conversion() { - let mut frames = vec![]; - crate::trace(|frame| { - let converted = BacktraceFrame::from(frame.clone()); - frames.push(converted); - true - }); - - let mut manual = Backtrace::from(frames); - manual.resolve(); - let frames = manual.frames(); - - for frame in frames { - println!("{:?}", frame.ip()); - println!("{:?}", frame.symbol_address()); - println!("{:?}", frame.module_base_address()); - println!("{:?}", frame.symbols()); - } - } -} |
