Skip to content

Commit

Permalink
Reason
Browse files Browse the repository at this point in the history
  • Loading branch information
d-e-s-o committed Dec 14, 2023
1 parent 533d5d3 commit d4eb1a6
Show file tree
Hide file tree
Showing 14 changed files with 108 additions and 57 deletions.
9 changes: 5 additions & 4 deletions capi/src/symbolize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ fn convert_symbolizedresults_to_c(results: Vec<Symbolized>) -> *const blaze_resu
// blaze_sym, and C strings of symbol and path.
let (strtab_size, inlined_fn_cnt) = results.iter().fold((0, 0), |acc, sym| match sym {
Symbolized::Sym(sym) => (acc.0 + sym_strtab_size(sym), acc.1 + sym.inlined.len()),
Symbolized::Unknown => acc,
Symbolized::Unknown(..) => acc,
});

let buf_size = strtab_size
Expand Down Expand Up @@ -466,7 +466,7 @@ fn convert_symbolizedresults_to_c(results: Vec<Symbolized>) -> *const blaze_resu
inlined_last = unsafe { inlined_last.add(1) };
}
}
Symbolized::Unknown => {
Symbolized::Unknown(..) => {
// Unknown symbols/addresses are just represented with all
// fields set to zero.
// SAFETY: `syms_last` is pointing to a writable and properly
Expand Down Expand Up @@ -670,6 +670,7 @@ mod tests {
use std::slice;

use blazesym::inspect;
use blazesym::symbolize::Reason;


/// Exercise the `Debug` representation of various types.
Expand Down Expand Up @@ -883,7 +884,7 @@ mod tests {

// One symbol and some unsymbolized values.
let results = vec![
Symbolized::Unknown,
Symbolized::Unknown(Reason::UnknownAddr),
Symbolized::Sym(Sym {
name: "test".into(),
addr: 0x1337,
Expand All @@ -898,7 +899,7 @@ mod tests {
.into_boxed_slice(),
_non_exhaustive: (),
}),
Symbolized::Unknown,
Symbolized::Unknown(Reason::InvalidFileOffset),
];
let result = convert_symbolizedresults_to_c(results);
let () = touch_result(result);
Expand Down
2 changes: 1 addition & 1 deletion cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ fn symbolize(symbolize: args::Symbolize) -> Result<()> {
print_frame(&frame.name, None, &frame.code_info);
}
}
symbolize::Symbolized::Unknown => {
symbolize::Symbolized::Unknown(..) => {
println!("{input_addr:#0width$x}: <no-symbol>", width = ADDR_WIDTH)
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/addr2ln.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ fn main() -> Result<()> {
print_frame(&frame.name, None, &frame.code_info);
}
}
Symbolized::Unknown => {
Symbolized::Unknown(..) => {
println!("{input_addr:#0width$x}: <no-symbol>", width = ADDR_WIDTH)
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/addr2ln_pid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ print its symbol, the file name of the source, and the line number.",
print_frame(&frame.name, None, &frame.code_info);
}
}
Symbolized::Unknown => {
Symbolized::Unknown(..) => {
println!("{input_addr:#0width$x}: <no-symbol>", width = ADDR_WIDTH)
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ fn symbolize_current_bt() {
print_frame(&frame.name, None, &frame.code_info);
}
}
Symbolized::Unknown => {
Symbolized::Unknown(..) => {
println!("{input_addr:#0width$x}: <no-symbol>", width = ADDR_WIDTH)
}
}
Expand Down
12 changes: 10 additions & 2 deletions src/elf/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::inspect::SymInfo;
use crate::inspect::SymType;
use crate::mmap::Mmap;
use crate::once::OnceCell;
use crate::symbolize::Reason;
use crate::util::find_match_or_lower_bound_by_key;
use crate::util::ReadRaw as _;
use crate::Addr;
Expand Down Expand Up @@ -470,11 +471,18 @@ impl ElfParser {
Ok(index)
}

pub fn find_sym(&self, addr: Addr, st_type: u8) -> Result<Option<(&str, Addr, usize)>> {
pub fn find_sym(&self, addr: Addr, st_type: u8) -> Result<Result<(&str, Addr, usize), Reason>> {
let strtab = self.cache.ensure_strtab()?;
let symtab = self.cache.ensure_symtab()?;

find_sym(symtab, strtab, addr, st_type)
let sym = find_sym(symtab, strtab, addr, st_type)?.ok_or({
if symtab.is_empty() {
Reason::MissingSyms
} else {
Reason::UnknownAddr
}
});
Ok(sym)
}

/// Calculate the file offset of the given symbol.
Expand Down
15 changes: 8 additions & 7 deletions src/elf/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::inspect::SymInfo;
use crate::once::OnceCell;
use crate::symbolize::AddrCodeInfo;
use crate::symbolize::IntSym;
use crate::symbolize::Reason;
use crate::symbolize::SrcLang;
use crate::Addr;
use crate::Error;
Expand Down Expand Up @@ -158,16 +159,16 @@ impl ElfResolver {

impl SymResolver for ElfResolver {
#[cfg_attr(feature = "tracing", crate::log::instrument(fields(addr = format_args!("{addr:#x}"))))]
fn find_sym(&self, addr: Addr) -> Result<Option<IntSym<'_>>> {
fn find_sym(&self, addr: Addr) -> Result<Result<IntSym<'_>, Reason>> {
#[cfg(feature = "dwarf")]
if let ElfBackend::Dwarf(dwarf) = &self.backend {
if let Some(sym) = dwarf.find_sym(addr)? {
return Ok(Some(sym))
return Ok(Ok(sym))
}
}

let parser = self.parser();
if let Some((name, addr, size)) = parser.find_sym(addr, STT_FUNC)? {
let result = parser.find_sym(addr, STT_FUNC)?.map(|(name, addr, size)| {
// ELF does not carry any source code language information.
let lang = SrcLang::Unknown;
// We found the address in ELF.
Expand All @@ -180,10 +181,10 @@ impl SymResolver for ElfResolver {
size: Some(size),
lang,
};
Ok(Some(sym))
} else {
Ok(None)
}
sym
});

Ok(result)
}

fn find_addr<'slf>(&'slf self, name: &str, opts: &FindAddrOpts) -> Result<Vec<SymInfo<'slf>>> {
Expand Down
9 changes: 5 additions & 4 deletions src/gsym/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::mmap::Mmap;
use crate::symbolize::AddrCodeInfo;
use crate::symbolize::CodeInfo;
use crate::symbolize::IntSym;
use crate::symbolize::Reason;
use crate::symbolize::SrcLang;
use crate::Addr;
use crate::IntoError as _;
Expand Down Expand Up @@ -158,14 +159,14 @@ impl<'dat> GsymResolver<'dat> {
}

impl SymResolver for GsymResolver<'_> {
fn find_sym(&self, addr: Addr) -> Result<Option<IntSym<'_>>> {
fn find_sym(&self, addr: Addr) -> Result<Result<IntSym<'_>, Reason>> {
if let Some(idx) = self.ctx.find_addr(addr) {
let found = self
.ctx
.addr_at(idx)
.ok_or_invalid_data(|| format!("failed to read address table entry {idx}"))?;
if addr < found {
return Ok(None)
return Ok(Err(Reason::UnknownAddr))
}

let info = self
Expand All @@ -188,9 +189,9 @@ impl SymResolver for GsymResolver<'_> {
lang,
};

Ok(Some(sym))
Ok(Ok(sym))
} else {
Ok(None)
Ok(Err(Reason::UnknownAddr))
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::inspect::SymInfo;
use crate::ksym::KSymResolver;
use crate::symbolize::AddrCodeInfo;
use crate::symbolize::IntSym;
use crate::symbolize::Reason;
use crate::Addr;
use crate::Error;
use crate::Result;
Expand Down Expand Up @@ -40,7 +41,7 @@ impl KernelResolver {
}

impl SymResolver for KernelResolver {
fn find_sym(&self, addr: Addr) -> Result<Option<IntSym<'_>>> {
fn find_sym(&self, addr: Addr) -> Result<Result<IntSym<'_>, Reason>> {
if let Some(ksym_resolver) = self.ksym_resolver.as_ref() {
ksym_resolver.find_sym(addr)
} else {
Expand Down
25 changes: 18 additions & 7 deletions src/ksym.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::inspect::SymType;
use crate::once::OnceCell;
use crate::symbolize::AddrCodeInfo;
use crate::symbolize::IntSym;
use crate::symbolize::Reason;
use crate::symbolize::SrcLang;
use crate::util::find_match_or_lower_bound_by_key;
use crate::Addr;
Expand Down Expand Up @@ -97,9 +98,19 @@ impl KSymResolver {
Ok(slf)
}

fn find_ksym(&self, addr: Addr) -> Option<&Ksym> {
find_match_or_lower_bound_by_key(&self.syms, addr, |ksym: &Ksym| ksym.addr)
.and_then(|idx| self.syms.get(idx))
fn find_ksym(&self, addr: Addr) -> Result<&Ksym, Reason> {
let result = find_match_or_lower_bound_by_key(&self.syms, addr, |ksym: &Ksym| ksym.addr)
.and_then(|idx| self.syms.get(idx));
match result {
Some(sym) => Ok(sym),
None => {
if self.syms.is_empty() {
Err(Reason::MissingSyms)
} else {
Err(Reason::UnknownAddr)
}
}
}
}

/// Retrieve the path to the kallsyms file used by this resolver.
Expand All @@ -109,7 +120,7 @@ impl KSymResolver {
}

impl SymResolver for KSymResolver {
fn find_sym(&self, addr: Addr) -> Result<Option<IntSym<'_>>> {
fn find_sym(&self, addr: Addr) -> Result<Result<IntSym<'_>, Reason>> {
let sym = self.find_ksym(addr).map(IntSym::from);
Ok(sym)
}
Expand Down Expand Up @@ -228,8 +239,8 @@ mod tests {
ensure_addr_for_name(found.name, addr);

// 0 is an invalid address. We remove all symbols with 0 as
// thier address from the list.
assert!(resolver.find_sym(0).unwrap().is_none());
// their address from the list.
assert!(resolver.find_sym(0).unwrap().is_err());

// Find the address of the last symbol
let sym = &resolver.syms.last().unwrap();
Expand Down Expand Up @@ -268,7 +279,7 @@ mod tests {
};

// The address is less than the smallest address of all symbols.
assert!(resolver.find_ksym(1).is_none());
assert!(resolver.find_ksym(1).is_err());

// The address match symbols exactly (the first address.)
let sym = resolver.find_ksym(0x123).unwrap();
Expand Down
1 change: 1 addition & 0 deletions src/normalize/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ mod tests {
addrs.as_slice().iter().copied(),
entries,
handler,
(),
)
.unwrap()
.normalized;
Expand Down
3 changes: 2 additions & 1 deletion src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::inspect::FindAddrOpts;
use crate::inspect::SymInfo;
use crate::symbolize::AddrCodeInfo;
use crate::symbolize::IntSym;
use crate::symbolize::Reason;
use crate::Addr;
use crate::Result;

Expand All @@ -17,7 +18,7 @@ where
Self: Debug,
{
/// Find the symbol corresponding to the given address.
fn find_sym(&self, addr: Addr) -> Result<Option<IntSym<'_>>>;
fn find_sym(&self, addr: Addr) -> Result<Result<IntSym<'_>, Reason>>;
/// Find information about a symbol given its name.
fn find_addr(&self, name: &str, opts: &FindAddrOpts) -> Result<Vec<SymInfo<'_>>>;
/// Finds the source code location for a given address.
Expand Down
29 changes: 24 additions & 5 deletions src/symbolize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
//! print_frame(&frame.name, None, &frame.code_info);
//! }
//! }
//! Symbolized::Unknown => {
//! Symbolized::Unknown(..) => {
//! println!("{input_addr:#0width$x}: <no-symbol>", width = ADDR_WIDTH)
//! }
//! }
Expand Down Expand Up @@ -313,6 +313,22 @@ pub struct Sym<'src> {
}


/// The reason why symbolization failed.
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum Reason {
/// The file offset does not map to a valid piece of code/data.
InvalidFileOffset,
/// The symbolization source has no or no relevant symbols.
///
/// This reason could for instance be used if a shared object only
/// has dynamic symbols, but appears to be stripped aside from that.
MissingSyms,
/// XXX
UnknownAddr,
}


/// An enumeration used as reporting vehicle for address symbolization.
// We keep this enum as exhaustive because additions to it, should they occur,
// are expected to be backwards-compatibility breaking.
Expand All @@ -321,7 +337,10 @@ pub enum Symbolized<'src> {
/// The input address was symbolized as the provided symbol.
Sym(Sym<'src>),
/// The input address was not found and could not be symbolized.
Unknown,
///
/// The provided reason is a best guess, hinting at what ultimately
/// prevented the symbolization from being successful.
Unknown(Reason),
}

impl<'src> Symbolized<'src> {
Expand All @@ -331,7 +350,7 @@ impl<'src> Symbolized<'src> {
pub fn as_sym(&self) -> Option<&Sym<'src>> {
match self {
Self::Sym(sym) => Some(sym),
Self::Unknown => None,
Self::Unknown(..) => None,
}
}

Expand All @@ -341,7 +360,7 @@ impl<'src> Symbolized<'src> {
pub fn into_sym(self) -> Option<Sym<'src>> {
match self {
Self::Sym(sym) => Some(sym),
Self::Unknown => None,
Self::Unknown(..) => None,
}
}
}
Expand Down Expand Up @@ -397,7 +416,7 @@ mod tests {
/// variant.
#[test]
fn symbolized_unknown_conversions() {
let symbolized = Symbolized::Unknown;
let symbolized = Symbolized::Unknown(Reason::UnknownAddr);
assert_eq!(symbolized.as_sym(), None);
assert_eq!(symbolized.into_sym(), None);
}
Expand Down
Loading

0 comments on commit d4eb1a6

Please sign in to comment.