Skip to content

Commit cb6b275

Browse files
authored
Source-based code coverage in nightly (#725)
1 parent 1a8abd2 commit cb6b275

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
layout: post
3+
title: Source-based code coverage in nightly
4+
author: Tyler Mandry
5+
team: The Compiler Team <https://www.rust-lang.org/governance/teams/compiler>
6+
---
7+
8+
9+
Support has landed in the nightly compiler for source-based code coverage,
10+
and we want your help testing it!
11+
12+
13+
# What is _source-based_ code coverage, exactly?
14+
15+
You may already be familiar with code coverage, which shows you which lines
16+
of code execute. Code coverage is usually applied to tests to find out which
17+
code is actually being tested and which code isn’t.
18+
19+
Nightly Rust already supports another kind of source code coverage, commonly
20+
called gcov, which relies on debug info to map from LLVM IR to lines of
21+
source code. Instrumentation is then added in the LLVM backend during code
22+
generation to count how many times each line is run.
23+
24+
However, since LLVM doesn’t know exactly how Rust code is structured, there’s
25+
a lot lost in the translation between Rust source and LLVM IR. Line-level
26+
granularity is sometimes too coarse, and debug info can be unreliable,
27+
especially when building in release mode. The result is coverage reports that
28+
only show an approximation of what code actually executed.
29+
30+
Source-based code coverage instrumentation is applied by the Rust compiler,
31+
not LLVM. This instrumentation is more precise because it's being done in
32+
MIR, which holds a mapping between the original Rust source code and the
33+
control-flow graph of the program.
34+
35+
That means things like short-circuited conditionals, closures, and match
36+
guards are all precisely counted. And since instrumentation counters are
37+
injected as regular MIR statements, the compiler can further optimize the
38+
program without affecting coverage results.
39+
40+
[![Comparison of gcov and source-based coverage results][comparison-img]][comparison-img]
41+
42+
_Above: A comparison of the gcov (left) and source-based coverage (right)
43+
results. gcov highlights skipped lines, marked with #####, while source-based
44+
coverage highlights exact regions of code that were skipped. Note that on
45+
line 30, one boolean subexpression is short-circuited. This is surfaced by
46+
source-based coverage but not gcov._
47+
48+
What this means is that source-based code coverage is both efficient and
49+
accurate. LLVM’s existing coverage tools ([llvm-profdata] and [llvm-cov])
50+
generate both coverage summaries and very fine-grained code regions, helping
51+
you find gaps in your testing coverage. What you do about that is up to you!
52+
53+
[comparison-img]: /images/inside-rust/2020-11-12-source-based-code-coverage/comparison.png
54+
[llvm-profdata]: https://llvm.org/docs/CommandGuide/llvm-profdata.html
55+
[llvm-cov]: https://llvm.org/docs/CommandGuide/llvm-cov.html
56+
57+
# Trying it out
58+
59+
Work on the implementation [began back in April][MCP], and [many PRs
60+
later][PRs], it’s ready for you to try. All you need is a recent nightly and
61+
a tool to read the coverage reports.
62+
63+
[Take a look at this guide to get started][guide]. If you spot any issues,
64+
please [report them]. It’s a huge help!
65+
66+
Finally, if you try it out and it works well, we’d also like to hear from
67+
you! Come by the [Zulip stream] for this change or comment on the [feature
68+
request].
69+
70+
[MCP]: https://github.com/rust-lang/compiler-team/issues/278
71+
[PRs]: https://github.com/rust-lang/rust/pulls?q=is%3Apr+author%3Arichkadel+is%3Aclosed+closed%3A%3C2020-11-06
72+
[guide]: https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/source-based-code-coverage.html
73+
[report them]: https://github.com/rust-lang/rust/issues/new/choose
74+
[Zulip stream]: https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/Implement.20LLVM-compatible.20source-based.20cod.20compiler-team.23278
75+
[feature request]: https://github.com/rust-lang/rust/issues/34701
76+
77+
# Acknowledgements
78+
79+
The implementation work was all done by Rich Kadel; thanks to him for all the
80+
amazing work he’s done. Thanks also to Wesley Wiser for helping with reviews,
81+
to Bob Wilson for lending his experience with LLVM's InstrProf coverage APIs,
82+
and to eddyb for their guidance in choosing a MIR-based approach.
Loading

0 commit comments

Comments
 (0)