From 5a07c0a055290fe95836a3a925a739105cbf940f Mon Sep 17 00:00:00 2001 From: Luc Varoqui Date: Thu, 1 Oct 2026 16:50:27 +0200 Subject: [PATCH 1/2] feat(instrument-hooks): declare benchmarks run in another process Add set_executed_benchmark_for_pid, which passes an explicit pid to instrument_hooks_set_executed_benchmark instead of the calling process' own. set_executed_benchmark keeps its behavior and delegates to it. Bump instrument-hooks, whose valgrind instrument now writes a "Benchmark pid: " desc line in the dump part when that pid is not the calling process'. This also brings thread-safe C API exports and the callgrind_toggle_collect helper. Refs COD-3722 Co-Authored-By: Claude Opus 5.5 --- .../instrument-hooks-bindings/instrument-hooks | 2 +- crates/instrument-hooks-bindings/src/lib.rs | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/crates/instrument-hooks-bindings/instrument-hooks b/crates/instrument-hooks-bindings/instrument-hooks index b9ddb5bc6..11c29ac43 160000 --- a/crates/instrument-hooks-bindings/instrument-hooks +++ b/crates/instrument-hooks-bindings/instrument-hooks @@ -1 +1 @@ -Subproject commit b9ddb5bc654b2e6fa13eb18efcd3a45e7ecda0bb +Subproject commit 11c29ac432cc33d651c7e2bf76651f4312329095 diff --git a/crates/instrument-hooks-bindings/src/lib.rs b/crates/instrument-hooks-bindings/src/lib.rs index 8ea620cb8..09a031dd7 100644 --- a/crates/instrument-hooks-bindings/src/lib.rs +++ b/crates/instrument-hooks-bindings/src/lib.rs @@ -58,10 +58,15 @@ mod linux_impl { #[inline(always)] pub fn set_executed_benchmark(&self, uri: &str) -> Result<(), u8> { - let pid = std::process::id() as i32; + self.set_executed_benchmark_for_pid(std::process::id(), uri) + } + + /// Declares a benchmark that ran in the process `pid` rather than in this one. + #[inline(always)] + pub fn set_executed_benchmark_for_pid(&self, pid: u32, uri: &str) -> Result<(), u8> { let c_uri = CString::new(uri).map_err(|_| 1u8)?; let result = unsafe { - ffi::instrument_hooks_set_executed_benchmark(self.0, pid, c_uri.as_ptr()) + ffi::instrument_hooks_set_executed_benchmark(self.0, pid as i32, c_uri.as_ptr()) }; if result == 0 { Ok(()) } else { Err(result) } } @@ -184,6 +189,10 @@ mod other_impl { Ok(()) } + pub fn set_executed_benchmark_for_pid(&self, _pid: u32, _uri: &str) -> Result<(), u8> { + Ok(()) + } + pub fn set_integration(&self, _name: &str, _version: &str) -> Result<(), u8> { Ok(()) } @@ -213,6 +222,11 @@ mod tests { let hooks = InstrumentHooks::instance("test_integration", "1.0.0"); assert!(!hooks.is_instrumented() || hooks.start_benchmark().is_ok()); assert!(hooks.set_executed_benchmark("test_uri").is_ok()); + assert!( + hooks + .set_executed_benchmark_for_pid(std::process::id() + 1, "test_uri") + .is_ok() + ); assert!(hooks.set_integration("test_integration", "1.0.0").is_ok()); let start = InstrumentHooks::current_timestamp(); let end = start + 1_000_000; // Simulate 1ms later From 485598a32671af0f1ad5cc08b686ab9d5a4681ed Mon Sep 17 00:00:00 2001 From: Luc Varoqui Date: Thu, 1 Oct 2026 16:50:56 +0200 Subject: [PATCH 2/2] feat(exec-harness): declare the benchmarked command's pid exec-harness measures a command from its own process, so the dumped part also holds the harness's cost of spawning the command and waiting for it, a fixed overhead added to every benchmark. Spawn the command and pass its pid to set_executed_benchmark_for_pid, so the profile states which process ran the benchmark and the harness's own cost can be told apart. Under valgrind this needs a valgrind build supporting CALLGRIND_REGISTER_DESC; older builds ignore it. Closes COD-3722 Co-Authored-By: Claude Opus 5.5 --- crates/exec-harness/src/analysis/mod.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/crates/exec-harness/src/analysis/mod.rs b/crates/exec-harness/src/analysis/mod.rs index feed1ab21..9d12738ee 100644 --- a/crates/exec-harness/src/analysis/mod.rs +++ b/crates/exec-harness/src/analysis/mod.rs @@ -25,15 +25,20 @@ pub fn perform(commands: Vec, mode: MeasurementMode) -> Result } hooks.start_benchmark().unwrap(); - let status = cmd.status(); + let result = cmd.spawn().and_then(|mut child| { + let pid = child.id(); + child.wait().map(|status| (pid, status)) + }); hooks.stop_benchmark().unwrap(); - let status = status.context("Failed to execute command")?; + let (pid, status) = result.context("Failed to execute command")?; if !status.success() { bail!("Command exited with non-zero status: {status}"); } - hooks.set_executed_benchmark(&name_and_uri.uri).unwrap(); + hooks + .set_executed_benchmark_for_pid(pid, &name_and_uri.uri) + .unwrap(); } Ok(())