From 274591164b8db1d1eb0dcca32a8c31cf2b5db076 Mon Sep 17 00:00:00 2001 From: not-matthias Date: Fri, 6 Nov 2026 14:50:44 +0100 Subject: [PATCH 1/2] fix(valgrind): stop excluding the node executable from callgrind --- .../valgrind/helpers/ignored_objects_path.rs | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/src/executor/valgrind/helpers/ignored_objects_path.rs b/src/executor/valgrind/helpers/ignored_objects_path.rs index df2d44715..f6a63a565 100644 --- a/src/executor/valgrind/helpers/ignored_objects_path.rs +++ b/src/executor/valgrind/helpers/ignored_objects_path.rs @@ -25,28 +25,6 @@ fn get_python_objects() -> Vec { vec![so_output] } -fn get_node_objects() -> Vec { - let output = Command::new("node") - .arg("-e") - .arg("console.log(process.execPath);") - .output(); - - if output.is_err() { - debug!("Failed to get node shared objects: {:?}", output.err()); - return vec![]; - } - let output = output.unwrap(); - if !output.status.success() { - debug!( - "Failed to get node shared objects: {}", - String::from_utf8_lossy(&output.stderr) - ); - return vec![]; - } - let so_output = String::from_utf8_lossy(&output.stdout).trim().to_string(); - vec![so_output] -} - fn normalize_object_paths(objects_path_to_ignore: &mut [String]) { for path in objects_path_to_ignore.iter_mut() { let cpath = PathBuf::from(&path).canonicalize(); @@ -61,7 +39,6 @@ fn normalize_object_paths(objects_path_to_ignore: &mut [String]) { pub fn get_objects_path_to_ignore() -> Vec { let mut objects_path_to_ignore = vec![]; objects_path_to_ignore.extend(get_python_objects()); - objects_path_to_ignore.extend(get_node_objects()); debug!("objects_path_to_ignore before normalization: {objects_path_to_ignore:?}"); normalize_object_paths(&mut objects_path_to_ignore); debug!("objects_path_to_ignore after normalization: {objects_path_to_ignore:?}"); From ae6049f88828e50eadf35c0818cbcf6ee390f5c8 Mon Sep 17 00:00:00 2001 From: not-matthias Date: Mon, 9 Nov 2026 15:18:56 +0100 Subject: [PATCH 2/2] feat(valgrind): separate callgrind contexts by whole call stack Pass --separate-callers=all --pop-on-jump to callgrind. With the node executable instrumented, V8 builtins sit between most pairs of JS functions; as single nodes they join every JS caller to every JS callee and form false cycles. Whole-stack contexts keep the chains apart, and --pop-on-jump keeps tail-jump chains (bytecode handler dispatch) from nesting. Requires a valgrind-codspeed release with --separate-callers=all (CodSpeedHQ/valgrind-codspeed#63). --- src/executor/valgrind/measure.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/executor/valgrind/measure.rs b/src/executor/valgrind/measure.rs index 545c796cb..9e72952fb 100644 --- a/src/executor/valgrind/measure.rs +++ b/src/executor/valgrind/measure.rs @@ -53,6 +53,12 @@ fn get_valgrind_args(tool: &SimulationTool, config: &ExecutorConfig) -> Vec { args.push("--tool=tracegrind".to_string());