Skip to content
Latchkey

valgrind: Usage, Options & Common CI Errors

valgrind runs a program under instrumentation to catch memory bugs and leaks.

valgrind (Memcheck) finds invalid reads/writes, uninitialized values, and leaks. The single most important CI flag is --error-exitcode: without it, valgrind reports errors but still exits 0, so the job passes despite real bugs.

What it does

valgrind runs a program on a synthetic CPU and instruments memory operations. Its default tool, Memcheck, detects invalid memory access, use of uninitialized memory, double frees, and memory leaks, reporting each with a stack trace.

Common usage

Terminal
valgrind --leak-check=full --error-exitcode=1 ./app
valgrind --leak-check=full --show-leak-kinds=all ./app
valgrind --track-origins=yes ./app        # where uninit came from
valgrind --suppressions=known.supp ./app
valgrind --tool=helgrind ./app            # data-race detector

Options

FlagWhat it does
--leak-check=fullDetailed per-leak reporting
--error-exitcode=NExit N if any error is found (CI gate)
--track-origins=yesTrace uninitialized-value origins
--show-leak-kinds=allReport all leak categories
--suppressions=<file>Ignore known/false-positive errors
--tool=memcheck|helgrind|callgrindChoose the analysis tool

Common errors in CI

The silent trap: by default valgrind exits 0 even when it finds errors, so a leaky build "passes" - always add --error-exitcode=1 to gate CI. In containers valgrind may hit "Fatal error ... could not create temp dir" or fail under a restrictive seccomp profile (it needs to mmap and intercept syscalls; loosen seccomp). It also runs ~10-50x slower, so wrap long suites in timeout. Use --gen-suppressions=all to capture and then suppress library false positives.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →