Valgrind

Updated: April 19, 2023

Valgrind (pronounced “val-grinned”) is a third-party tool suite that supports runtime analysis of programs. The IDE provides controls for configuring some of these tools, allowing you to track a program's dynamic memory operations, measure its heap usage, and more.

Here, we describe how to use the Tools tab in the launch configuration properties to configure the Valgrind tools that are integrated with the IDE. The integrated tools are:
  • Massif—Measures heap usage over time and where memory is being allocated
  • Memcheck—Detects memory management problems by checking all reads and writes of memory
  • Helgrind—Finds thread synchronization problems in programs that use pthreads
  • Cachegrind—Measures a program's reads and writes and its cache misses

QNX SDP actually includes the binaries for all tools in the Valgrind tool suite release. You can analyze your programs with any of them from the command line. For information on doing so and examples for the four tools mentioned above, see the valgrind entry in the Utilities Reference and the online Valgrind User Manual.

How to configure Valgrind tools

When you click the Valgrind radio button in the Tools tab, the IDE displays the Tool to run dropdown, in which you can select which of the supported Valgrind tools to configure. The UI controls shown below the dropdown consist of five tabs:
  1. General Options—displays some of the more widely used options that apply for all tools.
    The Basic Options panel has the following fields:
    Trace children on exec
    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 on exec option to make it follow execution into new process images created by exec*().
    Child silent after fork
    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 on exec is enabled.
    Run __libc_freeres on exit
    Whether to run the __libc_freeres routine provided by the C library (libc.so) when a process that uses the library exits. This routine releases all of the memory allocated by the library for its own uses, and was developed to prevent some leak checkers such as Valgrind from falsely reporting leaks in libc when a leak check is done at a process exit.

    If your program runs fine with Valgrind but encounters a segmentation fault while exiting, you can disable this option to prevent the running of __libc_freeres and avoid the crashing (although there may be falsely reported space leaks in libc.so).

    The following fields are shown in the Error Options panel:
    Demangle C++ names
    Whether to automatically demangle C++ names. When enabled, Valgrind attempts to translate encoded C++ names into a format closer to their original names.

    If you're writing suppression files manually, you should disable this option to see the mangled names in your error messages. This form must be used in suppression files.

    Callers in stack trace
    Sets the maximum number of entries to show in stack traces for program locations. This value doesn't affect the overall number of errors reported, just the call chain depth.

    Higher settings make Valgrind run slower and use more memory, but are necessary for programs with deep call chains. The default value is 12, and the maximum value is 500.

    Limit errors reported
    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.
    Show errors below main
    Whether to show any functions below main() in stack traces. Typically, such functions do C library-related work and other operations that are uninteresting for program analysis.
    Max stack frame size (B)
    The maximum size, in bytes, of a stack frame. If the stack pointer moves by more than this amount, Valgrind assumes that the program is switching to a different stack.

    You should only use this option if Valgrind's debugging output directs you to do so. In that case, it will tell you the new threshold you should specify.

    Set main thread's stack size (B)
    The stack size, in bytes, for the program's initial thread. This setting doesn't affect the size of thread stacks, as Valgrind doesn't allocate those.

    You may need to use this option and Max stack frame size together. You have to work out the suitable main thread stack size yourself (e.g., if your program encounters a segmentation fault)—Valgrind won't tell you like it will for the thread stack frame size.

    Note that the Run dsymutil (Mac OS X) checkbox has been disabled because QNX Neutrino is not supported for macOS targets.

    There's also the Extra Options text field, which lets you manually specify any extra general options you want to pass to the valgrind utility.

  2. Supressions—lets you name up to 100 suppression files that list any errors you want suppressed in the output. On QNX Neutrino targets, the default suppression file is /usr/lib/valgrind/default.supp. This file contains comments explaining the syntax required to specify an error to suppress.

    There are buttons for opening file navigators and selecting suppression files from the workspace or filesystem, and for removing a listed file.

  3. Tool Options—Here, Tool is the name of the tool selected in the Tool to run dropdown.
    For the Massif selection, the tab provides these options:
    Option Description
    Profile heap Whether to profile heap blocks.
    Administrative bytes per block

    The number of administrative bytes to use per heap block.

    This option is effective only if Profile heap is enabled.

    Profile stack Whether to profile stacks. Enabling this option greatly slows down Massif but produces stack usage data that's easy to read.
    Profile memory at page level Whether to profile memory at the page level rather than at the level of blocks allocated by malloc().
    Allocation tree depth The depth of the allocation tree, which lists the exact parts of code responsible for allocating heap memory.
    Heap allocation threshold 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.
    Allocation peak inaccuracy The percentage by which memory allocation must exceed the previous peak to be considered the new peak. Smaller values mean greater accuracy in the peak checking, but for values near 0%, Massif runs very slowly.
    Time units
    The time unit for measuring execution progress, one of:
    • i for machine instructions
    • ms for milliseconds since the program's start
    • B for the number of heap bytes currently allocated
    Detailed snaphost frequency How often the heap snapshots are detailed; a value of N means Massif makes every Nth snapshot a detailed one. These snapshots include stack traces of block allocation points, and a breakdown of heap memory by allocation point.
    Max snapshots The maximum number of snapshots (N) to keep in the results. Whenever Massif takes another snapshot and exceeds this limit, half of them are deleted. For longer programs, the final number of snapshots is between N/2 and N.
    Minimum heap block alignment The minimum alignment, in bytes, required for all allocated heap blocks. When a program asks for N bytes, Massif rounds N up to the nearest multiple of the value specified by this option.
    Allocation functions

    List of the functions to be treated like heap allocation functions. This is useful for functions that are wrappers to malloc() or new.

    There's a button for opening a dialog box to specify a new function to add to the list, and a button for removing the selected function from it.

    For the Memcheck selection, the tab provides these options:
    Option Description
    Check for memory leaks Whether to check for memory leaks. When this option is enabled, Valgrind checks for leaks when the program exits and prints a leak summary.
    Leak resolution
    The degree to which stack traces must match to be reported as the same leak, one of:
    • low—only the first two entries, which represent the bottom two functions in the call chain, must match
    • med—the first four entries must match
    • high—all entries must match (this is the default setting)

    This option is effective only if Check for memory leaks is enabled.

    Freelist size (blocks) 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, but also an increased memory footprint.
    Show reachable blocks Whether to include reachable and indirect memory leaks in the results. Reachable leaks are blocks for which a pointer to the start of the memory can be found but the memory was never freed. Indirect leaks occur when the blocks that point to the memory are lost themselves.
    Allow partial loads

    Whether to allow 32-, 64-, 128- and 256-bit naturally aligned loads from addresses for which some bytes are addressable and others are not.

    When this option is enabled, such loads don't produce an error. When it's disabled, loads from partially invalid addresses produce an illegal-address error, and the resulting bytes are marked as initialized.

    Undefined value errors Whether to report undefined value use errors. Disabling this option speeds up Memcheck.
    Track origins of uninitialized values

    Whether to track the origin of uninitialized memory (e.g., a heap block allocation, stack variable, or client request) when it's used dangerously. Enabling this option severely degrades performance, but greatly reduces the effort needed to find the cause of undefined value use errors.

    If you enable this option, you must also enable Undefined value errors.

    GCC 2.96 workarounds

    Whether to assume that reads and writes some small distance below the stack pointer are due to bugs in GCC 2.96 and hence, not to report them.

    You should enable this option only if you're using a version of QNX SDP older than 6.5.0 SP1. Otherwise, don't use it because real errors can be overlooked.

    Minimum heap block alignment The minimum alignment, in bytes, required for all allocated heap blocks. When a program asks for N bytes, Massif rounds N up to the nearest multiple of the value specified by this option.
    Show possibly lost blocks in leak check Whether to include possible memory leaks in the results. These are blocks for which a pointer to the middle but not the start of the memory can be found.
    Fill malloc'd areas with given value (0x) The byte pattern with which to fill blocks allocated by malloc(), new, etc, but not by calloc(). This option is useful when trying to solve obscure memory corruption problems.
    Fill free'd areas with given value (0x) The byte pattern with which to fill blocks released by free(), delete, etc. This option is useful when trying to solve obscure memory corruption problems.
    Ignore Ranges

    List of address ranges to be ignored by Memcheck's addressability checking.

    There's a button for opening a dialog box to specify a new address range to add to the list, and a button for removing a selected range from it.

    For the Helgrind selection, the tab provides these options:
    Option Description
    Track lockorders Whether to perform lock order consistency checking. When this option is enabled, Helgrind reports any inconsistencies in the order in which threads acquire locks. Inconsistent locking can lead to lock cycles, which create potential deadlocks that can lead to hard-to-diagnose failures.
    History level
    The historical data to keep about conflicting memory accesses, one of:
    • full—two stack traces are reported 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
    • approx—Helgrind reports the full trace of the current access, and two earlier traces such that the previous access happened between them
    • none—no data is kept about previous accesses
    Conflict cache size

    Size of the cache to keep for storing data about conflicting memory accesses. This value is the number of memory addresses for which access history is kept, not the number of bytes.

    This option is effective only when History Level is full. The minimum value is 10,000, and the maximum value is 30,000,000 (thirty million).

    For the Cachegrind selection, the tab provides these options:
    Option Description
    Profile Cache Accesses/Misses Whether to collect cache access and miss counts. You can't disable both this option and Profile Branch Instructions/Mispredictions (because no information would be collected).
    Profile Branch Instructions/Mispredictions Whether to collect branch instruction and misprediction counts. You can't disable both this option and Profile Cache Accesses/Misses (because no information would be collected).
    Manually Set Cache Specifications
    These checkboxes enable spinners for manually setting the total size, associativity, and line size of the following caches:
    • I1 Cache—first-level instruction cache
    • D1 Cache—first-level data cache
    • L2 Cache—second-level unified cache

    The total size and line size values are in bytes while the associativity value must be a power of two between 1 (for direct mapping) and 1024 (for 1024-way associativity).

  4. Symbols—provides controls for manually specifying the locations of debug symbols for any shared libraries used by your programs. Normally, the valgrind utility should be able to find these symbols by communicating with the symbol server, which runs on the host.
    You need to use this tab only if:
    • The debug symbols are on the host and Valgrind isn't producing any results and is terminating with a message saying that it's unable to connect to the server.

      In this case, you need to ensure that the server is running at the correct port and IP address, as explained in the Valgrind subsection of the “Configuring shared library support” topic.

    • The debug symbols are on the target, or you tried configuring the symbol server but still don't see any results (and hence, you must upload the symbols to the target).

      In this case, you can specify the target directories where the symbols are stored, as described in the Manually loading debug symbols on the target subsection of that same topic.

  5. Debugging Options—displays options that are useful for debugging.
    Track open file descriptors on exit
    Whether Valgrind will print a list of open file descriptors on exit or on request. Along with each file descriptor, Valgrind will print also a stack backtrace of where the file was opened and file descriptor details such as the filename or socket details.
    Show time stamp
    Whether each message is preceded with the elapsed time since startup, expressed as days, hours, minutes, seconds, and milliseconds.
    Trace system calls
    Trace signals
    Detection of self-modifying code
    Control Valgrind's detection of self-modifying code. You can select one of these options:
    • none—no detection
    • stack—detect self-modifying code on the stack (which is used for nested functions)
    • all—detect self-modifying code everywhere
    • all-non-file—detect self-modifying code everywhere except in file-backed mappings

    For information about the effect on a program's performance and behavior for each of the settings, see the smc-check description in the Valgrind User Manual.

    Verbosity level
    The verbosity level, which determines the extra information reported on various aspects of the program. You can choose none, low, or high.