Skip to main content

Crate valgrind_requests

Crate valgrind_requests 

Source
Expand description

Idiomatic Rust bindings for Valgrind’s Client Request Mechanism with zero-indirection execution and zero-cost fallback.

Valgrind has a trapdoor mechanism via which the client program can pass all manner of requests and queries to Valgrind and the current tool. The so-called client requests are provided to allow you to tell Valgrind facts about the behavior of your program, and also to make queries. In particular, your program can tell Valgrind about things that it otherwise would not know, leading to better results.

§Installation/Building

[dependencies]
valgrind-requests = "1.0"

or

cargo add valgrind-requests

valgrind-requests does not depend on any specific version of Valgrind. However, not all client requests are available in all Valgrind versions and this crate will abort the execution producing a panic message if a client request is used but not available in the header file.

The client requests need to be built with the Valgrind header files. Usually, these header files are installed by your distribution’s package manager with the Valgrind package into a global include path, and you don’t need to do anything. Note that the used headers need to match the used Valgrind version.

If you encounter problems because the Valgrind header files cannot be found, first ensure you have installed Valgrind and your package manager’s package includes the header files. If not or you use a custom build of Valgrind, you can point the VALGRIND_REQUESTS_VALGRIND_INCLUDE or the VALGRIND_REQUESTS_<triple>_VALGRIND_INCLUDE environment variables to the include path where the Valgrind headers can be found. For example, if the Valgrind header files reside in /home/foo/repo/valgrind/{valgrind.h, callgrind.h, ...}, then the environment variable has to point to VALGRIND_REQUESTS_VALGRIND_INCLUDE=/home/foo/repo and not VALGRIND_REQUESTS_VALGRIND_INCLUDE=/home/foo/repo/valgrind.

§Module Organization

The client requests are organized into modules representing the source header file. So, if you search for a client request originating from the valgrind.h header file, the client request can be found in the valgrind module. valgrind-requests is a complete implementation of all client requests which can be found in the original header files.

Instead of using macros like in Valgrind we’re using functions and small letter names, stripping the prefix if it is equal to the enclosing module. For example the client request RUNNING_ON_VALGRIND from the valgrind.h file equals valgrind::running_on_valgrind and VALGRIND_COUNT_ERRORS from the same valgrind.h header file equals valgrind::count_errors.

The only exception to this rule are the valgrind_printf macro and its descendants like valgrind_printf_unchecked which can be found in the crate root.

§Features

Core client request APIs are no_std compatible. The std feature which implies the alloc feature are enabled by default.

This crate provides two execution feature levels:

  • act (default): Enables actual execution of client requests when running under Valgrind. Implies stubs.
  • stubs: Enables the same public API surface and build-time code generation, but all client requests compile to no-ops that return default values. The compiler will optimize them away entirely, making this a zero-cost option suitable for production code.

Formatting convenience macros such as valgrind_printf and valgrind_println require the alloc feature because they allocate owned C strings. In allocation-free builds, you can use valgrind_print or valgrind_print_backtrace instead.

To use the zero-cost fallback, for example if you want to use the client requests for tests or benchmarks and need to make annotations in production code:

[dependencies]
valgrind-requests = { version = "1.0", default-features = false, features = ["stubs"] }

[dev-dependencies]
valgrind-requests = { version = "1.0" }

The stubs compile down to nothing and your production code is as performant as without any annotations. If your production code uses the formatting convenience macros, enable both stubs and alloc with features = ["stubs", "alloc"].

§Performance and implementation details

If possible, client requests execute with zero indirection and the same overhead as the original Valgrind C macros usable even in high performance code. On Valgrind-supported platforms for which zero-indirection isn’t implemented by us, a native C FFI binding is used which introduces at least an additional frame on the stack and the costs for the function call. That means all targets covered by Valgrind are also covered by valgrind-requests. Targets not supported by Valgrind produce a compile error.

TargetZero-indirectionNotes
x86_64/linuxyes-
x86_64/androidyesexcept the x32 ABI
x86_64/freebsdyes-
x86_64/macosyesthe versions supported by Valgrind
x86_64/windows+gnuyes-
x86_64/solarisyes-
x86/linuxyes-
x86/androidyes-
x86/freebsdyes-
x86/macosyesthe versions supported by Valgrind
x86/windows+gnuyes-
x86/solarisyes-
arm/linuxyes-
arm/androidyes-
aarch64/linuxyes-
aarch64/androidyes-
aarch64/freebsdyes-
aarch64/macosyesLouisBrunner/valgrind-macos
riscv64/linuxyes-
s390x/linuxyes-
powerpc/linuxyesrust >= 1.95.0
powerpc64/linuxyesrust >= 1.95.0
powerpc64le/linuxyesrust >= 1.95.0
mips32/linuxnono rust inline assembly available
mips64/linuxnono rust inline assembly available
nanomips/linuxnono zero-indirection planned
x86/windows+msvcnono zero-indirection planned

To disable the native C FFI binding as fallback you can set the environment variable VALGRIND_REQUESTS_STRATEGY=strict (possible values are: strict, fallback).

§Sources and additional documentation

A lot of the library documentation of the client requests within this module and its submodules is taken from the online manual and the Valgrind header files. For more details see also The Client Request mechanism

Modules§

cachegrind
All client requests from the cachegrind.h header file
callgrind
All client requests from the callgrind.h header file
dhat
All client requests from the dhat.h header file
drd
All public client requests from the drd.h header file
erroralloc
Provide the ClientRequestError
helgrind
All public client requests from the helgrind.h header file
memcheck
All public client requests from the memcheck.h header file
valgrind
All public client requests from the valgrind.h header file

Macros§

cstringalloc
Convenience macro to create a \0-byte terminated alloc::ffi::CString from a literal string
format_cstringalloc
Convenience macro to create a \0-byte terminated alloc::ffi::CString from a format string
valgrind_printfalloc
Prints to the Valgrind log.
valgrind_printf_backtracealloc
Prints to the Valgrind log with a backtrace.
valgrind_printf_backtrace_uncheckedalloc
Prints to the Valgrind log with a backtrace.
valgrind_printf_uncheckedalloc
Prints to the Valgrind log.
valgrind_printlnalloc
Prints to the Valgrind log ending with a newline.
valgrind_println_backtracealloc
Prints to the Valgrind log with a backtrace, ending the formatted string with a newline.
valgrind_println_backtrace_uncheckedalloc
Prints to the Valgrind log with a backtrace, ending the formatted string with a newline.
valgrind_println_uncheckedalloc
Prints to the Valgrind log ending with a newline.

Constants§

VALGRIND_VERSION
Valgrind’s version number from the valgrind.h file

Functions§

valgrind_print
Prints a C string to the Valgrind log.
valgrind_print_backtrace
Prints a C string with a backtrace to the Valgrind log.

Type Aliases§

RawFd
The raw file descriptor number
StackId
The StackId is used and returned by some client requests and represents an id on Valgrind’s stack
ThreadId
The ThreadId is used by some client requests to represent the tid which Valgrind uses or returns