Skip to content

Commit 82a55b9

Browse files
feat: collect debug info by pid
1 parent 8ab7c34 commit 82a55b9

4 files changed

Lines changed: 38 additions & 15 deletions

File tree

src/executor/wall_time/perf/debug_info.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use addr2line::{fallible_iterator::FallibleIterator, gimli};
55
use object::{Object, ObjectSection};
66
use rayon::prelude::*;
77
use runner_shared::debug_info::{DebugInfo, ModuleDebugInfo};
8+
use std::collections::HashMap;
89
use std::path::Path;
10+
use std::path::PathBuf;
911

1012
type EndianRcSlice = gimli::EndianRcSlice<gimli::RunTimeEndian>;
1113

src/executor/wall_time/perf/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -321,17 +321,16 @@ impl BenchmarkData {
321321
.clone()
322322
.ok_or(BenchmarkDataSaveError::MissingIntegration)?,
323323
uri_by_ts: self.marker_result.uri_by_ts.clone(),
324-
ignored_modules: artifacts.ignored_modules,
324+
ignored_modules_by_pid: artifacts.ignored_modules_by_pid,
325325
markers: self.marker_result.markers.clone(),
326326
debug_info: artifacts.debug_info,
327327
mapped_process_debug_info_by_pid: artifacts.mapped_process_debug_info_by_pid,
328328
mapped_process_unwind_data_by_pid: artifacts.mapped_process_unwind_data_by_pid,
329329
mapped_process_module_symbols: artifacts.symbol_pid_mappings_by_pid,
330330
path_key_to_path: artifacts.key_to_path,
331-
// Not yet implemented
332-
ignored_modules_by_pid: Default::default(),
333331
// Deprecated fields below are no longer used
334332
debug_info_by_pid: Default::default(),
333+
ignored_modules: Default::default(),
335334
};
336335
metadata.save_to(&path).unwrap();
337336

src/executor/wall_time/perf/module_symbols.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ impl ModuleSymbols {
4343
&self.symbols
4444
}
4545

46+
/// Returns `(min_addr, max_addr_end)` covering all symbols, or `None` if empty.
47+
pub fn addr_bounds(&self) -> Option<(u64, u64)> {
48+
let first = self.symbols.first()?;
49+
Some(
50+
self.symbols
51+
.iter()
52+
.fold((first.addr, first.addr + first.size), |(min, max), s| {
53+
(min.min(s.addr), max.max(s.addr + s.size))
54+
}),
55+
)
56+
}
57+
4658
/// Extract symbols from an ELF file (pid-agnostic, load_bias = 0).
4759
pub fn from_elf<P: AsRef<Path>>(path: P) -> anyhow::Result<Self> {
4860
let content = std::fs::read(path.as_ref())?;

src/executor/wall_time/perf/save_artifacts.rs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub struct SavedArtifacts {
1616
pub debug_info: HashMap<String, ModuleDebugInfo>,
1717
pub mapped_process_debug_info_by_pid: HashMap<pid_t, Vec<MappedProcessDebugInfo>>,
1818
pub mapped_process_unwind_data_by_pid: HashMap<pid_t, Vec<MappedProcessUnwindData>>,
19-
pub ignored_modules: Vec<(String, u64, u64)>,
19+
pub ignored_modules_by_pid: HashMap<pid_t, Vec<(String, u64, u64)>>,
2020
pub key_to_path: HashMap<String, PathBuf>,
2121
}
2222

@@ -43,7 +43,7 @@ pub fn save_artifacts(
4343
&mut path_to_key,
4444
);
4545

46-
let ignored_modules = collect_ignored_modules(mounted_modules_by_path);
46+
let ignored_modules_by_pid = collect_ignored_modules(loaded_modules_by_path);
4747

4848
let key_to_path = path_to_key
4949
.into_iter()
@@ -55,7 +55,7 @@ pub fn save_artifacts(
5555
debug_info,
5656
mapped_process_debug_info_by_pid,
5757
mapped_process_unwind_data_by_pid,
58-
ignored_modules,
58+
ignored_modules_by_pid,
5959
key_to_path,
6060
}
6161
}
@@ -247,10 +247,11 @@ fn save_unwind_data(
247247
}
248248

249249
/// Collect ignored modules by finding known-ignored and python modules in the mounted modules.
250+
/// Returns per-pid entries with runtime address ranges derived from symbol bounds + load bias.
250251
fn collect_ignored_modules(
251-
mounted_modules_by_path: &HashMap<PathBuf, MountedModule>,
252-
) -> Vec<(String, u64, u64)> {
253-
let mut to_ignore = vec![];
252+
loaded_modules_by_path: &HashMap<PathBuf, LoadedModule>,
253+
) -> HashMap<pid_t, Vec<(String, u64, u64)>> {
254+
let mut by_pid: HashMap<pid_t, Vec<(String, u64, u64)>> = HashMap::new();
254255

255256
let ignore_paths = get_objects_path_to_ignore();
256257

@@ -269,16 +270,25 @@ fn collect_ignored_modules(
269270
continue;
270271
}
271272

272-
for pm in m.process_mounted_module.values() {
273-
if let Some(ref pud) = pm.process_unwind_data {
274-
to_ignore.push((
273+
let addr_bounds = loaded_module
274+
.module_symbols
275+
.as_ref()
276+
.and_then(|ms| ms.addr_bounds());
277+
278+
let Some((elf_start, elf_end)) = addr_bounds else {
279+
continue;
280+
};
281+
282+
for (&pid, pm) in &loaded_module.process_loaded_modules {
283+
if let Some(load_bias) = pm.symbols_load_bias {
284+
by_pid.entry(pid).or_default().push((
275285
path_str.to_string(),
276-
pud.avma_range.start,
277-
pud.avma_range.end,
286+
elf_start + load_bias,
287+
elf_end + load_bias,
278288
));
279289
}
280290
}
281291
}
282292

283-
to_ignore
293+
by_pid
284294
}

0 commit comments

Comments
 (0)