diff --git a/src/symbolize/dbghelp.rs b/src/symbolize/dbghelp.rs index 50d5384f..a2d613aa 100644 --- a/src/symbolize/dbghelp.rs +++ b/src/symbolize/dbghelp.rs @@ -18,7 +18,7 @@ #![allow(bad_style)] use super::super::{dbghelp, windows::*}; -use super::{BytesOrWideString, ResolveWhat, SymbolName}; +use super::{BytesOrWideString, RawSymbolName, ResolveWhat}; use core::char; use core::ffi::c_void; use core::marker; @@ -47,8 +47,8 @@ pub struct Symbol<'a> { } impl Symbol<'_> { - pub fn name(&self) -> Option> { - Some(SymbolName::new(unsafe { &*self.name })) + pub fn name_raw(&self) -> Option> { + Some(RawSymbolName::new(unsafe { &*self.name })) } pub fn addr(&self) -> Option<*mut c_void> { diff --git a/src/symbolize/gimli.rs b/src/symbolize/gimli.rs index 51f1c803..75ac30a4 100644 --- a/src/symbolize/gimli.rs +++ b/src/symbolize/gimli.rs @@ -7,8 +7,8 @@ use self::gimli::NativeEndian as Endian; use self::mmap::Mmap; use self::stash::Stash; use super::BytesOrWideString; +use super::RawSymbolName; use super::ResolveWhat; -use super::SymbolName; use addr2line::gimli; use core::convert::TryInto; use core::mem; @@ -492,13 +492,13 @@ pub enum Symbol<'a> { } impl Symbol<'_> { - pub fn name(&self) -> Option> { + pub fn name_raw(&self) -> Option> { match self { Symbol::Frame { name, .. } => { let name = name.as_ref()?; - Some(SymbolName::new(name)) + Some(RawSymbolName::new(name)) } - Symbol::Symtab { name, .. } => Some(SymbolName::new(name)), + Symbol::Symtab { name, .. } => Some(RawSymbolName::new(name)), } } diff --git a/src/symbolize/miri.rs b/src/symbolize/miri.rs index 5b0dc308..b7eb9213 100644 --- a/src/symbolize/miri.rs +++ b/src/symbolize/miri.rs @@ -3,7 +3,7 @@ use core::marker::PhantomData; use super::super::backtrace::miri::{resolve_addr, Frame}; use super::BytesOrWideString; -use super::{ResolveWhat, SymbolName}; +use super::{RawSymbolName, ResolveWhat}; pub unsafe fn resolve(what: ResolveWhat<'_>, cb: &mut dyn FnMut(&super::Symbol)) { let sym = match what { @@ -25,8 +25,8 @@ pub struct Symbol<'a> { } impl<'a> Symbol<'a> { - pub fn name(&self) -> Option> { - Some(SymbolName::new(&self.inner.inner.name)) + pub fn name_raw(&self) -> Option> { + Some(RawSymbolName::new(&self.inner.inner.name)) } pub fn addr(&self) -> Option<*mut c_void> { diff --git a/src/symbolize/mod.rs b/src/symbolize/mod.rs index b01fe86d..6b9c0fbf 100644 --- a/src/symbolize/mod.rs +++ b/src/symbolize/mod.rs @@ -205,7 +205,14 @@ impl Symbol { /// utf-8). /// * The raw bytes for the symbol name can be accessed. pub fn name(&self) -> Option> { - self.inner.name() + self.name_raw().map(|s| s.demangle()) + } + + /// Returns the raw name of this function. + /// + /// This is similar to `name` but doesn't do any demangling. + pub fn name_raw(&self) -> Option> { + self.inner.name_raw() } /// Returns the starting address of this function. @@ -356,6 +363,42 @@ impl<'a> SymbolName<'a> { } } +/// A wrapper around the raw, mangled, symbol name. +pub struct RawSymbolName<'a> { + bytes: &'a [u8], +} +impl<'a> RawSymbolName<'a> { + /// Creates a new raw symbol name from the raw underlying bytes. + pub fn new(bytes: &'a [u8]) -> RawSymbolName<'a> { + RawSymbolName { bytes } + } + + /// Attempt to demangle the symbol name. + pub fn demangle(self) -> SymbolName<'a> { + SymbolName::new(self.bytes) + } + + /// Returns the raw (mangled) symbol name as a `str` if the symbol is valid utf-8. + pub fn as_str(&self) -> Option<&'a str> { + str::from_utf8(self.bytes).ok() + } + + /// Returns the raw symbol name as a list of bytes + pub fn as_bytes(&self) -> &'a [u8] { + self.bytes + } +} +impl<'a> fmt::Display for RawSymbolName<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + format_symbol_name(fmt::Display::fmt, self.bytes, f) + } +} +impl<'a> fmt::Debug for RawSymbolName<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + format_symbol_name(fmt::Debug::fmt, self.bytes, f) + } +} + fn format_symbol_name( fmt: fn(&str, &mut fmt::Formatter<'_>) -> fmt::Result, mut bytes: &[u8], diff --git a/src/symbolize/noop.rs b/src/symbolize/noop.rs index c5333653..f9b5723b 100644 --- a/src/symbolize/noop.rs +++ b/src/symbolize/noop.rs @@ -1,7 +1,7 @@ //! Empty symbolication strategy used to compile for platforms that have no //! support. -use super::{BytesOrWideString, ResolveWhat, SymbolName}; +use super::{BytesOrWideString, RawSymbolName, ResolveWhat}; use core::ffi::c_void; use core::marker; @@ -12,7 +12,7 @@ pub struct Symbol<'a> { } impl Symbol<'_> { - pub fn name(&self) -> Option> { + pub fn name_raw(&self) -> Option> { None }