nuclear option: no symbol resolution in the crate

pull/740/head
Addison Crump 1 year ago
parent fbbf191bd3
commit ed777273b1
No known key found for this signature in database
GPG Key ID: D495C2DF24C779B2

@ -1,12 +1,7 @@
//! A hash map of kernel or user space stack traces. //! A hash map of kernel or user space stack traces.
//! //!
//! See [`StackTraceMap`] for documentation and examples. //! See [`StackTraceMap`] for documentation and examples.
use std::{ use std::{borrow::Borrow, fs, io, mem, path::Path, str::FromStr};
borrow::{Borrow, Cow},
fs, io, mem,
path::Path,
str::FromStr,
};
use crate::{ use crate::{
maps::{IterableMap, MapData, MapError, MapIter, MapKeys}, maps::{IterableMap, MapData, MapError, MapIter, MapKeys},
@ -51,16 +46,20 @@ use crate::{
/// // here we resolve symbol names using kernel symbols. If this was a user space stack (for /// // 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 /// // example captured from a uprobe), you'd have to load the symbols using some other mechanism
/// // (eg loading the target binary debuginfo) /// // (eg loading the target binary debuginfo)
/// for frame in stack_trace.resolve(&ksyms).frames() { /// for frame in stack_trace.frames() {
/// if let Some(sym) = ksyms.range(..=frame.ip).next_back().map(|(_, s)| s) {
/// println!( /// println!(
/// "{:#x} {}", /// "{:#x} {}",
/// frame.ip, /// frame.ip,
/// frame /// sym
/// .symbol_name /// );
/// .as_deref() /// } else {
/// .unwrap_or("[unknown symbol name]") /// println!(
/// "{:#x}",
/// frame.ip
/// ); /// );
/// } /// }
/// }
/// ///
/// # Ok::<(), Error>(()) /// # Ok::<(), Error>(())
/// ``` /// ```
@ -118,10 +117,7 @@ impl<T: Borrow<MapData>> StackTraceMap<T> {
let frames = frames let frames = frames
.into_iter() .into_iter()
.take_while(|ip| *ip != 0) .take_while(|ip| *ip != 0)
.map(|ip| StackFrame { .map(|ip| StackFrame { ip })
ip,
symbol_name: None,
})
.collect::<Vec<_>>(); .collect::<Vec<_>>();
Ok(StackTrace { Ok(StackTrace {
@ -162,12 +158,6 @@ impl<'a, T: Borrow<MapData>> IntoIterator for &'a StackTraceMap<T> {
} }
} }
/// 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<Cow<'_, str>>;
}
/// A kernel or user space stack trace. /// A kernel or user space stack trace.
/// ///
/// See the [`StackTraceMap`] documentation for examples. /// See the [`StackTraceMap`] documentation for examples.
@ -178,19 +168,6 @@ pub struct StackTrace {
} }
impl 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<R: SymbolResolver>(&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. /// Returns the frames in this stack trace.
pub fn frames(&self) -> &[StackFrame] { pub fn frames(&self) -> &[StackFrame] {
&self.frames &self.frames
@ -201,11 +178,6 @@ impl StackTrace {
pub struct StackFrame { pub struct StackFrame {
/// The instruction pointer of this frame. /// The instruction pointer of this frame.
pub ip: u64, 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<String>,
} }
fn sysctl<T: FromStr>(key: &str) -> Result<T, io::Error> { fn sysctl<T: FromStr>(key: &str) -> Result<T, io::Error> {

@ -1,6 +1,5 @@
//! Utility functions. //! Utility functions.
use std::{ use std::{
borrow::Cow,
collections::BTreeMap, collections::BTreeMap,
error::Error, error::Error,
ffi::{CStr, CString}, ffi::{CStr, CString},
@ -12,7 +11,6 @@ use std::{
use crate::{ use crate::{
generated::{TC_H_MAJ_MASK, TC_H_MIN_MASK}, generated::{TC_H_MAJ_MASK, TC_H_MIN_MASK},
maps::stack_trace::SymbolResolver,
Pod, Pod,
}; };
@ -203,25 +201,16 @@ fn parse_cpu_ranges(data: &str) -> Result<Vec<u32>, ()> {
Ok(cpus) Ok(cpus)
} }
/// The simplest resolver: a direct map from addresses to strings.
pub type SimpleSymbolResolver = BTreeMap<u64, String>;
impl SymbolResolver for SimpleSymbolResolver {
fn resolve_symbol(&self, addr: u64) -> Option<Cow<'_, str>> {
self.range(..=addr).next_back().map(|(_, s)| s.into())
}
}
/// Loads kernel symbols from `/proc/kallsyms`. /// Loads kernel symbols from `/proc/kallsyms`.
/// ///
/// The symbols can be passed to [`StackTrace::resolve`](crate::maps::stack_trace::StackTrace::resolve). /// See [`crate::maps::StackTraceMap`] for an example on how to use this to resolve kernel addresses to symbols.
pub fn kernel_symbols() -> Result<SimpleSymbolResolver, io::Error> { pub fn kernel_symbols() -> Result<BTreeMap<u64, String>, io::Error> {
let mut reader = BufReader::new(File::open("/proc/kallsyms")?); let mut reader = BufReader::new(File::open("/proc/kallsyms")?);
parse_kernel_symbols(&mut reader) parse_kernel_symbols(&mut reader)
} }
fn parse_kernel_symbols(reader: impl BufRead) -> Result<SimpleSymbolResolver, io::Error> { fn parse_kernel_symbols(reader: impl BufRead) -> Result<BTreeMap<u64, String>, io::Error> {
let mut syms = SimpleSymbolResolver::new(); let mut syms = BTreeMap::new();
for line in reader.lines() { for line in reader.lines() {
let line = line?; let line = line?;

@ -708,7 +708,6 @@ pub fn aya::maps::stack::Stack<T, V>::from(t: T) -> T
pub mod aya::maps::stack_trace pub mod aya::maps::stack_trace
pub struct aya::maps::stack_trace::StackFrame pub struct aya::maps::stack_trace::StackFrame
pub aya::maps::stack_trace::StackFrame::ip: u64 pub aya::maps::stack_trace::StackFrame::ip: u64
pub aya::maps::stack_trace::StackFrame::symbol_name: core::option::Option<alloc::string::String>
impl core::marker::Send for aya::maps::stack_trace::StackFrame impl core::marker::Send for aya::maps::stack_trace::StackFrame
impl core::marker::Sync 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 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 pub aya::maps::stack_trace::StackTrace::id: u32
impl aya::maps::stack_trace::StackTrace 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::frames(&self) -> &[aya::maps::stack_trace::StackFrame]
pub fn aya::maps::stack_trace::StackTrace::resolve<R: aya::maps::stack_trace::SymbolResolver>(&mut self, symbols: &R) -> &aya::maps::stack_trace::StackTrace
impl<T: core::borrow::Borrow<aya::maps::MapData>> aya::maps::IterableMap<u32, aya::maps::stack_trace::StackTrace> for aya::maps::stack_trace::StackTraceMap<T> impl<T: core::borrow::Borrow<aya::maps::MapData>> aya::maps::IterableMap<u32, aya::maps::stack_trace::StackTrace> for aya::maps::stack_trace::StackTraceMap<T>
pub fn aya::maps::stack_trace::StackTraceMap<T>::get(&self, index: &u32) -> core::result::Result<aya::maps::stack_trace::StackTrace, aya::maps::MapError> pub fn aya::maps::stack_trace::StackTraceMap<T>::get(&self, index: &u32) -> core::result::Result<aya::maps::stack_trace::StackTrace, aya::maps::MapError>
pub fn aya::maps::stack_trace::StackTraceMap<T>::map(&self) -> &aya::maps::MapData pub fn aya::maps::stack_trace::StackTraceMap<T>::map(&self) -> &aya::maps::MapData
@ -803,10 +801,6 @@ impl<T> core::borrow::BorrowMut<T> for aya::maps::stack_trace::StackTraceMap<T>
pub fn aya::maps::stack_trace::StackTraceMap<T>::borrow_mut(&mut self) -> &mut T pub fn aya::maps::stack_trace::StackTraceMap<T>::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::maps::stack_trace::StackTraceMap<T> impl<T> core::convert::From<T> for aya::maps::stack_trace::StackTraceMap<T>
pub fn aya::maps::stack_trace::StackTraceMap<T>::from(t: T) -> T pub fn aya::maps::stack_trace::StackTraceMap<T>::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<alloc::borrow::Cow<'_, str>>
impl aya::maps::stack_trace::SymbolResolver for aya::util::SimpleSymbolResolver
pub fn aya::util::SimpleSymbolResolver::resolve_symbol(&self, addr: u64) -> core::option::Option<alloc::borrow::Cow<'_, str>>
pub enum aya::maps::Map pub enum aya::maps::Map
pub aya::maps::Map::Array(aya::maps::MapData) pub aya::maps::Map::Array(aya::maps::MapData)
pub aya::maps::Map::BloomFilter(aya::maps::MapData) pub aya::maps::Map::BloomFilter(aya::maps::MapData)
@ -6935,11 +6929,10 @@ impl<T> core::borrow::BorrowMut<T> for aya::util::KernelVersion where T: core::m
pub fn aya::util::KernelVersion::borrow_mut(&mut self) -> &mut T pub fn aya::util::KernelVersion::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::util::KernelVersion impl<T> core::convert::From<T> for aya::util::KernelVersion
pub fn aya::util::KernelVersion::from(t: T) -> T pub fn aya::util::KernelVersion::from(t: T) -> T
pub fn aya::util::kernel_symbols() -> core::result::Result<aya::util::SimpleSymbolResolver, std::io::error::Error> pub fn aya::util::kernel_symbols() -> core::result::Result<alloc::collections::btree::map::BTreeMap<u64, alloc::string::String>, std::io::error::Error>
pub fn aya::util::nr_cpus() -> core::result::Result<usize, std::io::error::Error> pub fn aya::util::nr_cpus() -> core::result::Result<usize, std::io::error::Error>
pub fn aya::util::online_cpus() -> core::result::Result<alloc::vec::Vec<u32>, std::io::error::Error> pub fn aya::util::online_cpus() -> core::result::Result<alloc::vec::Vec<u32>, std::io::error::Error>
pub fn aya::util::syscall_prefix() -> core::result::Result<&'static str, 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<u64, alloc::string::String>
pub macro aya::include_bytes_aligned! pub macro aya::include_bytes_aligned!
pub enum aya::BpfError pub enum aya::BpfError
pub aya::BpfError::BtfError(aya_obj::btf::btf::BtfError) pub aya::BpfError::BtfError(aya_obj::btf::btf::BtfError)

Loading…
Cancel
Save