Home Explore Blog CI



rustc

1st chunk of `src/llvm-coverage-instrumentation.md`
b81dc1e5f4d1524e050c474a5df3a007fb85a680d2dc94a70000000100000b21
# LLVM Source-Based Code Coverage

<!-- toc -->

`rustc` supports detailed source-based code and test coverage analysis
with a command line option (`-C instrument-coverage`) that instruments Rust
libraries and binaries with additional instructions and data, at compile time.

The coverage instrumentation injects calls to the LLVM intrinsic instruction
[`llvm.instrprof.increment`][llvm-instrprof-increment] at code branches
(based on a MIR-based control flow analysis), and LLVM converts these to
instructions that increment static counters, when executed. The LLVM coverage
instrumentation also requires a [Coverage Map] that encodes source metadata,
mapping counter IDs--directly and indirectly--to the file locations (with
start and end line and column).

Rust libraries, with or without coverage instrumentation, can be linked into
instrumented binaries. When the program is executed and cleanly terminates,
LLVM libraries write the final counter values to a file (`default.profraw` or
a custom file set through environment variable `LLVM_PROFILE_FILE`).

Developers use existing LLVM coverage analysis tools to decode `.profraw`
files, with corresponding Coverage Maps (from matching binaries that produced
them), and generate various reports for analysis, for example:

<img alt="Screenshot of sample `llvm-cov show` result, for function add_quoted_string"
 src="img/llvm-cov-show-01.png" class="center"/>
<br/>

Detailed instructions and examples are documented in the
[rustc book][rustc-book-instrument-coverage].


## Recommended `bootstrap.toml` settings

When working on the coverage instrumentation code, it is usually necessary to
**enable the profiler runtime** by setting `profiler = true` in `[build]`.
This allows the compiler to produce instrumented binaries, and makes it possible
to run the full coverage test suite.

Enabling debug assertions in the compiler and in LLVM is recommended, but not
mandatory.

```toml
# Similar to the "compiler" profile, but also enables debug assertions in LLVM.
# These assertions can detect malformed coverage mappings in some cases.
profile = "codegen"

[build]
# IMPORTANT: This tells the build system to build the LLVM profiler runtime.
# Without it, the compiler can't produce coverage-instrumented binaries,
# and many of the coverage tests will be skipped.
profiler = true

[rust]
# Enable debug assertions in the compiler.
debug-assertions = true
```

## Rust symbol mangling

`-C instrument-coverage` automatically enables Rust symbol mangling `v0` (as
if the user specified `-C symbol-mangling-version=v0` option when invoking
`rustc`) to ensure consistent and reversible name mangling. This has two
important benefits:

1. LLVM coverage tools can analyze coverage over multiple runs, including some
   changes to source code; so mangled names must be consistent across compilations.

Title: LLVM Source-Based Code Coverage in Rust
Summary
This document describes how Rust supports source-based code coverage analysis using the `-C instrument-coverage` option, which instruments code with additional instructions and data to track code execution. It involves injecting calls to the `llvm.instrprof.increment` intrinsic and using Coverage Maps to map counter IDs to file locations. The document also recommends enabling the profiler runtime and debug assertions in `bootstrap.toml` when working on coverage instrumentation code. Additionally, `-C instrument-coverage` automatically enables Rust symbol mangling `v0` to ensure consistent and reversible name mangling.