valgrind

How to get valgrind to print final tool stats for rustc


Perhaps someone knows why Valgrind tools fail to print final stats when applied to rustc ?

E.g. lackey works fine with C programs:

$ valgrind -q --tool=lackey --basic-counts=yes whoami
yugr
==3668989== Counted 0 calls to main()
==3668989==
==3668989== Jccs:
==3668989==   total:         166,636
==3668989==   taken:         61,832 (37%)
...

but fails to call its finalizers for Rust:

$ valgrind --tool=lackey --basic-counts=yes rustc --version
rustc 1.87.0 (17067e9ac 2025-05-09)
# Nothing printed here

I tried both stable (valgrind-3.16.1) and trunk (e10b7fff) valgrinds.

I also tried completely replacing main in compiler/rustc_driver_impl/src/lib.rs with

pub fn main() {
    safe_println!("Hello");
}

(suspecting that process::exit in original main was causing the problem) but still couldn't get final stats to print...

Please note that this question is specifically about rustc (other Rust programs print Valgrind stats as expected).

EDIT: Adding --trace-children=yes fixes the problem but I still do not understand the underlying reason.


Solution

  • You guest executable ($CARGO_HOME/bin/rustc) calls the real compiler ($RUSTUP_HOME/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc) internally via fork (or clone) and exec.

    Two things are possible

    1. You have not specified any options (or --trace-children=no). In this case the fork does its usual thing. At that point there are two Valgrind processes running each one with the guest running in it. Then the child valgrind/guest calls exec and the executed binary replaces the valgrind/guest child process. This is just a regular executable not running under Valgrind.

    2. You have specified --trace-children=yes, The same thing happens for the fork but when the exec happens Valgrind will exec Valgrind with the required options and executable.

    So without --trace-children=yes the $RUSTUP_HOME/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc was not executed under Valgrind, whereas when you added --trace-children=yes Valgrind exec'ed valgrind $RUSTUP_HOME/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc`.