1#![cfg_attr(docsrs, feature(doc_cfg))]
34#![cfg_attr(feature = "nightly", feature(test))]
35#![cfg_attr(
36 not(all(
37 feature = "apk",
38 feature = "bpf",
39 feature = "breakpad",
40 feature = "dwarf",
41 feature = "gsym"
42 )),
43 allow(dead_code, unused_imports)
44)]
45#![cfg_attr(not(linux), allow(dead_code, unused_imports))]
46
47
48#[cfg(feature = "nightly")]
49#[allow(unused_extern_crates)]
50extern crate test;
51
52#[macro_use]
53mod cfg;
54#[cfg(feature = "apk")]
55mod apk;
56#[cfg(feature = "breakpad")]
57mod breakpad;
58#[cfg(feature = "dwarf")]
59mod dwarf;
60mod elf;
61mod error;
62mod file_cache;
63#[cfg(feature = "gsym")]
64mod gsym;
65mod insert_map;
66pub mod inspect;
67mod kernel;
68mod maps;
69mod mmap;
70pub mod normalize;
71mod pathlike;
72mod perf_map;
73mod pid;
74pub mod symbolize;
75#[cfg(any(test, feature = "test"))]
76mod test_helper;
77mod util;
78mod vdso;
79#[cfg(feature = "apk")]
80mod zip;
81
82use std::result;
83
84
85pub use crate::error::Error;
86pub use crate::error::ErrorExt;
87pub use crate::error::ErrorKind;
88pub use crate::error::IntoError;
89pub use crate::mmap::Mmap;
90pub use crate::normalize::buildid::BuildId;
91pub use crate::pid::Pid;
92
93pub type Result<T, E = Error> = result::Result<T, E>;
95
96
97pub type Addr = u64;
99
100
101#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
103#[non_exhaustive]
104pub enum SymType {
105 #[default]
111 Undefined,
112 Function,
114 Variable,
116}
117
118
119#[derive(Clone, Debug, PartialEq)]
121pub enum MaybeDefault<T> {
122 None,
124 Default,
126 Some(T),
128}
129
130impl<T> From<T> for MaybeDefault<T> {
131 #[inline]
132 fn from(value: T) -> Self {
133 Self::Some(value)
134 }
135}
136
137
138pub mod helper {
140 use super::Addr;
141 use super::Result;
142
143 pub use crate::normalize::buildid::read_elf_build_id;
144 pub use crate::normalize::buildid::read_elf_build_id_from_mmap;
145 pub use crate::normalize::ioctl::is_procmap_query_supported;
146
147 cfg_breakpad! {
148 pub use crate::breakpad::BreakpadResolver;
149 }
150 pub use crate::elf::ElfResolver;
151 cfg_gsym! {
152 use std::path::Path;
153 use crate::symbolize::Symbolize;
154 use crate::symbolize::ResolvedSym;
155 use crate::symbolize::Reason;
156 use crate::symbolize::FindSymOpts;
157 use crate::gsym;
158
159 #[derive(Debug)]
162 pub struct GsymResolver(gsym::GsymResolver<'static>);
163
164 impl GsymResolver {
165 #[inline]
167 pub fn open<P>(path: P) -> Result<Self>
168 where
169 P: AsRef<Path>,
170 {
171 Ok(Self(gsym::GsymResolver::open(path)?))
172 }
173 }
174
175 impl Symbolize for GsymResolver {
176 #[inline]
177 fn find_sym(&self, addr: Addr, opts: &FindSymOpts) -> Result<Result<ResolvedSym<'_>, Reason>> {
178 self.0.find_sym(addr, opts)
179 }
180 }
181 }
182}
183
184#[doc(hidden)]
188pub mod __private {
189 pub use crate::util::bytes_to_path;
190 pub use crate::util::stat;
191 pub use crate::util::ReadRaw;
192
193 #[cfg(feature = "apk")]
194 pub mod zip {
195 pub use crate::zip::Archive;
196 }
197
198 #[cfg(linux)]
199 #[cfg(feature = "test")]
200 pub use crate::test_helper::find_gettimeofday_in_process;
201 #[cfg(feature = "test")]
202 pub use crate::test_helper::find_the_answer_fn;
203 #[cfg(feature = "test")]
204 pub use crate::test_helper::find_the_answer_fn_in_zip;
205 #[cfg(linux)]
206 #[cfg(feature = "test")]
207 pub use crate::test_helper::find_vdso_range;
208}
209
210
211#[cfg(feature = "tracing")]
212#[macro_use]
213#[allow(unused_imports)]
214mod log {
215 pub(crate) use tracing::debug;
216 pub(crate) use tracing::error;
217 pub(crate) use tracing::info;
218 pub(crate) use tracing::instrument;
219 pub(crate) use tracing::trace;
220 pub(crate) use tracing::warn;
221}
222
223#[cfg(not(feature = "tracing"))]
224#[macro_use]
225#[allow(unused_imports)]
226mod log {
227 macro_rules! debug {
228 ($($args:tt)*) => {{
229 if false {
230 let _args = format_args!($($args)*);
233 }
234 }};
235 }
236 pub(crate) use debug;
237 pub(crate) use debug as error;
238 pub(crate) use debug as info;
239 pub(crate) use debug as trace;
240 pub(crate) use debug as warn;
241}
242
243
244#[cfg(test)]
245mod tests {
246 use super::*;
247
248 use std::path::Path;
249
250 use crate::symbolize::FindSymOpts;
251 use crate::symbolize::Symbolize as _;
252
253
254 #[test]
256 fn gsym_resolver() {
257 let test_gsym = Path::new(&env!("CARGO_MANIFEST_DIR"))
258 .join("data")
259 .join("test-stable-addrs.gsym");
260
261 let resolver = helper::GsymResolver::open(test_gsym).unwrap();
262 let sym = resolver
263 .find_sym(0x2000200, &FindSymOpts::Basic)
264 .unwrap()
265 .unwrap();
266 assert_eq!(sym.name, "factorial");
267 }
268}