Skip to content

Commit b0de731

Browse files
committed
Source-based code coverage in nightly
1 parent d995727 commit b0de731

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
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 happens directly in the Rust
31+
compiler. The compiler can see branches in individual expressions within the
32+
same line or spanning multiple lines, and this analysis is always precise
33+
because it's being done in MIR. That means that things like short-circuited
34+
conditionals, closures, and match guards are all precisely counted. Counters
35+
are injected as additional MIR code statements, so the compiler can still
36+
optimize the program without affecting the coverage results.
37+
38+
[![Comparison of gcov and source-based coverage results][comparison-img]][comparison-img]
39+
40+
_Above: A comparison of the gcov (left) and source-based coverage (right)
41+
results. gcov highlights skipped lines, marked with #####, while source-based
42+
coverage highlights exact regions of code that were skipped. Note that on
43+
line 30, one boolean subexpression is short-circuited. This is surfaced by
44+
source-based coverage but not gcov._
45+
46+
What this means is that source-based code coverage is both efficient and
47+
accurate. LLVM’s existing coverage tools ([llvm-profdata] and [llvm-cov])
48+
generate both coverage summaries and very fine-grained code regions, helping
49+
you find gaps in your testing coverage. What you do about that is up to you!
50+
51+
[comparison-img]: /images/inside-rust/2020-11-11-source-based-code-coverage/comparison.png
52+
[llvm-profdata]: https://llvm.org/docs/CommandGuide/llvm-profdata.html
53+
[llvm-cov]: https://llvm.org/docs/CommandGuide/llvm-cov.html
54+
55+
# Trying it out
56+
57+
Work on the implementation [began back in April][MCP], and [many PRs
58+
later][PRs], it’s ready for you to try. All you need is a recent nightly and
59+
a tool to read the coverage reports.
60+
61+
[Take a look at this guide to get started][guide]. If you spot any issues,
62+
please [report them]. It’s a huge help!
63+
64+
Finally, if you try it out and it works well, we’d also like to hear from
65+
you! Come by the [Zulip stream] for this change or comment on the [feature
66+
request].
67+
68+
[MCP]: https://github.com/rust-lang/compiler-team/issues/278
69+
[PRs]: https://github.com/rust-lang/rust/pulls?q=is%3Apr+author%3Arichkadel+is%3Aclosed+closed%3A%3C2020-11-06
70+
[guide]: https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/source-based-code-coverage.html
71+
[report them]: https://github.com/rust-lang/rust/issues/new/choose
72+
[Zulip stream]: https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/Implement.20LLVM-compatible.20source-based.20cod.20compiler-team.23278
73+
[feature request]: https://github.com/rust-lang/rust/issues/34701
74+
75+
# Acknowledgements
76+
77+
The implementation work was all done by Rich Kadel; thanks to him for all the
78+
amazing work he’s done. Thanks also to Wesley Wiser for helping with reviews,
79+
to Bob Wilson for lending his experience with LLVM's InstrProf coverage APIs,
80+
and to eddyb for their guidance in choosing a MIR-based approach.
Loading

0 commit comments

Comments
 (0)