### Complete Output Example Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/output-module.md Demonstrates executing a program with Valgrind, processing the results, and displaying errors and stack traces. Includes example output formatting. ```rust use valgrind::{xml::{Error, Kind, Resources, Stack, Frame}, execute}; let result = execute(vec!["target/debug/test"]); if let Ok(output) = result { if let Some(errors) = output.errors { output::display_errors(&errors); } } // Example output: // Error leaked 5 B in 1 block // Info stack trace (user code at the bottom) // at malloc (vg_replace_malloc.c:446) // at alloc (alloc.rs:100) // at CString::new (c_str.rs:319) // at main (main.rs:9) // Error invalid read of size 4 // Info main stack trace (user code at the bottom) // at my_function (file.rs:42) // Summary Leaked 5 B total (1 other errors) ``` -------------------------------- ### Install Cargo Valgrind from Crates.io Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/README.md Use this command to install the latest official released version of cargo-valgrind from crates.io. ```bash cargo install cargo-valgrind ``` -------------------------------- ### Installing the Custom Panic Handler Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/panic-module.md Demonstrates how to install the custom panic handler at the beginning of the main function in src/main.rs. This ensures that any subsequent panics, including those from Valgrind errors, are caught by the custom logic. ```rust use std::panic; fn main() { // Install the custom panic handler at program start panic::replace_hook(); // ... rest of main // If a MalformedOutput error is encountered and panicked: // The custom hook displays helpful information and exits } ``` -------------------------------- ### Example: Using driver() in main.rs Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/driver-module.md This example shows the typical usage of the `driver()` function within `main.rs`. It handles the successful execution status or prints an error if the Cargo invocation fails. ```rust use std::process; // When user runs: cargo valgrind run --arg value if is_cargo_subcommand() { match driver::driver() { Ok(exit_status) => { process::exit(exit_status.code().unwrap_or(200)); } Err(e) => { eprintln!("Failed to invoke cargo: {}", e); process::exit(1); } } } ``` -------------------------------- ### Example Frame Output Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/valgrind-xml-module.md Illustrates the formatted output of a Frame, showing function name, file, and line number. ```text malloc (vg_replace_malloc.c:446) alloc (alloc.rs:100) _RUNNER Example Values Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/configuration.md Illustrates example values for the CARGO_TARGET__RUNNER environment variable, which is set internally by cargo-valgrind to configure Cargo to use itself as the binary runner for specific target triples. ```text CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER=/path/to/cargo-valgrind ``` ```text CARGO_TARGET_AARCH64_APPLE_DARWIN_RUNNER=/path/to/cargo-valgrind ``` ```text CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_RUNNER=/path/to/cargo-valgrind ``` -------------------------------- ### Install Cargo Valgrind from Git Repository Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/README.md Install the latest development version of cargo-valgrind directly from its git repository. This is useful for using changes not yet published to crates.io. ```bash cargo install --git https://github.com/jfrimmel/cargo-valgrind ``` -------------------------------- ### Execute Rust Binary with Valgrind Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/valgrind-module.md Demonstrates how to execute a Rust binary with specified arguments under Valgrind. It shows how to handle successful execution, Valgrind not being installed, process termination by signal, and other Valgrind execution failures. ```rust use std::ffi::OsString; // Execute a simple binary under Valgrind let command = vec![ OsString::from("target/debug/my_binary"), OsString::from("--arg1"), OsString::from("value1"), ]; match valgrind::execute(command) { Ok(output) => { if let Some(errors) = output.errors { println!("Found {} memory errors", errors.len()); for error in errors { println!("Error: {}", error.kind); } } else { println!("No memory errors detected"); } } Err(valgrind::Error::ValgrindNotInstalled) => { eprintln!("Valgrind is not installed"); } Err(valgrind::Error::ProcessSignal(sig, partial_output)) => { eprintln!("Program terminated by signal {}", sig); if let Some(errors) = partial_output.errors { eprintln!("Errors found before termination: {}", errors.len()); } } Err(e) => { eprintln!("Valgrind execution failed: {}", e); } } ``` -------------------------------- ### Handle ValgrindNotInstalled Error in Rust Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/errors.md This snippet demonstrates how to catch and handle the `ValgrindNotInstalled` error, guiding the user to install Valgrind if it's missing. ```rust match valgrind::execute(command) { Err(valgrind::Error::ValgrindNotInstalled) => { eprintln!("Please install valgrind first:"); eprintln!(" Ubuntu/Debian: sudo apt install valgrind"); eprintln!(" macOS: brew install valgrind"); } Ok(_) => {} Err(e) => eprintln!("Error: {}", e), } ``` -------------------------------- ### Running a Cargo Project with Valgrind Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/README.md This command is used to compile and run a Cargo project with Valgrind. Ensure Valgrind is installed and configured. ```bash $ cargo valgrind run ``` -------------------------------- ### Process Valgrind Execution Output Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/types.md Example of executing a command with Valgrind and handling its output. It checks for errors and prints the number of errors found or a message indicating no errors. ```rust match valgrind::execute(command) { Ok(output) => { match output.errors { Some(errors) => println!("Found {} errors", errors.len()), None => println!("No errors detected") } } Err(e) => eprintln!("Error: {}", e), } ``` -------------------------------- ### Install cargo-valgrind without textwrap Feature Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/configuration.md This command installs the cargo-valgrind binary without the 'textwrap' feature enabled. This results in a smaller binary size by disabling the wrapping of panic messages. ```bash cargo install cargo-valgrind --no-default-features ``` -------------------------------- ### Example Panic Output Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/panic-module.md Illustrates the expected output format when cargo-valgrind panics due to an internal error, specifically showing an XML format mismatch and the Valgrind XML content. ```text Oooops. cargo valgrind unexpectedly crashed. This is a bug! This is an error in this program, which should be fixed. If you can, please submit a bug report at https://github.com/jfrimmel/cargo-valgrind/issues/new/choose To make fixing the error more easy, please provide the information below as well as additional information on which project the error occurred or how to reproduce it. cargo-valgrind version 2.4.1 XML format mismatch between `valgrind` and `cargo valgrind`: missing field `errors` at line 1 column 0 XML output of valgrind: ```xml xml ``` ``` -------------------------------- ### driver Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/driver-module.md Executes Cargo with cargo-valgrind configured as a custom runner for the target platform. This function orchestrates environment variable setup and spawns a Cargo subprocess. ```APIDOC ## driver ### Description Executes Cargo with cargo-valgrind configured as a custom runner for the target platform. This function orchestrates environment variable setup and spawns a Cargo subprocess. ### Method Rust Function ### Parameters None ### Return Type `Result` - On success: `Ok(ExitStatus)` — the exit status of the Cargo subprocess - On error: `Err(io::Error)` — an I/O error if the Cargo process could not be spawned or waited on ### Errors - `io::Error`: The `CARGO` environment variable is not set. - `io::Error`: Cannot determine the host triple. - `io::Error`: Cannot spawn the Cargo subprocess. ### Behavior 1. Reads the `CARGO` environment variable and derives the `rustc` path. 2. Determines the host triple by running `cargo version -v` or `rustc -vV`. 3. Computes the `CARGO_TARGET__RUNNER` environment variable. 4. Executes Cargo with the computed runner environment variable set, passing all original arguments. ### Example ```rust // Typical invocation from main.rs when user runs: cargo valgrind run let exit_status = driver::driver()?; process::exit(exit_status.code().unwrap_or(200)); ``` ``` -------------------------------- ### Display Error Resources Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/valgrind-xml-module.md Example of how to access and display the memory resource details (bytes and blocks) for a given error. This is useful for reporting and analysis. ```rust println!("Leaked {} bytes in {} blocks", error.resources.bytes, error.resources.blocks); ``` -------------------------------- ### Rust Valgrind Error Handling Example Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/valgrind-module.md Demonstrates how to match and handle different variants of the `valgrind::Error` enum after executing a Valgrind command. This is useful for diagnosing specific Valgrind failures. ```Rust match valgrind::execute(vec![OsString::from("binary")]) { Ok(output) => { /* handle success */ } Err(e) => { eprintln!("{}", e); // Prints human-readable error message match e { valgrind::Error::ProcessSignal(sig, partial) => { eprintln!("Signal: {}, partial output: {:?}", sig, partial); } valgrind::Error::MalformedOutput(parse_err, raw_xml) => { eprintln!("Parse error: {}", parse_err); eprintln!("Raw XML: {}", String::from_utf8_lossy(&raw_xml)); } _ => {} } } } ``` -------------------------------- ### Iterate and Display Stack Frames Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/valgrind-xml-module.md Example of iterating through an error's stack trace and printing each stack frame. This helps in pinpointing the exact location of errors in the code. ```rust for stack in error.stack_trace { for frame in stack.frames { println!(" {}", frame); // Uses Frame's Display implementation } } ``` -------------------------------- ### Set VALGRINDFLAGS Environment Variable Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/valgrind-module.md Example of setting the VALGRINDFLAGS environment variable to pass options to Valgrind before running a cargo-valgrind command. ```bash export VALGRINDFLAGS="--tool=memcheck --leak-check=full" cargo-valgrind run ``` -------------------------------- ### Rust Mismatched Free Example (FFI) Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/errors.md Illustrates a 'mismatched free' scenario in Rust involving Foreign Function Interface (FFI) calls. It shows the correct usage of `libc::free` to deallocate memory obtained via `libc::malloc`, emphasizing the need for consistent allocation/deallocation pairs. ```rust extern crate libc; fn main() { // In Rust code wrapping C library let ptr = libc::malloc(100); // C allocation unsafe { libc::free(ptr) }; // Correct: use free, not delete } ``` -------------------------------- ### Handle SocketConnection Error in Rust Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/errors.md This code example shows how to handle `SocketConnection` errors, which indicate issues with TCP socket creation or I/O operations during Valgrind execution. ```rust match valgrind::execute(command) { Err(valgrind::Error::SocketConnection) => { eprintln!("Could not establish communication with valgrind"); eprintln!("This might indicate a system resource issue"); } Ok(_) => {} Err(e) => eprintln!("Error: {}", e), } ``` -------------------------------- ### Example Usage of Kind Enum and is_leak Method Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/types.md Demonstrates how to match on different error kinds and use the `is_leak` method to check for leak types. This is useful for conditional logic based on error categories. ```rust match error.kind { Kind::LeakDefinitelyLost => println!("Definite leak"), Kind::InvalidRead => println!("Invalid memory read"), _ => println!("Other error: {}", error.kind), } if error.kind.is_leak() { println!("Total leaked: {} bytes", error.resources.bytes); } ``` -------------------------------- ### Handling Different Valgrind Error Kinds Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/valgrind-xml-module.md Shows how to process Valgrind errors by matching on their `kind` enum. This example specifically handles 'DefinitelyLost' and 'InvalidRead' errors, printing relevant details like memory usage or error messages. It also demonstrates accessing the first stack trace. ```rust use valgrind::xml::{Error, Kind}; for error in output.errors.unwrap_or_default() { match error.kind { Kind::LeakDefinitelyLost => { println!("Definitely lost: {} bytes", error.resources.bytes); } Kind::InvalidRead => { if let Some(info) = error.main_info { println!("Invalid read: {}", info); } } _ => {} // Handle other kinds if necessary } // Display the first stack trace if let Some(stack) = error.stack_trace.first() { for frame in &stack.frames { println!(" {}", frame); } } } ``` -------------------------------- ### Execute Cargo with Custom Runner Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/driver-module.md This function orchestrates the execution of Cargo with cargo-valgrind configured as a custom runner. It handles environment variable setup, host triple detection, and subprocess execution. Use this when invoking the `cargo valgrind` subcommand. ```rust pub fn driver() -> io::Result ``` ```rust // Typical invocation from main.rs when user runs: cargo valgrind run let exit_status = driver::driver()?; process::exit(exit_status.code().unwrap_or(200)); // This function: // 1. Detects the host triple (e.g., "x86_64-unknown-linux-gnu") // 2. Sets CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER= // 3. Runs: cargo run (or other subcommand) // 4. Cargo compiles and runs the binary using cargo-valgrind as the runner ``` -------------------------------- ### Rust Invalid Free Example (Double Free) Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/errors.md Demonstrates an 'invalid free' error scenario in Rust where a raw pointer obtained from a Box is freed twice. This results in undefined behavior and potential crashes. ```rust fn main() { let ptr = Box::into_raw(Box::new(42)); unsafe { drop(Box::from_raw(ptr)); drop(Box::from_raw(ptr)); // ERROR: double-free } } ``` -------------------------------- ### valgrind::Error Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/types.md Enumeration of all possible error conditions when executing Valgrind. It details various failure modes including Valgrind not being installed, communication issues, process failures, Valgrind-specific errors, stack overflows, process signals, and malformed output. ```APIDOC ## valgrind::Error ### Description Enumeration of all possible error conditions when executing Valgrind. It details various failure modes including Valgrind not being installed, communication issues, process failures, Valgrind-specific errors, stack overflows, process signals, and malformed output. ### Variants - **ValgrindNotInstalled**: None. Triggered when the `valgrind` binary is not found in PATH or is not executable. - **SocketConnection**: None. Triggered when TCP socket creation or communication fails. - **ProcessFailed**: None. Triggered when the Valgrind subprocess cannot be spawned or waited upon. - **ValgrindFailure**: `String` (stderr). Triggered when Valgrind fails to execute (e.g., invalid arguments). - **StackOverflow**: `String` (stderr). Triggered when a stack overflow is detected in the analyzed program. - **ProcessSignal**: `i32` (signal number), `xml::Output` (partial results). Triggered when the program terminates by a signal (e.g., SIGABRT, SIGSEGV). - **MalformedOutput**: `serde_xml_rs::Error` (parse error), `Vec` (raw XML). Triggered when Valgrind output cannot be deserialized. ### Used By - `valgrind::execute()` — returns this type as the error variant. - `main.rs` — matches on this type to determine exit codes and error messages. ### Location `src/valgrind/mod.rs` ``` -------------------------------- ### Project Structure Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/README.md The project is organized into several directories and files, with src/ containing the core logic and valgrind/ handling Valgrind execution and XML parsing. ```tree cargo-valgrind/ ├── src/ │ ├── main.rs # Entry point; CLI handler │ ├── driver.rs # Cargo subcommand integration │ ├── output.rs # Colored error formatting │ ├── panic.rs # Custom panic handler │ └── valgrind/ │ ├── mod.rs # Valgrind execution API │ └── xml/ │ ├── mod.rs # Valgrind XML output structures │ └── tests.rs # XML deserialization tests ├── suppressions/ # Valgrind suppression files ├── Cargo.toml # Package metadata └── README.md # User documentation ``` -------------------------------- ### Valgrind Execution API Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/MANIFEST.md Documentation for the `execute` function and related `Error` types for running Valgrind. ```APIDOC ## `execute()` function ### Description Executes Valgrind with specified configurations and returns the result or an error. ### Method (Not specified, likely a function call within the Rust API) ### Parameters - **(generic parameters)**: (type not specified) - Description of generic parameters. - **(parameters table)**: (1 parameter, fully documented) - Details of the single parameter. ### Return Type (Description of return type and behavior) ### Error Variants (Table of 7 error types with associated data) ### Constants - **STACK_OVERFLOW**: (type not specified) - Description of the stack overflow constant. ### Example (Real-world example with error handling) ``` -------------------------------- ### Execute Command Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/README.md The main entry point for executing a command under Valgrind. It takes an iterator of string slices representing the command and its arguments, and returns a Result containing either the parsed XML output or an error. ```APIDOC ## valgrind::execute ### Description Executes a command under Valgrind and returns parsed output or error. ### Signature ```rust pub fn valgrind::execute(command: I) -> Result where S: AsRef, I: IntoIterator, ``` ### Parameters - `command`: An iterator of string slices representing the command and its arguments. ``` -------------------------------- ### Display Help and Version for Cargo Valgrind Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/configuration.md Use the --help or -h flags to display the help message. Running the command without any arguments also shows the help message. ```bash # Display help message cargo valgrind --help cargo valgrind -h # No arguments also shows help cargo valgrind ``` -------------------------------- ### Valgrind Error Enum Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/README.md Defines the possible errors that can occur during Valgrind execution, including installation issues, process failures, and malformed output. ```rust pub enum valgrind::Error { ValgrindNotInstalled, SocketConnection, ProcessFailed, ValgrindFailure(String), StackOverflow(String), ProcessSignal(i32, xml::Output), MalformedOutput(serde_xml_rs::Error, Vec), } ``` -------------------------------- ### Iterate and Check Error Kinds Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/valgrind-xml-module.md Example of iterating through a collection of errors and checking if each error kind is a leak. This pattern is common when processing Valgrind output. ```rust for error in errors { if error.kind.is_leak() { println!("Leak: {} bytes", error.resources.bytes); } else { println!("Error: {}", error.kind); } } ``` -------------------------------- ### valgrind::execute() Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/INDEX.md Executes a binary under Valgrind's supervision to detect memory errors and other issues. ```APIDOC ## valgrind::execute() ### Description Run binary under Valgrind. ### Module valgrind ``` -------------------------------- ### Rust InvalidRead Example Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/errors.md Demonstrates an InvalidRead error by attempting to read out of bounds from a vector's memory. This occurs when accessing memory beyond the allocated bounds. ```rust let vec = vec![1, 2, 3]; unsafe { let ptr = vec.as_ptr(); let _ = *ptr.add(10); // ERROR: reading out of bounds } ``` -------------------------------- ### Main Function - Initialize Panic Hook Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/panic-module.md Demonstrates the call location for `panic::replace_hook()` within the `main` function, indicating where the custom panic handler is initialized. ```rust fn main() { panic::replace_hook(); // ... rest of main } ``` -------------------------------- ### Handle ValgrindFailure Error in Rust Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/errors.md This example demonstrates catching `ValgrindFailure`, which signifies Valgrind exiting with a non-zero status, and displays Valgrind's stderr output for debugging. ```rust match valgrind::execute(command) { Err(valgrind::Error::ValgrindFailure(stderr)) => { eprintln!("Valgrind failed to execute properly:"); eprintln!("{}", stderr); eprintln!("Check that valgrind is properly installed"); } Ok(_) => {} Err(e) => eprintln!("Error: {}", e), } ``` -------------------------------- ### Execute Command with Valgrind Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/README.md Use this function to run a command under Valgrind. It returns parsed output or an error, supporting generic command inputs. ```rust pub fn valgrind::execute(command: I) -> Result where S: AsRef, I: IntoIterator, ``` -------------------------------- ### Output Formatting Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/README.md Functions for displaying Valgrind output. ```APIDOC ## output::display_errors ### Description Displays a list of Valgrind errors. ### Signature ```rust pub fn output::display_errors(errors: &[valgrind::xml::Error]) ``` ### Parameters - `errors`: A slice of `valgrind::xml::Error` structs to display. ``` ```APIDOC ## output::display_stack_overflow ### Description Displays information related to a stack overflow. ### Signature ```rust pub fn output::display_stack_overflow(output: &str) ``` ### Parameters - `output`: A string slice containing the raw output related to the stack overflow. ``` -------------------------------- ### Rust InvalidWrite Example with Overlapping Memory Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/errors.md Illustrates an InvalidWrite error scenario using `libc::memcpy` with overlapping source and destination memory regions. This can lead to data corruption. ```rust let mut buffer = [1, 2, 3, 4, 5]; unsafe { // Overlapping copy: destination overlaps source libc::memcpy( buffer.as_mut_ptr() as *mut _, buffer.as_ptr().add(1) as *const _, 3, ); } ``` -------------------------------- ### Pattern Matching on valgrind::Error Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/errors.md Use this snippet to handle different types of errors returned by `valgrind::execute`. It demonstrates how to specifically catch `ValgrindNotInstalled` and `ProcessSignal` errors, as well as a general catch-all for other Valgrind errors. ```rust match valgrind::execute(command) { Ok(output) => { println!("Success!"); } Err(valgrind::Error::ValgrindNotInstalled) => { eprintln!("Install valgrind first"); process::exit(1); } Err(valgrind::Error::ProcessSignal(sig, partial_output)) => { eprintln!("Program crashed with signal {}", sig); if let Some(errors) = partial_output.errors { eprintln!("Errors before crash: {}", errors.len()); } process::exit(128 + sig); } Err(e) => { eprintln!("Error: {}", e); process::exit(1); } } ``` -------------------------------- ### execute Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/valgrind-module.md Executes a specified command within the Valgrind environment and captures its structured output. It returns the parsed Valgrind analysis results or an error if the execution fails. ```APIDOC ## execute ### Description Executes a command inside Valgrind and collects the output. This function handles the setup of Valgrind, process execution, and parsing of the XML output. ### Signature ```rust pub fn execute(command: I) -> Result where S: AsRef, I: IntoIterator, ``` ### Parameters #### Path Parameters - **command** (I: IntoIterator where S: AsRef) - Required - The command and arguments to execute under Valgrind. Accepts any iterable of OS strings. ### Return Type Returns `Result`. - On success, contains a `xml::Output` struct with the Valgrind analysis results. - On failure, returns a `valgrind::Error` variant describing the issue. ### Throws - **`Error::ValgrindNotInstalled`**: The `valgrind` binary is not found in PATH or not executable. - **`Error::SocketConnection`**: TCP socket creation or connection failed. - **`Error::ProcessFailed`**: Subprocess failed to start or wait. - **`Error::ValgrindFailure`**: Valgrind execution failed with a non-success exit status and no signal termination. - **`Error::StackOverflow`**: Stack overflow detected in the program under test. - **`Error::ProcessSignal`**: Program terminated with a signal (e.g., SIGABRT). - **`Error::MalformedOutput`**: Valgrind XML output could not be parsed or was unexpected. ### Behavior 1. Opens a TCP socket on localhost for XML output reception. 2. Launches Valgrind with XML output enabled (`--xml=yes`) and directs it to the socket. 3. Applies memory leak suppressions from a temporary file. 4. Respects `VALGRINDFLAGS` environment variable if set. 5. Spawns a background thread to parse incoming XML data. 6. Waits for both the Valgrind process and the XML parsing thread to complete. 7. Filters out zero-byte/zero-block leaks from the output. 8. Handles success, signal termination, and Valgrind execution failures. ### Example Usage ```rust use std::ffi::OsString; // Execute a simple binary under Valgrind let command = vec![ OsString::from("target/debug/my_binary"), OsString::from("--arg1"), OsString::from("value1"), ]; match valgrind::execute(command) { Ok(output) => { if let Some(errors) = output.errors { println!("Found {} memory errors", errors.len()); for error in errors { println!("Error: {}", error.kind); } } else { println!("No memory errors detected"); } } Err(valgrind::Error::ValgrindNotInstalled) => { eprintln!("Valgrind is not installed"); } Err(valgrind::Error::ProcessSignal(sig, partial_output)) => { eprintln!("Program terminated by signal {}", sig); if let Some(errors) = partial_output.errors { eprintln!("Errors found before termination: {}", errors.len()); } } Err(e) => { eprintln!("Valgrind execution failed: {}", e); } } ``` ``` -------------------------------- ### File Organization Structure Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/INDEX.md Shows the directory structure of the cargo-valgrind project, detailing the location of API reference files and other documentation. ```text /api-reference/ ├── INDEX.md (this file) ├── valgrind-module.md ├── valgrind-xml-module.md ├── output-module.md ├── driver-module.md └── panic-module.md / ├── README.md (project overview) ├── types.md (all type definitions) ├── errors.md (error reference) └── configuration.md (configuration options) ``` -------------------------------- ### Invoke Cargo Valgrind with Subcommands Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/configuration.md Use this to run Cargo subcommands like 'run', 'test', or 'bench' under Valgrind. Arguments can be passed to the Cargo subcommand using '--'. ```bash cargo valgrind [ARGS...] ``` ```bash # Run the main binary cargo valgrind run # Run with arguments passed to the binary cargo valgrind run -- --my-arg value # Run tests cargo valgrind test # Run specific test cargo valgrind test my_test_name # Run benchmarks cargo valgrind bench # Run with release profile cargo valgrind run --release ``` -------------------------------- ### Rust Memory Leak Example (Indirectly Lost) Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/errors.md Shows an 'indirectly lost' memory leak where a Box containing a Vec of Boxes is never dropped. The inner String is indirectly lost because the outer Box holding the Vec is leaked. ```rust fn main() { // If my_vector is leaked, all its heap-allocated elements are indirectly lost let my_vector = Box::new(vec![Box::new(String::from("test"))]); // Box is never dropped; the inner String is indirectly lost } ``` -------------------------------- ### driver::driver() Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/INDEX.md Integrates cargo-valgrind as a Cargo subcommand. ```APIDOC ## driver::driver() ### Description Cargo subcommand integration. ### Module driver ``` -------------------------------- ### Module Dependency Graph Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/INDEX.md Illustrates the dependency relationships between different modules and functions within the cargo-valgrind project. ```text main.rs ├── panic.rs (replace_hook) ├── driver.rs (driver) ├── valgrind::execute() │ ├── valgrind::xml deserialization │ └── Output filtering └── output functions ├── display_errors() └── display_stack_overflow() ``` -------------------------------- ### Cargo Valgrind Command Line Usage Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/README.md This is the general command-line syntax for using cargo-valgrind. It accepts a subcommand and optional arguments. ```bash cargo valgrind [ARGS...] ``` -------------------------------- ### Rust Memory Leak Example (Still Reachable) Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/errors.md Illustrates a 'still reachable' memory leak using a lazy_static HashMap. This pattern is often acceptable for long-lived programs or intentional global allocations, but can indicate design issues in short-lived processes. ```rust use std::collections::HashMap; use lazy_static::lazy_static; // Global allocation that's never freed (often acceptable) lazy_static! { static ref CACHE: HashMap = HashMap::new(); } ``` -------------------------------- ### Rust Memory Leak Example (Definitely Lost) Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/errors.md Demonstrates a memory leak scenario in Rust where a CString is converted to a raw pointer and the memory is never freed. This typically occurs when manual memory management is used without proper deallocation. ```rust use std::ffi::CString; use std::os::raw::c_char; extern "C" { fn puts(s: *const c_char) -> i32; } fn main() { // Memory leak! let string = CString::new("test").unwrap(); let ptr = string.into_raw(); unsafe { puts(ptr) }; // Memory is never freed; ptr is lost } ``` -------------------------------- ### Valgrind Error Enum Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/types.md This enum represents all possible error conditions that can occur when executing Valgrind. It includes variants for Valgrind not being installed, connection issues, process failures, Valgrind-specific failures, stack overflows, process termination by signals, and malformed output. ```rust pub enum Error { ValgrindNotInstalled, SocketConnection, ProcessFailed, ValgrindFailure(String), StackOverflow(String), ProcessSignal(i32, xml::Output), MalformedOutput(serde_xml_rs::Error, Vec), } ``` -------------------------------- ### Processing valgrind::xml::Kind for Error Types Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/errors.md This snippet shows how to iterate through Valgrind errors and match on the `Kind` enum to identify specific error types like definite leaks or memory access violations. It provides examples for handling critical and warning-level issues. ```rust if let Some(errors) = output.errors { for error in errors { match error.kind { Kind::LeakDefinitelyLost => { println!("FATAL: Definite leak of {} bytes", error.resources.bytes); } Kind::InvalidRead | Kind::InvalidWrite => { println!("FATAL: Memory access violation"); } Kind::LeakStillReachable => { println!("WARNING: Possibly intentional leak"); } _ => { println!("Found error: {}", error.kind); } } } } ``` -------------------------------- ### Run Cargo Valgrind with Manual Suppressions Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/configuration.md This command demonstrates how to run cargo-valgrind while specifying a custom Valgrind suppression file. This is useful for suppressing additional errors not covered by the built-in rules. ```bash VALGRINDFLAGS="--suppressions=/path/to/my.supp" cargo valgrind run ``` -------------------------------- ### Combine Multiple Valgrind Options Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/configuration.md Combines several Valgrind options for a comprehensive analysis, including full leak checking, origin tracking, and increased stack size. It also passes the --nocapture flag to the test runner. ```bash VALGRINDFLAGS="--leak-check=full --track-origins=yes --main-stacksize=16777216" \ cargo valgrind test -- --nocapture ``` -------------------------------- ### Enable Deep Stack Tracing Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/configuration.md Increases the number of stack frames Valgrind displays to 50, which is useful for analyzing memory issues in deeply nested code. Use this when the default stack trace depth is insufficient. ```bash VALGRINDFLAGS="--num-callers=50" cargo valgrind test ``` -------------------------------- ### Handle Cannot Determine Host Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/driver-module.md This snippet demonstrates error handling when the host system cannot be determined from Cargo or Rustc version information. It returns a specific io::Error. ```rust .ok_or_else(|| io::Error::other("could not determine host"))? ``` -------------------------------- ### valgrind::xml::Output Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/types.md Represents the complete parsed output from a Valgrind analysis run. It contains an optional list of detected errors. ```APIDOC ## valgrind::xml::Output ### Description Represents the complete parsed output from a Valgrind analysis run. It contains an optional list of detected errors. ### Fields #### `errors` - **Type**: `Option>` - **Description**: List of detected errors, or `None` if no errors found. ### Usage This type is returned by `valgrind::execute()` on success and is inspected by `main.rs` and `output::display_errors()`. ### Example ```rust match valgrind::execute(command) { Ok(output) => { match output.errors { Some(errors) => println!("Found {} errors", errors.len()), None => println!("No errors detected"), } } Err(e) => eprintln!("Error: {}", e), } ``` ``` -------------------------------- ### Handle Malformed Valgrind Output Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/errors.md This code demonstrates how to handle errors where Valgrind's XML output cannot be parsed or does not conform to the expected schema. It prints the parsing error and the raw XML for debugging. ```rust match valgrind::execute(command) { Err(valgrind::Error::MalformedOutput(parse_err, xml_bytes)) => { eprintln!("Failed to parse valgrind output"); eprintln!("Parse error: {}", parse_err); eprintln!("Raw XML: {}", String::from_utf8_lossy(&xml_bytes)); eprintln!("This might indicate an incompatible valgrind version"); } Ok(_) => {} // Program executed successfully Err(e) => eprintln!("Error: {}", e), } ``` -------------------------------- ### Rust: Display Call Stack Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/output-module.md Formats and outputs a call stack with a given message label. It iterates through each frame in the stack and formats it for display. ```rust fn display_stack_trace(msg: &str, stack: &valgrind::xml::Stack) ``` -------------------------------- ### Valgrind XML Output Structures Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/MANIFEST.md Defines the structures for parsing Valgrind XML output, including error details and resource information. ```APIDOC ## Valgrind XML Output Structures ### Description Provides structures for deserializing Valgrind XML output, detailing detected errors, resource usage, and call stacks. ### Root Structure - **Output**: The root structure for Valgrind XML output. ### Error Structure - **Error**: Represents a detected error record. - **Kind**: Enum with 15 error classifications (Leak variants, Incorrect free variants, Memory access violations, Other error types). - **`is_leak()`**: Method to check if an error is a leak. ### Resource Structure - **Resources**: Contains memory usage information. ### Stack Structure - **Stack**: Represents a call stack. - **Frame**: Represents a stack frame. - **Fields**: 6 documented fields (e.g., filename, lineno, function, inline, file, line). - **Display Format**: Examples of how frames are displayed. ### Internal Types - **ProtocolVersion**: Enum representing protocol versions (4, 5, 6). - **Tool**: Enum representing the tool used (memcheck only). ### Helper Functions - **`deserialize_hex()`**: Helper function for deserializing hexadecimal values. ### Example (Complete error processing example) ``` -------------------------------- ### Iterating Through Valgrind Errors Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/valgrind-xml-module.md Demonstrates how to iterate through the detected errors in a Valgrind output structure and print details about each error, such as its kind and resource usage. Handles cases where no errors are found. ```rust use valgrind::xml::Output; match output.errors { Some(errors) => { for error in errors { println!("Found error: {}", error.kind); println!("Location: {} bytes, {} blocks", error.resources.bytes, error.resources.blocks); } } None => { println!("No errors detected"); } } ``` -------------------------------- ### Output Structures Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/README.md Defines the structures used to represent the parsed XML output from Valgrind. ```APIDOC ## xml::Output ### Description Represents the overall output from Valgrind, containing a list of errors. ### Fields - `errors`: An optional vector of `xml::Error` structs detailing the detected issues. ``` ```APIDOC ## xml::Error ### Description Represents a single error detected by Valgrind. ### Fields - `kind`: The type of error detected (`xml::Kind`). - `resources`: Information about the resources affected by the error (`xml::Resources`). - `main_info`: Optional main descriptive information about the error. - `auxiliary_info`: A vector of strings containing auxiliary information. - `stack_trace`: A vector of `xml::Stack` structs representing the call stack at the point of the error. ``` ```APIDOC ## xml::Kind ### Description Enumerates the different kinds of errors Valgrind can detect. ### Variants - `LeakDefinitelyLost` - `LeakStillReachable` - `LeakIndirectlyLost` - `LeakPossiblyLost` - `InvalidFree` - `MismatchedFree` - `InvalidRead` - `InvalidWrite` - `InvalidJump` - `Overlap` - `InvalidMemPool` - `UninitCondition` - `UninitValue` - `SyscallParam` - `ClientCheck` ``` ```APIDOC ## xml::Resources ### Description Contains information about the resources involved in a Valgrind error. ### Fields - `bytes`: The number of bytes affected. - `blocks`: The number of memory blocks affected. ``` ```APIDOC ## xml::Stack ### Description Represents a stack trace associated with a Valgrind error. ### Fields - `frames`: A vector of `xml::Frame` structs representing the call stack frames. ``` ```APIDOC ## xml::Frame ### Description Represents a single frame in a call stack. ### Fields - `instruction_pointer`: The instruction pointer address. - `object`: Optional name of the object file. - `directory`: Optional directory of the source file. - `function`: Optional name of the function. - `file`: Optional name of the source file. - `line`: Optional line number in the source file. ``` -------------------------------- ### Console Output Formatting Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/MANIFEST.md Functions for formatting and displaying Valgrind errors and stack overflows to the console. ```APIDOC ## Console Output Formatting ### Public Functions #### `display_errors()` ##### Description Formats and displays detected errors to the console. ##### Parameters (Table of parameters for `display_errors()`) ##### Return Type (Description of return type and behavior) ##### Output Format Details on the console output format, including color scheme and alignment. ##### Example (Colored output example) #### `display_stack_overflow()` ##### Description Formats and displays stack overflow information to the console. ##### Parameters (Table of parameters for `display_stack_overflow()`) ##### Behavior Explanation of the behavior, including output format with indentation. ##### Example (Example usage of `display_stack_overflow()`) ### Formatting Details - **Color Scheme**: Red, cyan, bold. - **Alignment**: 12-character column. - **Byte Size Formatting**: Uses the `bytesize` crate. ### Example (Complete output example with all error types) ``` -------------------------------- ### Analyze Release Builds Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/configuration.md Runs cargo-valgrind on a release build of the project. This is useful for analyzing memory behavior in optimized code, which might differ from debug builds. ```bash cargo valgrind run --release ``` -------------------------------- ### Panic Version Information Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/panic-module.md Displays the version of cargo-valgrind at the time of the panic. This helps in identifying the specific version that might be affected by a bug. ```text cargo-valgrind version X.Y.Z ``` -------------------------------- ### Valgrind Output Structure Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/api-reference/valgrind-xml-module.md Defines the structure for the complete Valgrind XML output, including protocol version, tool information, and a list of detected errors. Supports deserialization via serde-xml-rs. ```rust pub struct Output { protocol_version: ProtocolVersion, tool: Tool, pub errors: Option>, } ``` -------------------------------- ### Valgrind XML Output Structures Source: https://github.com/jfrimmel/cargo-valgrind/blob/master/_autodocs/README.md Defines the data structures for parsing Valgrind's XML output, including error details, kinds, resources, and stack frames. Supports Valgrind XML formats 4, 5, and 6. ```rust struct Output { // ... root structure ... } struct Error { // ... single detected error ... } enum Kind { // ... error classification ... } struct Resources { // ... memory usage info ... } struct Stack { // ... call stack ... } struct Frame { // ... stack frame ... } ```