Skip to content
Latchkey

valgrind --tool=callgrind: Call-Graph Profiling

valgrind --tool=callgrind counts instructions and calls per function to build a precise call-graph profile.

Callgrind is deterministic: it counts every instruction rather than sampling, so results are reproducible across runs. That determinism is valuable for CI regression checks, at the cost of speed.

What it does

Callgrind instruments a program to count instruction executions and function calls, producing a callgrind.out file. callgrind_annotate summarizes it as text, and KCachegrind visualizes the call graph. Because it counts rather than samples, results are deterministic.

Common usage

Terminal
valgrind --tool=callgrind ./my-program
callgrind_annotate callgrind.out.<pid>
# also simulate the cache
valgrind --tool=callgrind --cache-sim=yes ./my-program

Options

FlagWhat it does
--tool=callgrindSelect the Callgrind profiler
--cache-sim=yesSimulate cache to report cache misses
--branch-sim=yesSimulate branch prediction
--callgrind-out-file=<f>Path for the output file
--dump-instr=yesCollect per-instruction (not just per-line) costs

In CI

Because callgrind is deterministic, the instruction count for a fixed workload is stable, so you can gate on it more reliably than on wall time. Store callgrind.out as an artifact and inspect with callgrind_annotate or KCachegrind offline.

Common errors in CI

Long runtimes are the usual failure; callgrind is even slower than Memcheck, so a small benchmark, not the full suite, is the right target. "callgrind_annotate: command not found" means the valgrind package that ships the helper is not installed. Multiple callgrind.out.<pid> files appear when the program forks; annotate the one for the main pid.

Related guides

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