Expand description
§Summary
crabgrind is a small library that enables Rust programs to tap into
Valgrind’s tools and environment.
It exposes full set of Valgrind’s client requests in Rust, manages the structure, type conversions and enforces static typing where possible.
§Usage
Minimum Supported Rust Version: 1.64
First, add crabgrind to Cargo.toml
[dependencies]
crabgrind = "0.2"Note: This crate is
no_stdand dependency free
§Build Configuration
We need to build against local Valgrind installation to read C macro
definition, constants, and supported requests.
The build script (build.rs) attempts to locate headers in this order:
- Environment Variable: If
VALGRIND_INCLUDEis set, it is used as the include path. - pkg-config: The system is queried via
pkg-config. - Standard Paths: Using standard include paths.
If headers cannot be located, the crate compiles using dummy headers; any
request will panic! at runtime.
§Example
Use some of the Client Requests:
use crabgrind::valgrind::{running_mode, RunningMode};
fn main() {
assert_eq!(
running_mode(), RunningMode::Valgrind,
":~$ valgrind {}", std::env::current_exe().unwrap().display()
);
crabgrind::println!("Hey, Valgrind!");
}And run under Valgrind
:~$ cargo build :~$ valgrind ./target/debug/app
§Features
If you need your builds to be free of Valgrind artifacts, enable the opt-out
feature. This turns every request into no-op.
crabgrind = { version = "0.2", features = ["opt-out"] }
§More Examples
- Valgrind: Deterministic regression testing(e.g. CI or unit tests)
- Callgrind: Profiling specific code blocks in isolation
- Callgrind: Clearing setup costs to isolate some operation
- Memcheck: Checking for memory leaks at runtime(e.g. CI or unit tests)
- Memcheck: Enforcing bounds in a custom allocator
- DHAT: Tracking data volumes
- DRD: Tracking races in a custom shared memory
- DRD: Tracing memory accesses over some memory
§Implementation
Valgrind’s client request mechanism is a C implementation
detail, exposed strictly via C macros. Since Rust does not support C
preprocessor, these macros cannot be used directly.
crabgrind wraps the foundational VALGRIND_DO_CLIENT_REQUEST_EXPR macro via
FFI binding. All higher-level client requests are implemented in Rust on top of
this binding.
The overhead per request, compared to using C macros directly is strictly the
cost of a single function call.
The implementation is independent of any specific Valgrind version. Instead, mismatches between requests and local Valgrind instance are handled at compile-time in a zero-cost way for supported requests.
§Runtime Safety
We are coupled to the Valgrind version present during compilation.
If a request is invoked at runtime that is unsupported by the active Valgrind instance (e.g. running under an older Valgrind), the call panics immediately, showing the version mismatch message and request requirements.
If your application is running without Valgrind, these requests execute as harmless machine code. They will not panic or segfault, and overhead is probably undetectable except in a tight loops.
§License
crabgrind is distributed under MIT license.
Valgrind itself is a GPL2, however valgrind/*.h headers are distributed
under a BSD-style license, so we can use them without worrying about license
conflicts.
Modules§
- cachegrind
- Cachegrind Client Requests
- callgrind
- Callgrind Client Requests
- dhat
- DHAT Client Requests
- drd
- DRD(Data Race Detector) Client Requests
- helgrind
- Helgrind Client Requests
- memcheck
- Memcheck Client Requests
- valgrind
- Valgrind Client Requests
Macros§
- print_
stacktrace - Prints formatted text to the Valgrind output channel with a stack trace.
- println
- Prints formatted text to the Valgrind output channel.
Structs§
- Scope
Guard - Generic scoped RAII guard for client requests.
Constants§
- VALGRIND_
VERSION - Valgrind version this crate was compiled against.
Functions§
- valgrind_
client_ ⚠request_ expr - Direct mapping to the internal
VALGRIND_DO_CLIENT_REQUEST_EXPRmacro.