diff --git a/src/profiler.rs b/src/profiler.rs index c343f15..3523b46 100644 --- a/src/profiler.rs +++ b/src/profiler.rs @@ -3,6 +3,7 @@ use parking_lot::RwLock; use std::collections::hash_map::Entry; use std::collections::hash_map::OccupiedEntry; use std::collections::HashMap; +use std::env::temp_dir; use std::fs; use std::mem::size_of; use std::mem::ManuallyDrop; @@ -41,8 +42,8 @@ use crate::process::{ ProcessStatus, }; use crate::profile::*; -use crate::unwind_info::compact_unwind_info; use crate::unwind_info::log_unwind_info_sections; +use crate::unwind_info::manager::UnwindInfoManager; use crate::unwind_info::types::CompactUnwindRow; use crate::util::{get_online_cpus, summarize_address_range}; use lightswitch_object::{ExecutableId, ObjectFile}; @@ -121,9 +122,11 @@ pub struct Profiler { /// evictions which might reduce the quality of the profiles and in more work /// for the profiler. max_native_unwind_info_size_mb: i32, + unwind_info_manager: UnwindInfoManager, } pub struct ProfilerConfig { + pub cache_dir: PathBuf, pub libbpf_debug: bool, pub bpf_logging: bool, pub duration: Duration, @@ -143,6 +146,7 @@ pub struct ProfilerConfig { impl Default for ProfilerConfig { fn default() -> Self { Self { + cache_dir: temp_dir(), libbpf_debug: false, bpf_logging: false, duration: Duration::MAX, @@ -387,6 +391,7 @@ impl Profiler { native_unwind_info_bucket_sizes: profiler_config.native_unwind_info_bucket_sizes, debug_info_manager: profiler_config.debug_info_manager, max_native_unwind_info_size_mb: profiler_config.max_native_unwind_info_size_mb, + unwind_info_manager: UnwindInfoManager::new(&profiler_config.cache_dir, None), } } @@ -1248,32 +1253,34 @@ impl Profiler { ) .entered(); - let unwind_info: Vec = - match compact_unwind_info(&executable_path_open.to_string_lossy()) { - Ok(unwind_info) => unwind_info, - Err(e) => { - let executable_path_str = executable_path; - let known_naughty = executable_path_str.contains("libicudata"); - - // tracing doesn't support a level chosen at runtime: https://github.com/tokio-rs/tracing/issues/2730 - if known_naughty { - debug!( - "failed to get unwind information for {} with {}", - executable_path_str, e - ); - } else { - info!( - "failed to get unwind information for {} with {}", - executable_path_str, e - ); + let unwind_info = self + .unwind_info_manager + .fetch_unwind_info(&executable_path_open, executable_id); + let unwind_info: Vec = match unwind_info { + Ok(unwind_info) => unwind_info, + Err(e) => { + let executable_path_str = executable_path; + let known_naughty = executable_path_str.contains("libicudata"); + + // tracing doesn't support a level chosen at runtime: https://github.com/tokio-rs/tracing/issues/2730 + if known_naughty { + debug!( + "failed to get unwind information for {} with {}", + executable_path_str, e + ); + } else { + info!( + "failed to get unwind information for {} with {}", + executable_path_str, e + ); - if let Err(e) = log_unwind_info_sections(&executable_path_open) { - warn!("log_unwind_info_sections failed with {}", e); - } + if let Err(e) = log_unwind_info_sections(&executable_path_open) { + warn!("log_unwind_info_sections failed with {}", e); } - return; } - }; + return; + } + }; span.exit(); let bucket = @@ -1527,7 +1534,7 @@ impl Profiler { let object_file = match ObjectFile::new(&PathBuf::from(abs_path.clone())) { Ok(f) => f, Err(e) => { - warn!("object_file {} failed with {:?}", abs_path, e); + warn!("object_file {} failed with {}", abs_path, e); // Rather than returning here, we prefer to be able to profile some // parts of the binary continue;