Skip to content

[WIP] Add more mangling information to demangling API. #45

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions samply-symbols/src/breakpad/symbol_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ impl<'a, T: FileContents> SymbolMapTrait for BreakpadSymbolMapInner<'a, T> {
function: name,
file_path: file.map(SourceFilePath::from_breakpad_path),
line_number: Some(inlinee.call_line),
mangled_name: None,
});
let inline_origin = inline_origins
.get_str(inlinee.origin_id)
Expand All @@ -319,6 +320,7 @@ impl<'a, T: FileContents> SymbolMapTrait for BreakpadSymbolMapInner<'a, T> {
function: name,
file_path: file.map(SourceFilePath::from_breakpad_path),
line_number,
mangled_name: None,
});
frames.reverse();

Expand Down Expand Up @@ -452,31 +454,35 @@ mod test {
FrameDebugInfo {
function: Some("WriteRelease64(long long*, long long)".into()),
file_path: Some(SourceFilePath::new("/builds/worker/workspace/obj-build/browser/app/d:/agent/_work/2/s/src/externalapis/windows/10/sdk/inc/winnt.h".into(), None)),
line_number: Some(7729)
line_number: Some(7729),
mangled_name: None,
}
);
assert_eq!(
frames[1],
FrameDebugInfo {
function: Some("WritePointerRelease(void**, void*)".into()),
file_path: Some(SourceFilePath::new("/builds/worker/workspace/obj-build/browser/app/d:/agent/_work/2/s/src/externalapis/windows/10/sdk/inc/winnt.h".into(), None)),
line_number: Some(8358)
line_number: Some(8358),
mangled_name: None,
}
);
assert_eq!(
frames[2],
FrameDebugInfo {
function: Some("DloadUnlock()".into()),
file_path: Some(SourceFilePath::new("/builds/worker/workspace/obj-build/browser/app/d:/agent/_work/2/s/src/vctools/delayimp/dloadsup.h".into(), None)),
line_number: Some(345)
line_number: Some(345),
mangled_name: None,
}
);
assert_eq!(
frames[3],
FrameDebugInfo {
function: Some("DloadAcquireSectionWriteAccess()".into()),
file_path: Some(SourceFilePath::new("/builds/worker/workspace/obj-build/browser/app/d:/agent/_work/2/s/src/vctools/delayimp/dloadsup.h".into(), None)),
line_number: Some(665)
line_number: Some(665),
mangled_name: None,
}
);
}
Expand Down
26 changes: 19 additions & 7 deletions samply-symbols/src/demangle.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
use super::demangle_ocaml;
use msvc_demangler::DemangleFlags;

pub fn demangle_any(name: &str) -> String {
/// MangleKind represents the possible name mangling that we may meet when trying to demangle a name.
/// In some situations, it is quite useful to know *how* a name was mangled, even after we have decoded it.
#[derive(Debug, PartialEq)]
pub enum MangleKind {
MSVC,
Rust,
OCaml,
Itanium,
Unknown
}

pub fn demangle_any(name: &str) -> (MangleKind, String) {
if name.starts_with('?') {
let flags = DemangleFlags::NO_ACCESS_SPECIFIERS
| DemangleFlags::NO_FUNCTION_RETURNS
Expand All @@ -11,29 +22,30 @@ pub fn demangle_any(name: &str) -> String {
| DemangleFlags::NO_CLASS_TYPE
| DemangleFlags::SPACE_AFTER_COMMA
| DemangleFlags::HUG_TYPE;
return msvc_demangler::demangle(name, flags).unwrap_or_else(|_| name.to_string());
return (MangleKind::MSVC, msvc_demangler::demangle(name, flags).unwrap_or_else(|_| name.to_string()));
}

if let Ok(demangled_symbol) = rustc_demangle::try_demangle(name) {
return format!("{demangled_symbol:#}");
return (MangleKind::Rust, format!("{demangled_symbol:#}"));
}

if name.starts_with('_') {
let options = cpp_demangle::DemangleOptions::default().no_return_type();
if let Ok(symbol) = cpp_demangle::Symbol::new(name) {
if let Ok(demangled_string) = symbol.demangle(&options) {
return demangled_string;
return (MangleKind::Itanium, demangled_string);
}
}
}

if let Some(symbol) = demangle_ocaml::demangle(name) {
return symbol;
return (MangleKind::OCaml, symbol);
}

if name.starts_with('_') {
return name.split_at(1).1.to_owned();
return (MangleKind::Itanium, name.split_at(1).1.to_owned());
}

name.to_owned()
(MangleKind::Unknown, name.to_owned())
}

9 changes: 5 additions & 4 deletions samply-symbols/src/dwarf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ pub fn convert_stack_frame<R: gimli::Reader>(
frame: addr2line::Frame<R>,
path_mapper: &mut PathMapper<()>,
) -> FrameDebugInfo {
let function = match frame.function {
let (function, mangled_name) = match frame.function {
Some(function_name) => {
if let Ok(name) = function_name.raw_name() {
Some(demangle::demangle_any(&name))
(Some(demangle::demangle_any(&name).1), Some(name.to_string()))
} else {
None
(None, None)
}
}
None => None,
None => (None, None),
};
let file_path = frame.location.as_ref().and_then(|l| l.file).map(|file| {
let mapped_path = path_mapper.map_path(file);
Expand All @@ -52,6 +52,7 @@ pub fn convert_stack_frame<R: gimli::Reader>(
function,
file_path,
line_number: frame.location.and_then(|l| l.line),
mangled_name,
}
}

Expand Down
1 change: 1 addition & 0 deletions samply-symbols/src/jitdump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ impl<'a, T: FileContents> JitDumpSymbolMapInner<'a, T> {
function: Some(name.clone()),
file_path: Some(SourceFilePath::new(file_path, None)),
line_number: Some(entry.line),
mangled_name: None,
};
FramesLookupResult::Available(vec![frame])
}
Expand Down
2 changes: 2 additions & 0 deletions samply-symbols/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,8 @@ pub struct FrameDebugInfo {
pub file_path: Option<SourceFilePath>,
/// The line number for this frame, if known.
pub line_number: Option<u32>,
/// The mangled name of this frame, if known.
pub mangled_name: Option<String>,
}

/// A trait which abstracts away the token that's passed to the [`FileAndPathHelper::load_file`]
Expand Down
2 changes: 1 addition & 1 deletion samply-symbols/src/symbol_map_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ where
}
};

let name = demangle::demangle_any(&name);
let name = demangle::demangle_any(&name).1;
Some(AddressInfo {
symbol: SymbolInfo {
address: *start_addr,
Expand Down
3 changes: 2 additions & 1 deletion samply-symbols/src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ impl<'object> SymbolMapTrait for PdbSymbolMapInner<'object> {
let function_frames = self.context.find_frames(address).ok()??;
let symbol_address = function_frames.start_rva;
let symbol_name = match &function_frames.frames.last().unwrap().function {
Some(name) => demangle::demangle_any(name),
Some(name) => demangle::demangle_any(name).1,
None => "unknown".to_string(),
};
let function_size = function_frames
Expand All @@ -259,6 +259,7 @@ impl<'object> SymbolMapTrait for PdbSymbolMapInner<'object> {
function: frame.function,
file_path: frame.file.map(&mut map_path),
line_number: frame.line,
mangled_name: None,
})
.collect();
FramesLookupResult::Available(frames)
Expand Down