Skip to content

Commit

Permalink
make it easy to resolve symbols by frame
Browse files Browse the repository at this point in the history
  • Loading branch information
fraillt authored and Mindaugas Vinkelis committed Jul 7, 2023
1 parent f3af31c commit a1fb68b
Showing 1 changed file with 31 additions and 21 deletions.
52 changes: 31 additions & 21 deletions src/capture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,27 @@ impl Frame {
} => module_base_address.map(|addr| addr as *mut c_void),
}
}

/// Resolve all addresses in the frame to their symbolic names.
fn resolve_symbols(&self) -> Vec<BacktraceSymbol> {
let mut symbols = Vec::new();
let sym = |symbol: &Symbol| {
symbols.push(BacktraceSymbol {
name: symbol.name().map(|m| m.as_bytes().to_vec()),
addr: symbol.addr().map(|a| a as usize),
filename: symbol.filename().map(|m| m.to_owned()),
lineno: symbol.lineno(),
colno: symbol.colno(),
});
};
match *self {
Frame::Raw(ref f) => resolve_frame(f, sym),
Frame::Deserialized { ip, .. } => {
resolve(ip as *mut c_void, sym);
}
}
symbols
}
}

/// Captured version of a symbol in a backtrace.
Expand Down Expand Up @@ -216,27 +237,7 @@ impl Backtrace {
/// 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) {
for frame in self.frames.iter_mut().filter(|f| f.symbols.is_none()) {
let mut symbols = Vec::new();
{
let sym = |symbol: &Symbol| {
symbols.push(BacktraceSymbol {
name: symbol.name().map(|m| m.as_bytes().to_vec()),
addr: symbol.addr().map(|a| a as usize),
filename: symbol.filename().map(|m| m.to_owned()),
lineno: symbol.lineno(),
colno: symbol.colno(),
});
};
match frame.frame {
Frame::Raw(ref f) => resolve_frame(f, sym),
Frame::Deserialized { ip, .. } => {
resolve(ip as *mut c_void, sym);
}
}
}
frame.symbols = Some(symbols);
}
self.frames.iter_mut().for_each(BacktraceFrame::resolve);
}
}

Expand Down Expand Up @@ -314,6 +315,15 @@ impl BacktraceFrame {
pub fn symbols(&self) -> &[BacktraceSymbol] {
self.symbols.as_ref().map(|s| &s[..]).unwrap_or(&[])
}

/// Resolve all addresses in the frame to their symbolic names.
///
/// If this frame has been previously resolved, this function does nothing.
pub fn resolve(&mut self) {
if self.symbols.is_none() {
self.symbols = Some(self.frame.resolve_symbols());
}
}
}

impl BacktraceSymbol {
Expand Down

0 comments on commit a1fb68b

Please sign in to comment.