From 4fec70b28eca534df9099644043d1dcfb3027037 Mon Sep 17 00:00:00 2001 From: not-matthias Date: Mon, 20 Apr 2026 12:21:56 +0200 Subject: [PATCH] feat: warn when libc debug info is not found When libc-dbg is not installed, libc frames in perf flamegraphs appear as bare hex addresses, making comparisons unusable. This adds a warning during walltime profile processing when libc is loaded but has no DWARF debug info, suggesting users install libc6-dbg. --- src/executor/wall_time/perf/save_artifacts.rs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/executor/wall_time/perf/save_artifacts.rs b/src/executor/wall_time/perf/save_artifacts.rs index e5b1d572..34f47629 100644 --- a/src/executor/wall_time/perf/save_artifacts.rs +++ b/src/executor/wall_time/perf/save_artifacts.rs @@ -124,6 +124,36 @@ fn save_symbols( mappings_by_pid } +fn is_libc_path(path: &Path) -> bool { + let Some(filename) = path.file_name().and_then(|n| n.to_str()) else { + return false; + }; + // Match libc.so.6, libc-2.31.so, etc. but not unrelated libs like libc-client.so + filename.starts_with("libc.so") + || (filename.starts_with("libc-") + && filename.as_bytes().get(5).is_some_and(u8::is_ascii_digit)) +} + +fn warn_missing_libc_debug_info( + loaded_modules_by_path: &HashMap, + debug_info_by_elf_path: &HashMap, +) { + for (path, loaded_module) in loaded_modules_by_path { + if !is_libc_path(path) || loaded_module.module_symbols.is_none() { + continue; + } + if debug_info_by_elf_path.contains_key(path) { + continue; + } + warn!( + "libc debug info not found for {}. Flamegraphs may contain \ + unsymbolicated libc frames. Install debug symbols \ + (e.g., `apt install libc6-dbg`) to fix this.", + path.display() + ); + } +} + /// Compute debug info from symbols and build per-pid debug info mappings. fn save_debug_info( loaded_modules_by_path: &HashMap, @@ -136,6 +166,8 @@ fn save_debug_info( let debug_info_by_elf_path = debug_info_by_path(loaded_modules_by_path); + warn_missing_libc_debug_info(loaded_modules_by_path, &debug_info_by_elf_path); + for path in debug_info_by_elf_path.keys() { get_or_insert_key(path_to_key, path); }