From ed777273b187cc30afa573101a1fade14a4fb465 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Thu, 10 Aug 2023 17:22:56 +0200 Subject: [PATCH] nuclear option: no symbol resolution in the crate --- aya/src/maps/stack_trace.rs | 58 ++++++++++--------------------------- aya/src/util.rs | 19 +++--------- xtask/public-api/aya.txt | 9 +----- 3 files changed, 20 insertions(+), 66 deletions(-) diff --git a/aya/src/maps/stack_trace.rs b/aya/src/maps/stack_trace.rs index 63a92fe9..8d3add5a 100644 --- a/aya/src/maps/stack_trace.rs +++ b/aya/src/maps/stack_trace.rs @@ -1,12 +1,7 @@ //! A hash map of kernel or user space stack traces. //! //! See [`StackTraceMap`] for documentation and examples. -use std::{ - borrow::{Borrow, Cow}, - fs, io, mem, - path::Path, - str::FromStr, -}; +use std::{borrow::Borrow, fs, io, mem, path::Path, str::FromStr}; use crate::{ maps::{IterableMap, MapData, MapError, MapIter, MapKeys}, @@ -51,15 +46,19 @@ use crate::{ /// // here we resolve symbol names using kernel symbols. If this was a user space stack (for /// // example captured from a uprobe), you'd have to load the symbols using some other mechanism /// // (eg loading the target binary debuginfo) -/// for frame in stack_trace.resolve(&ksyms).frames() { -/// println!( -/// "{:#x} {}", -/// frame.ip, -/// frame -/// .symbol_name -/// .as_deref() -/// .unwrap_or("[unknown symbol name]") -/// ); +/// for frame in stack_trace.frames() { +/// if let Some(sym) = ksyms.range(..=frame.ip).next_back().map(|(_, s)| s) { +/// println!( +/// "{:#x} {}", +/// frame.ip, +/// sym +/// ); +/// } else { +/// println!( +/// "{:#x}", +/// frame.ip +/// ); +/// } /// } /// /// # Ok::<(), Error>(()) @@ -118,10 +117,7 @@ impl> StackTraceMap { let frames = frames .into_iter() .take_while(|ip| *ip != 0) - .map(|ip| StackFrame { - ip, - symbol_name: None, - }) + .map(|ip| StackFrame { ip }) .collect::>(); Ok(StackTrace { @@ -162,12 +158,6 @@ impl<'a, T: Borrow> IntoIterator for &'a StackTraceMap { } } -/// A resolver for symbols based on an address obtained from a stack trace. -pub trait SymbolResolver { - /// Resolve a symbol for a given address, if possible. - fn resolve_symbol(&self, addr: u64) -> Option>; -} - /// A kernel or user space stack trace. /// /// See the [`StackTraceMap`] documentation for examples. @@ -178,19 +168,6 @@ pub struct StackTrace { } impl StackTrace { - /// Resolves symbol names using the given symbol map. - /// - /// You can use [`util::kernel_symbols()`](crate::util::kernel_symbols) to load kernel symbols. For - /// user-space traces you need to provide the symbols, for example loading - /// them from debug info. - pub fn resolve(&mut self, symbols: &R) -> &StackTrace { - for frame in self.frames.iter_mut() { - frame.symbol_name = symbols.resolve_symbol(frame.ip).map(|s| s.into_owned()) - } - - self - } - /// Returns the frames in this stack trace. pub fn frames(&self) -> &[StackFrame] { &self.frames @@ -201,11 +178,6 @@ impl StackTrace { pub struct StackFrame { /// The instruction pointer of this frame. pub ip: u64, - /// The symbol name corresponding to the start of this frame. - /// - /// Set to `Some()` if the frame address can be found in the symbols passed - /// to [`StackTrace::resolve`]. - pub symbol_name: Option, } fn sysctl(key: &str) -> Result { diff --git a/aya/src/util.rs b/aya/src/util.rs index 1161885e..4db89af8 100644 --- a/aya/src/util.rs +++ b/aya/src/util.rs @@ -1,6 +1,5 @@ //! Utility functions. use std::{ - borrow::Cow, collections::BTreeMap, error::Error, ffi::{CStr, CString}, @@ -12,7 +11,6 @@ use std::{ use crate::{ generated::{TC_H_MAJ_MASK, TC_H_MIN_MASK}, - maps::stack_trace::SymbolResolver, Pod, }; @@ -203,25 +201,16 @@ fn parse_cpu_ranges(data: &str) -> Result, ()> { Ok(cpus) } -/// The simplest resolver: a direct map from addresses to strings. -pub type SimpleSymbolResolver = BTreeMap; - -impl SymbolResolver for SimpleSymbolResolver { - fn resolve_symbol(&self, addr: u64) -> Option> { - self.range(..=addr).next_back().map(|(_, s)| s.into()) - } -} - /// Loads kernel symbols from `/proc/kallsyms`. /// -/// The symbols can be passed to [`StackTrace::resolve`](crate::maps::stack_trace::StackTrace::resolve). -pub fn kernel_symbols() -> Result { +/// See [`crate::maps::StackTraceMap`] for an example on how to use this to resolve kernel addresses to symbols. +pub fn kernel_symbols() -> Result, io::Error> { let mut reader = BufReader::new(File::open("/proc/kallsyms")?); parse_kernel_symbols(&mut reader) } -fn parse_kernel_symbols(reader: impl BufRead) -> Result { - let mut syms = SimpleSymbolResolver::new(); +fn parse_kernel_symbols(reader: impl BufRead) -> Result, io::Error> { + let mut syms = BTreeMap::new(); for line in reader.lines() { let line = line?; diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt index 7adc9b63..db03ee59 100644 --- a/xtask/public-api/aya.txt +++ b/xtask/public-api/aya.txt @@ -708,7 +708,6 @@ pub fn aya::maps::stack::Stack::from(t: T) -> T pub mod aya::maps::stack_trace pub struct aya::maps::stack_trace::StackFrame pub aya::maps::stack_trace::StackFrame::ip: u64 -pub aya::maps::stack_trace::StackFrame::symbol_name: core::option::Option impl core::marker::Send for aya::maps::stack_trace::StackFrame impl core::marker::Sync for aya::maps::stack_trace::StackFrame impl core::marker::Unpin for aya::maps::stack_trace::StackFrame @@ -734,7 +733,6 @@ pub struct aya::maps::stack_trace::StackTrace pub aya::maps::stack_trace::StackTrace::id: u32 impl aya::maps::stack_trace::StackTrace pub fn aya::maps::stack_trace::StackTrace::frames(&self) -> &[aya::maps::stack_trace::StackFrame] -pub fn aya::maps::stack_trace::StackTrace::resolve(&mut self, symbols: &R) -> &aya::maps::stack_trace::StackTrace impl> aya::maps::IterableMap for aya::maps::stack_trace::StackTraceMap pub fn aya::maps::stack_trace::StackTraceMap::get(&self, index: &u32) -> core::result::Result pub fn aya::maps::stack_trace::StackTraceMap::map(&self) -> &aya::maps::MapData @@ -803,10 +801,6 @@ impl core::borrow::BorrowMut for aya::maps::stack_trace::StackTraceMap pub fn aya::maps::stack_trace::StackTraceMap::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya::maps::stack_trace::StackTraceMap pub fn aya::maps::stack_trace::StackTraceMap::from(t: T) -> T -pub trait aya::maps::stack_trace::SymbolResolver -pub fn aya::maps::stack_trace::SymbolResolver::resolve_symbol(&self, addr: u64) -> core::option::Option> -impl aya::maps::stack_trace::SymbolResolver for aya::util::SimpleSymbolResolver -pub fn aya::util::SimpleSymbolResolver::resolve_symbol(&self, addr: u64) -> core::option::Option> pub enum aya::maps::Map pub aya::maps::Map::Array(aya::maps::MapData) pub aya::maps::Map::BloomFilter(aya::maps::MapData) @@ -6935,11 +6929,10 @@ impl core::borrow::BorrowMut for aya::util::KernelVersion where T: core::m pub fn aya::util::KernelVersion::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya::util::KernelVersion pub fn aya::util::KernelVersion::from(t: T) -> T -pub fn aya::util::kernel_symbols() -> core::result::Result +pub fn aya::util::kernel_symbols() -> core::result::Result, std::io::error::Error> pub fn aya::util::nr_cpus() -> core::result::Result pub fn aya::util::online_cpus() -> core::result::Result, std::io::error::Error> pub fn aya::util::syscall_prefix() -> core::result::Result<&'static str, std::io::error::Error> -pub type aya::util::SimpleSymbolResolver = alloc::collections::btree::map::BTreeMap pub macro aya::include_bytes_aligned! pub enum aya::BpfError pub aya::BpfError::BtfError(aya_obj::btf::btf::BtfError)