1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
//! **blazesym** is a library that can be used to symbolize addresses. Address
//! symbolization is a common problem in tracing contexts, for example, where users
//! want to reason about functions by name, but low level components report only the
//! "raw" addresses (e.g., in the form of stacktraces).
//!
//! In addition to symbolization, **blazesym** also provides APIs for the reverse
//! operation: looking up addresses from symbol names. That can be useful, for
//! example, for configuring breakpoints or tracepoints.
//!
//! ## Overview
//! The crate is organized via public modules that expose functionality
//! pertaining a certain topic. Specifically, these areas are currently covered:
//!
//! - [`symbolize`] covers address symbolization functionality
//! - [`inspect`] contains APIs for inspecting files such as ELF and Gsym to
//! lookup addresses to symbol names, for example
//! - [`normalize`] exposes address normalization functionality
//!
//! C API bindings are defined in a cross-cutting manner as part of the
//! `cblazesym` crate (note that Rust code should not have to consume
//! these functions and on the ABI level this module organization has no
//! relevance for C).
#![allow(
clippy::collapsible_if,
clippy::fn_to_numeric_cast,
clippy::let_and_return,
clippy::let_unit_value
)]
#![deny(unsafe_op_in_unsafe_fn)]
#![warn(
missing_debug_implementations,
missing_docs,
rustdoc::broken_intra_doc_links
)]
#![cfg_attr(feature = "nightly", feature(test))]
#![cfg_attr(not(feature = "dwarf"), allow(dead_code))]
#[cfg(feature = "nightly")]
extern crate test;
#[cfg(feature = "dwarf")]
mod dwarf;
mod elf;
mod error;
mod file_cache;
mod gsym;
mod insert_map;
pub mod inspect;
mod kernel;
mod ksym;
mod maps;
mod mmap;
pub mod normalize;
mod once;
mod resolver;
pub mod symbolize;
mod util;
mod zip;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result as FmtResult;
use std::num::NonZeroU32;
use std::result;
use resolver::SymResolver;
pub use crate::error::Error;
pub use crate::error::ErrorExt;
pub use crate::error::ErrorKind;
pub use crate::error::IntoError;
/// A result type using our [`Error`] by default.
pub type Result<T, E = Error> = result::Result<T, E>;
/// A type representing addresses.
pub type Addr = u64;
/// Utility functionality not specific to any overarching theme.
pub mod helper {
pub use crate::normalize::buildid::read_elf_build_id;
}
/// An enumeration identifying a process.
#[derive(Clone, Copy, Debug)]
pub enum Pid {
/// The current process.
Slf,
/// The process identified by the provided ID.
Pid(NonZeroU32),
}
impl Display for Pid {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
Self::Slf => write!(f, "self"),
Self::Pid(pid) => write!(f, "{pid}"),
}
}
}
impl From<u32> for Pid {
fn from(pid: u32) -> Self {
NonZeroU32::new(pid).map(Pid::Pid).unwrap_or(Pid::Slf)
}
}
#[cfg(feature = "tracing")]
#[macro_use]
#[allow(unused_imports)]
mod log {
pub(crate) use tracing::debug;
pub(crate) use tracing::error;
pub(crate) use tracing::info;
pub(crate) use tracing::instrument;
pub(crate) use tracing::trace;
pub(crate) use tracing::warn;
}
#[cfg(not(feature = "tracing"))]
#[macro_use]
#[allow(unused_imports)]
mod log {
macro_rules! debug {
($($args:tt)*) => {{
if false {
// Make sure to use `args` to prevent any warnings about
// unused variables.
let _args = format_args!($($args)*);
}
}};
}
pub(crate) use debug;
pub(crate) use debug as error;
pub(crate) use debug as info;
pub(crate) use debug as trace;
pub(crate) use debug as warn;
}