SanitizerCoverage#
Introduction#
LLVM has a simple code coverage instrumentation built in (SanitizerCoverage). It inserts calls to user-defined functions on function-, basic-block-, and edge- levels. Default implementations of those callbacks are provided and implement simple coverage reporting and visualization, however if you need just coverage visualization you may want to use SourceBasedCodeCoverage instead.
Tracing PCs with guards#
With -fsanitize-coverage=trace-pc-guard the compiler will insert the following code
on every edge:
__sanitizer_cov_trace_pc_guard(&guard_variable)
Every edge will have its own guard_variable (uint32_t).
The compiler will also insert calls to a module constructor:
// The guards are [start, stop).
// This function will be called at least once per DSO and may be called
// more than once with the same values of start/stop.
__sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop);
With an additional ...=trace-pc,indirect-calls flag
__sanitizer_cov_trace_pc_indirect(void *callee) will be inserted on every indirect call.
The functions __sanitizer_cov_trace_pc_* should be defined by the user.
Example:
// trace-pc-guard-cb.cc
#include <stdint.h>
#include <stdio.h>
#include <sanitizer/coverage_interface.h>
// This callback is inserted by the compiler as a module constructor
// into every DSO. 'start' and 'stop' correspond to the
// beginning and end of the section with the guards for the entire
// binary (executable or DSO). The callback will be called at least
// once per DSO and may be called multiple times with the same parameters.