iai_callgrind

Module client_requests

source
Available on crate feature client_requests_defs only.
Expand description

The iai-callgrind rustified interface to Valgrind’s Client Request Mechanism

You can use these methods to manipulate and query Valgrind’s execution inside iai-callgrind benchmarks or your own programs.

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.

§Building

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 but activating the client_requests feature (see below) of the iai-callgrind dependency.

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 IAI_CALLGRIND_VALGRIND_INCLUDE or the IAI_CALLGRIND_<triple>_VALGRIND_INCLUDE environment variables to the include path where the valgrind headers can be found. The include directive used by iai-callgrind is #include "valgrind/valgrind.h" and is prefixed with valgrind. 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 IAI_CALLGRIND_VALGRIND_INCLUDE=/home/foo/repo and not IAI_CALLGRIND_VALGRIND_INCLUDE=/home/foo/repo/valgrind.

Also, worth to consider is that the build of iai-callgrind with client requests takes longer than the build without them.

§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 crate::client_requests::valgrind module. 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 crate::client_requests::valgrind::running_on_valgrind and VALGRIND_COUNT_ERRORS from the same valgrind.h header file equals crate::client_requests::valgrind::count_errors.

The only exception to this rule are the crate::valgrind_printf macro and its descendents like crate::valgrind_printf_unchecked which can be found in the root of iai-callgrind.

§Features

The client requests are organized into two separate features. The client_requests_defs feature enables the definitions but doesn’t run any code yet. To actually run the client requests you need to enable the client_requests feature. The client_requests feature implies client_requests_defs. For example, if you need to include the client requests into your production code, you usually don’t want them to run if not running under valgrind in the iai-callgrind benchmarks. In order to achieve this, the client_requests_defs can be safely included in the production code since the compiler will optimize them completely away. So, in your Cargo.toml file, you can do

[dependencies]
iai-callgrind = { version = "0.14.0", default-features = false, features = [
    "client_requests_defs"
]}

[dev-dependencies]
iai-callgrind = { version = "0.14.0", features = ["client_requests"] }

If you would only need the client requests in iai-callgrind benchmarks, you only need to add iai-callgrind with the client_requests feature to your dev-dependencies.

§Performance and implementation details

Depending on the target, the client requests are optimized to run with the same overhead as the original valgrind client requests in C code. The optimizations are based on inline assembly with the asm! macro and depend on the availability of it on a specific target. Since inline assembly is not stable on all targets which are supported by valgrind, we cannot provide optimized client requests for them. But, you can still use the non-optimized version on all platforms which would be natively supported by valgrind. In the end, all targets which are covered by valgrind are also covered by iai-callgrind.

The non-optimized version add overhead because we need to wrap the macro from the header file in a function call. This additional function call equals the additional overhead compared to the original valgrind implementation. Although this is usually not much, we try hard to avoid any overhead to not slow down the benchmarks.

Here’s a short overview on which targets the optimized client requests are available and why not (Valgrind version = 3.22)

TargetOptimizedReason
x86_64/linuxyes-
x86_64/freebsdyes-
x86_64/apple+darwinyes-
x86_64/windows+gnuyes-
x86_64/solarisyes-
x86/linuxyes-
x86/freebsdyes-
x86/apple+darwinyes-
x86/windows+gnuyes-
x86/solarisyes-
x86/windows+msvcnoTBD
arm/linuxyes-
aarch64/linuxyes-
x86_64/windows+msvcnounsupported by valgrind
s390x/linuxnounstable inline assembly
mips32/linuxnounstable inline assembly
mips64/linuxnounstable inline assembly
powerpc/linuxnounstable inline assembly
powerpc64/linuxnounstable inline assembly
powerpc64le/linuxnounstable inline assembly
nanomips/linuxnovalgrind only

All other targets you don’t find in the table above are also not supported by valgrind, yet.

Note this table might quickly become outdated with higher versions of valgrind, and you should not rely on it to be up-to-date. As indicated above, the bindings are created dynamically in such a way, that always all targets which are covered by valgrind are also covered by iai-callgrind. They just might not have been optimized, yet. If you need to know if your target is supported you should consult the valgrind.h header file in the Valgrind Repository or have a look at the Valgrind Release Notes

§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§

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

Constants§

Type Aliases§

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