Skip to content

Commit

Permalink
Handle address lookup failures more gracefully
Browse files Browse the repository at this point in the history
When symbolizing addresses in a process, we error out on two paths when
failing to find the address. However, it seems more apt to handle these
cases gracefully and indicate an unknown address instead.

Signed-off-by: Daniel Müller <[email protected]>
  • Loading branch information
d-e-s-o authored and danielocfb committed Oct 17, 2023
1 parent 4be5e02 commit e67f5c8
Showing 1 changed file with 36 additions and 42 deletions.
78 changes: 36 additions & 42 deletions src/symbolize/symbolizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::maps::PathMapsEntry;
use crate::normalize;
use crate::normalize::create_apk_elf_path;
use crate::normalize::normalize_sorted_user_addrs_with_entries;
use crate::normalize::Handler as _;
use crate::util;
use crate::util::uname_release;
use crate::zip;
Expand Down Expand Up @@ -343,29 +344,24 @@ impl Symbolizer {
fn handle_apk_addr(&mut self, addr: Addr, entry: &PathMapsEntry) -> Result<()> {
let file_off = addr - entry.range.start + entry.offset;
let apk_path = &entry.path.symbolic_path;
// TODO: We should probably symbolize the address to
// `Symbolized::Unknown` instead of erroring out.
let (norm_addr, elf_path, elf_parser) = find_apk_elf_addr(file_off, apk_path)?
.ok_or_invalid_input(|| {
format!(
"failed to find ELF entry in {} that contains file offset {:#x}",
apk_path.display(),
file_off
)
})?;
// Create an Android-style binary-in-APK path for
// reporting purposes.
let apk_elf_path = create_apk_elf_path(apk_path, &elf_path)?;
// TODO: Should support DWARF as well. In general this needs to
// go through the "ELF cache".
let backend = ElfBackend::Elf(Rc::new(elf_parser));

let resolver = ElfResolver::with_backend(&apk_elf_path, backend)?;
let symbol = self
.symbolizer
.symbolize_with_resolver(norm_addr, &resolver)?;
let () = self.all_symbols.push(symbol);
Ok(())
match find_apk_elf_addr(file_off, apk_path)? {
Some((norm_addr, elf_path, elf_parser)) => {
// Create an Android-style binary-in-APK path for
// reporting purposes.
let apk_elf_path = create_apk_elf_path(apk_path, &elf_path)?;
// TODO: Should support DWARF as well. In general this needs to
// go through the "ELF cache".
let backend = ElfBackend::Elf(Rc::new(elf_parser));

let resolver = ElfResolver::with_backend(&apk_elf_path, backend)?;
let symbol = self
.symbolizer
.symbolize_with_resolver(norm_addr, &resolver)?;
let () = self.all_symbols.push(symbol);
Ok(())
}
None => self.handle_unknown_addr(addr),
}
}

fn handle_elf_addr(&mut self, addr: Addr, entry: &PathMapsEntry) -> Result<()> {
Expand All @@ -374,25 +370,23 @@ impl Symbolizer {
let parser = ElfParser::open(&entry.path.maps_file).with_context(|| {
format!("failed to open map file {}", entry.path.maps_file.display())
})?;
let norm_addr =
elf_offset_to_address(file_off, &parser)?.ok_or_invalid_input(|| {
format!(
"failed to find ELF segment in {} that contains file offset {:#x}",
entry.path.symbolic_path.display(),
entry.offset,
)
})?;
let symbol = self
.symbolizer
.resolve_addr_in_elf(norm_addr, path)
.with_context(|| {
format!(
"failed to symbolize normalized address {norm_addr:#x} in ELF file {}",
path.display()
)
})?;
let () = self.all_symbols.push(symbol);
Ok(())

match elf_offset_to_address(file_off, &parser)? {
Some(norm_addr) => {
let symbol = self
.symbolizer
.resolve_addr_in_elf(norm_addr, path)
.with_context(|| {
format!(
"failed to symbolize normalized address {norm_addr:#x} in ELF file {}",
path.display()
)
})?;
let () = self.all_symbols.push(symbol);
Ok(())
}
None => self.handle_unknown_addr(addr),
}
}
}

Expand Down

0 comments on commit e67f5c8

Please sign in to comment.