cargo-valgrind

repository·master·Indexed 41 days ago

https://github.com/jfrimmel/cargo-valgrind

A cargo subcommand for running Valgrind on Rust crate executables. It simplifies memory leak detection by automatically applying Rust standard library suppressions and providing a pass/fail status based on Valgrind's output. Version 2.4.1 supports standard cargo patterns like `cargo valgrind run` and `cargo valgrind test`, and allows custom configuration via the `VALGRINDFLAGS` environment variable.

Tokens
3.3K
Snippets
15
Records
19
Agent score
51%

What's inside cargo-valgrind

  1. What are the Rust Standard Library suppressions?

    master
    Valgrind often reports memory leaks in the Rust standard library (std) that are actually small, permanent, non-growing allocations. These are considered non-actionable by the Rust team. This repository provides a curated list of Valgrind suppressions for the Rust std library that are applied automatically to prevent these non-actionable reports from appearing in your Valgrind output.
  2. Command syntax for cargo-valgrind

    master

    In version 2.x, cargo-valgrind follows the standard cargo subcommand pattern. You must provide a cargo command after valgrind.

    Supported pattern: cargo valgrind <command>

    Where <command> can be any standard cargo subcommand (e.g., run, test).

    Note for 1.x users: The syntax has changed. In version 1.x, cargo valgrind replaced commands like cargo run. In current versions, it acts as a wrapper for those commands.

  3. Install cargo-valgrind

    master

    Requirements

    • valgrind must be installed and available in your PATH.
    • cargo must be installed and available in your PATH.

    Installation Methods

    Install the latest official version from crates.io:

    cargo install cargo-valgrind

    To install the latest development version from the git repository:

    cargo install --git https://github.com/jfrimmel/cargo-valgrind cargo-valgrind

    Using Pre-built Binaries

    1. Download the artifact for your platform from the GitHub releases page.
    2. Extract the binary into your .cargo directory (typically $HOME/.cargo).
    3. Ensure the directory is in your cargo subcommand search path.
    $ cargo install cargo-valgrind
  4. Use cargo-valgrind to detect memory leaks

    master

    The cargo-valgrind subcommand extends cargo by running valgrind on any crate executable. It automatically applies suppressions for known false positives in the Rust standard library and uses the Valgrind output to mark the binary execution as pass/fail.

    This tool is particularly useful for FFI-related code where you need to verify that memory usage across FFI boundaries is correct.

    Note on std::process::exit(): Using std::process::exit() prevents normal destructors (Drop implementations) from running, which will cause cargo-valgrind to report memory leaks. To avoid this, either explicitly drop variables before exiting or return a Result from main to allow graceful resource releasing.

    $ cargo valgrind run
  5. How to generate a new Valgrind suppression

    master

    If a new, legitimate leak is identified in the Rust standard library, you can generate a suppression file by creating a minimal reproducer and running Valgrind with the --gen-suppressions=yes flag.

    1. Create a minimal cargo project (e.g., cargo new --lib reproducer).
    2. Run the project's tests to identify the executable path.
    3. Execute Valgrind on the resulting binary using --leak-check=full and --gen-suppressions=yes.
    4. Trim the generated output as necessary for use in the suppressions directory.
    $ cargo new --lib reproducer
    $ cd reproducer
    $ cargo test --lib  # note down the path executed
    $ valgrind --leak-check=full --gen-suppressions=yes target/debug/reproducer-$HASH
  6. Configure Valgrind options via VALGRINDFLAGS

    master

    You can pass custom flags to the underlying Valgrind process by setting the VALGRINDFLAGS environment variable. This variable should contain a space-delimited list of valid Valgrind options (e.g., to use a different subtool).

    # Example: setting flags via environment variable
    export VALGRINDFLAGS="--tool=memcheck --leak-check=full"
    cargo valgrind run
  7. Use cargo-valgrind as a direct runner

    master

    If you are not using it as a cargo subcommand, cargo-valgrind can act as a direct wrapper for any command. In this mode, the first argument after the command itself is treated as the command to execute. This is useful when cargo-valgrind is being invoked by another tool (like a cargo runner).

    #!/usr/bin/env cargo-valgrind
    ./my_binary --arg1
  8. Use cargo-valgrind as a cargo subcommand

    master

    As a cargo subcommand, cargo-valgrind integrates directly with your existing Cargo workflow. You can run any standard cargo command (like run or test) through Valgrind by appending valgrind to the command. This allows you to compile and execute your binary under Valgrind's memory analysis in a single step.

    Common usage patterns:

    • To run your binary: cargo valgrind run
    • To run your tests: cargo valgrind test
    cargo valgrind run
    cargo valgrind test
  9. Configure Valgrind via `VALGRINDFLAGS`

    master

    You can pass additional arguments to the underlying Valgrind process by setting the VALGRINDFLAGS environment variable. The execute function will split this variable by spaces and append the resulting arguments to the Valgrind command.

    Example:

    # Pass specific Valgrind flags via environment variable
    export VALGRINDFLAGS="--leak-check=full --track-origins=yes"
    cargo run
  10. Display Valgrind errors with `display_errors`

    master

    The display_errors function takes a slice of valgrind::xml::Error objects and prints a human-readable, colorized summary of memory leaks and other errors to stderr.

    It performs the following:

    • Iterates through errors, distinguishing between memory leaks and generic errors.
    • For leaks, it displays the amount of memory leaked and the number of blocks involved.
    • For generic errors, it displays the error information and associated stack traces.
    • Prints a final summary showing the total bytes leaked and the count of non-leak errors.
    pub fn display_errors(errors: &[valgrind::xml::Error])
  11. Display stack overflow messages with `display_stack_overflow`

    master

    The display_stack_overflow function is used to format and print a stack overflow error message to stderr. It takes a raw string output (presumably from Valgrind) and prints a structured message indicating that the program likely overflowed its stack, followed by the provided Valgrind output lines.

    pub fn display_stack_overflow(output: &str)
  12. Parse Valgrind Memcheck XML output

    master

    The Output struct is the primary entry point for deserializing Valgrind XML output. It is designed specifically for the memcheck tool and supports Valgrind XML protocol versions 4, 5, and 6.

    When parsing, the Output struct will contain an optional vector of Error objects representing the issues found during the Valgrind run.

    // Example of the expected structure for deserialization
    let output: Output = serde_json::from_str(xml_content)?;