valgrind
Run and analyze a program with a Valgrind tool, using the specified Valgrind and program options
Syntax:
valgrind general_options [--tool=tool_name [tool_options]] program_name program_options
Runs on:
QNX OS
General options:
Core Command-line Optionssection of the Valgrind User Manual explains all general options.
- --child-silent-after-fork=yes|no
- Whether to remain silent and not show debugging or logging output for child processes created by fork(). Enabling this option makes the output less confusing for multiprocess programs and is especially useful when trace-children is enabled (provided that the child processes call exec*() after the fork() call).
- --error-exitcode=value
- Define an alternative exit code to use if Valgrind detects errors in the program being analyzed. In such cases, the value of this option is returned; if there are no errors, Valgrind just returns whatever value the program returns.
- --error-limit=yes|no
- Whether to stop reporting errors after 10,000,000 in total or 1,000 different types have occurred. Enabling this option limits the performance impact on programs with many errors.
- --extra-debuginfo-path=path
- Specify an extra path for locating debug symbol (.sym) files. Valgrind searches several standard paths, such as /usr/lib/debug, to find debug information when analyzing a program. Sometimes, though, you may need to store the symbol files in a mounted location or a temporary writeable directory (e.g., /tmp). In these cases, you may provide an absolute path in extra-debuginfo-path. For more information about this option, see the Valgrind User Manual.
- -h or --help
- Display information about valgrind options, both general and tool-specific, then exit. Any other options on the command line are ignored.
- --log-file=filename
- Send all messages to the specified file. You can specify an absolute or relative filepath. An empty filename makes Valgrind abort.
- --num-callers=number
- Set the maximum number of entries to show in stack traces for program locations. Note that this value doesn't affect the overall number of errors reported, just the call chain depth.
- -q or --quiet
- Run silently, printing only error messages. This is useful if you're running automated tests.
- --suppressions=filename[,filename]*
- Suppress the output of any errors listed in the specified files. You can name up to 100 suppression files, with the names separated by commas.
- --time-stamp=yes|no
- Whether to precede each message with a timestamp in the form of days, hours, minutes, seconds, and milliseconds.
- --tool=tool_name
- Run the specified Valgrind tool. This is the most important option!
- --trace-children=yes|no
- Whether to trace into any process images created by exec*(). Valgrind automatically traces into any process copies created by fork(), but you must enable the trace-children option to make it follow execution into new process images initiated by exec*().
- -v or --verbose
- Increase output verbosity. This option makes valgrind show information about various aspects of its operation, such as warnings about unusual behavior. You can use multiple -v arguments to produce more messages, up to three levels. Each argument must be in its own option (e.g., you must specify -v -v for two levels instead of -vv).
Memcheck options:
Memcheck Command-Line Optionssection of the Valgrind User Manual explains all tool-specific options.
- --freelist-vol=size
- Set the size, in bytes, of the space used to store recently freed blocks. A larger freelist means a longer time period in which Memcheck can store freed blocks and detect invalid accesses to them. However, it also means an increased memory footprint.
- --leak-check=no|summary|yes|full
- Specify whether to check for leaks and how much leak information to report. If set to a supported value other than no, Valgrind checks for leaks when the program exits and prints either a leak summary only (if summary is specified) or both a summary and details about the leaks found (if yes or full is specified).
- --leak-resolution=low|med|high
- Control the degree to which stack traces must match to be reported as the same leak.
- --show-leak-kinds=list|all|none
- Specify which kinds of leaks to look for.
This option argument can be a comma-separated list with one or more of these entries:
- definite — no pointer to the memory can be found so the programmer couldn't have freed it
- indirect — the blocks that point to the memory are lost themselves
- possible — a pointer to the middle but not the start of the memory can be found
- reachable — a pointer to the start of the memory can be found but the memory was never freed
- --track-origins=yes|no
- Whether to track the origin of uninitialized memory when it's used dangerously.
The origin could be a heap block allocation, a stack variable within a function, a client request,
or other sources. Enabling this option is helpful for interpreting undefined value use errors.
Note:This option is disabled by default because origin tracking severely degrades performance, both in speed and memory usage. But it greatly reduces the effort needed to find the cause of undefined value use errors, so it's often worth the cost.
- --undef-value-errors=yes|no
- Whether to report undefined value use errors. Disabling this option speeds up Memcheck.
Massif options:
Massif Command-line Optionssection of the Valgrind User Manual explains all tool-specific options.
- --detailed-freq=N
- Set how often the heap snapshots are detailed, meaning Massif does an in-depth analysis of the current heap blocks. In the results, the detailed snapshots include stack traces of where the blocks were allocated, and a breakdown of heap memory by allocation point. The lowest allowable value is 1, which makes every snapshot detailed.
- --heap=yes|no
- Whether to profile heap blocks.
- --massif-out-file=filename
- Write the heap profiling data to the specified file instead of the default massif.out.pid. You can specify an absolute or relative filepath. An empty filename makes Valgrind abort.
- --max-snapshots=N
- Set the maximum number of snapshots to keep in the results. Whenever Massif takes another snapshot and exceeds this limit, half of them are deleted. For all programs except short-running ones, the final number of snapshots is between N/2 and N.
- --peak-inaccuracy=m.n
- Specify the percentage by which memory allocation must exceed the previous peak to be considered the new peak. This memory usage checking doesn't guarantee that Massif records the actual peak because there can be many high points in memory usage that are quite close together. Reducing this option's value increases the accuracy of the checking, but for low values approaching and including 0%, Massif runs very slowly.
- --stacks=yes|no
- Whether to profile stacks. Enabling this option greatly slows down Massif but produces stack usage data that's easier to interpret than what's produced with Memcheck.
- --threshold=m.n
- Set the relative size threshold for heap blocks to be reported individually in the results. Allocations for blocks smaller than this threshold are aggregated into a single results entry.
- --time-unit=i|ms|B
- Specify the time unit for measuring execution progress. The possible values
are:
- i for instructions — machine instructions, not lines of code
- ms for milliseconds — the real time since the start of the program
- B for bytes — the number of bytes currently allocated on the heap
Helgrind options:
Helgrind Command-line Optionssection of the Valgrind User Manual explains all tool-specific options.
- --conflict-cache-size=N
- The size of the cache to keep for storing information about conflicting memory accesses. This value is the number of memory addresses for which access history is kept, not the number of bytes. Note that this option is effective only when history-level is full.
- --history-level=none|approx|full
- How much historical data to keep about conflicting memory accesses. The default setting is full and it makes Helgrind store and report two stack traces for data races—the full trace of the current access to a memory location and the partial trace (up to 8 entries) of the previous access. This setting uses a lot of CPU and memory but is very useful for finding the root cause of data races.
- --track-lockorders=no|yes
- Whether to perform lock order consistency checking. By default, this option is enabled, so Helgrind monitors the order in which threads acquire locks and reports any inconsistencies in this ordering. Inconsistent locking can lead to lock cycles (i.e., patterns of circular dependency between threads acquiring the same set of locks), which create potential deadlocks. This information is useful because potential deadlocks are often missed during testing but can lead to hard-to-diagnose failures.
Cachegrind options:
Cachegrind Command-line Optionssection in the Valgrind User Manual.
- --branch-sim=no|yes
- Whether to collect branch instruction and misprediction counts. When enabled this setting slows Cachegrind noticeably, so by default it's disabled. You can't set both branch-sim and cache-sim to no (because no information would be collected).
- --cache-sim=no|yes
- Whether to collect cache access and miss counts. By default, this setting is enabled. You can't set both branch-sim and cache-sim to no (because no information would be collected).
- --cachegrind-out-file=filename
- Write the profiling data to the specified file rather than the default file of cachegrind.out.pid. You can use the %p and %q modifiers to insert the PID or the value of an environment variable, similar to --log-file.
- --D1=size,associativity,line size
- Set the size, associativity, and line size of the first-level data cache. The first and third values are in bytes while the second value must be a power of two between 1 (for direct mapping) and 1024 (for 1024-way associativity).
- --I1=size,associativity,line size
- Set the size, associativity, and line size of the first-level instruction cache. The first and third values are in bytes while the second value must be a power of two between 1 (for direct mapping) and 1024 (for 1024-way associativity).
- --LL=size,associativity,line size
- Set the size, associativity, and line size of the last-level unified cache. The first and third values are in bytes while the second value must be a power of two between 1 (for direct mapping) and 1024 (for 1024-way associativity).
Description:
The valgrind utility lets you use a Valgrind tool to analyze a program's runtime behavior. The utility takes an executable binary and uses the selected tool to add instrumentation code, then runs the program on a synthetic CPU. This design means you don't have to recompile the program to analyze it with Valgrind. Because Valgrind simulates the execution of every machine instruction, the active tool analyzes the code not only in your program but also in all linked libraries, including the C library.
- Copy the Valgrind binary and libraries you need to a writeable target location (e.g., /tmp)
- Include the necessary Valgrind files in a location mounted on the target
- Modify your target image to include the Valgrind files, as explained in
Adding Valgrind to your target image
Your program binary and the libraries it uses must contain debug symbols if you
want to see accurate file names and line numbers in the results. The exception
is the libc library; its debug symbols must be provided to
Valgrind for it to run at all. There are two methods of making debug symbols
available, as explained in Providing debug
symbols to Valgrind
.
- the path and name of the valgrind binary
- general Valgrind options that you want to set
- the tool to use, if you're not using Memcheck
- any options to configure the selected tool as needed
- the path, name, and any necessary arguments of the program to analyze
For Memcheck, it's recommended to use -O1 compiler optimization but no higher, because higher settings make the tool report false positives.
--memcheck:leak-check=yes
The online Valgrind reference describes all current tools in the distribution. Below, we provide examples of common use cases for Memcheck, Massif, Helgrind, and Cachegrind.
Adding Valgrind to your target image
When possible, you should copy the Valgrind binary and libraries to your target's filesystem or to a location mounted on the target; modifying the image is complex and time-consuming (because you have to rebuild and redeploy it). Also, you must be sure that your target image has enough space to hold the Valgrind files in addition to the rest of the image content.
/usr/bin/valgrind=${QNX_TARGET}/${PROCESSOR}/usr/bin/valgrind
/usr/lib/valgrind=${QNX_TARGET}/${PROCESSOR}/usr/lib/valgrind
In general, you should store the binary file at /usr/bin/valgrind and the libraries and error suppression files in /usr/lib/valgrind. If your target uses a different directory structure, you must specify the alternative locations of these files in the PATH and VALGRIND_LIB variables. Note that you must export their settings (e.g., export VALGRIND_LIB=path) to make them visible to Valgrind.
For general information on modifying your BSP buildfile and building your target image, see Building Embedded Systems or your BSP User's Guide.
Providing debug symbols to Valgrind
- Running a binary and library files that contain debug symbols
- Uploading symbol files to a target path searched by Valgrind
[+raw] libc.so.1
For details about determining which shared object library files you need, see the
Shared libraries
section of Building
Embedded Systems.
For the second method, you can copy the debug symbol (.sym) files to either the same target directory where you intend to run the program (i.e., the working directory) or a directory in the LD_LIBRARY_PATH or QNX_TARGET environment variables (to use mounted locations). The valgrind binary looks for these files at startup, and always looks in the working directory before searching those other paths. You can also store the symbol files in a directory named in the extra-debuginfo-path option.
If you use LD_LIBRARY_PATH, you must store the symbol files in the same directory as the libraries themselves (i.e., the .so files), but they can be in any directory listed in the variable definition. With QNX_TARGET, you must store the files in a subdirectory within the single path listed in this variable, and this subdirectory must be named for the target architecture. For instance, if QNX_TARGET is /var/tmp and your target is an x86_64 system, the proper path for storing the files is /var/tmp/x86_64.
When setting either of these environment variables, you must export the setting (e.g., export QNX_TARGET=path) to make it visible to Valgrind.
For QNX SDP components delivered as libraries (e.g., audio drivers, video capture), the symbol files are available from the QNX Software Center. Some component packages contain the stripped libraries and the debug symbol files. For others, there's a separate package for the symbols. Typically, symbol packages are automatically installed, but you should confirm that the symbols you need are installed. For details, see the QNX Software Center User's Guide.
Examples:
Memcheck
Run the valgrind binary to analyze the cpu_burner program. Because the --tool option isn't specified, the default tool, Memcheck, is used for analysis. Valgrind precedes each output message with a timestamp and sends the messages enabled for two levels of verbosity to the cpu_burner.log file in the same directory in which it runs.valgrind --log-file=cpu_burner.log --time-stamp=yes -v -v cpu_burner
valgrind --trace-children=yes --child-silent-after-fork=yes NeutrinoThreads_Example -t 4
Run the default tool of Memcheck on the NeutrinoThreads_Example program, while tracing into the images of child processes and outputting their debug and log messages only after exec*() is called, not right after fork(). No log file is named, so the output messages are directed to the terminal from where Valgrind is run. Here, the program is given one option (-t, which is set to 4 to request four threads).
valgrind --suppressions=$HOME/glibc_glitches.supp --track-origins=yes --undef-value-errors=yes ip_cam --res=low
Pass a resolution (res) setting of low onto ip_cam and run Memcheck on this program. Any errors listed in the specified suppressions file will not be outputted. The two tool-specific options tell Memcheck to track and report the origins of any uninitialized memory used by the program.
valgrind --tool=memcheck --show-leak-kinds=definite,indirect,possible --leak-check=full PeaksAndValleys
Perform a thorough leak check on PeaksAndValleys, looking for definite, indirect, and possible leaks with Memcheck and reporting details about each leak. Although Memcheck is the default tool, it can be useful to name it explicitly if you're running Valgrind test cases from a script file and you want to easily find commands that use this tool.
Massif
valgrind --tool=massif --time-unit=B --massif-out-file=cpu_burner_heap.log cpu_burner
Run Massif to analyze the heap usage of cpu_burner. Use bytes, not machine instructions, as the time unit to mark execution progress, and direct the output messages from Massif to the cpu_burner_heap.log file in the same directory in which the tool (and the program) runs.
valgrind --tool=massif --time-unit=B --max-snapshots=50 --detailed-freq=5 ip_cam --res=med
Pass a resolution (res) setting of medium (med) to ip_cam and run Massif on this program, using bytes as the time unit. The Valgrind tool will keep at most 50 heap snapshots in the results and will perform a detailed heap analysis every fifth snapshot.
Helgrind
valgrind --tool=helgrind --history-level=full --conflict-cache-size=5000000 road_race -t 4 -h 4
Find causes of data races in a multithreaded program using Helgrind. To uncover many potential data races by showing many stack trace entries, the access history cache size is set to 5,000,000 (five million) entries, or five times its default size. The program being analyzed is named road_race, and it takes -t and -h arguments to create 4 tortoise and 4 hare threads.
valgrind --log-file=road_race.log -v -v --tool=helgrind --history-level=none --track-lockorders=yes road_race -t 2 -h 2
Use Helgrind to find thread synchronization problems other than data races, such as misuses of the pthreads API and inconsistent lock ordering. Here, Valgrind writes the messages enabled for two levels of verbosity to road_race.log in the same directory in which it runs.
Cachegrind
valgrind --tool=cachegrind --branch-sim=yes --cachegrind-out-file=%q{HOME}/cachegrind.out.%p HTMLGears
Run Cachegrind on the HTMLGears program and report branch counts in addition to cache counts (which are reported by default). The analysis output is directed to a file with a name ending with the PID of the Valgrind process and stored in the $HOME directory.
valgrind --tool=cachegrind --I1=65536,2,256 --D1=524288,4,512 HTMLGears
Run Cachegrind on HTMLGears using a simulated first-level instruction cache of 65536 bytes, 2-way associativity, and a 256-byte line size, and first-level data cache of 524288 bytes, 4-way associativity, and a 512-byte line size. Because --LL isn't specified, Cachegrind uses the CPUID instruction to determine the configuration of the last-level cache. The default output file is used; this file is named cachegrind.out.PID and is written to the directory in which the program runs.
Exit status:
- 0
- A zero value is returned in any of these cases:
- you use the default error exit code setting for valgrind and the program being analyzed returns a zero value, whether or not it has errors
- you set the error-exitcode option to override the exit code to return when Valgrind detects errors, but the program being analyzed is error-free and returns a zero value
- >0
- A nonzero value is returned in any of these cases:
- you use the default error exit code setting for valgrind and the program being analyzed is hard-coded to return a nonzero value, whether or not it has errors
- you set the error-exitcode option to override the exit code to return when Valgrind detects errors, and the program being analyzed has errors
- the valgrind binary experiences an error and can't run the program (e.g., a required library isn't found); in such cases, valgrind returns a value of 1