addressed feedback

This commit is contained in:
Rich Kadel 2020-11-02 11:59:24 -08:00
parent a8dfb26b62
commit 6d949112f6
1 changed files with 24 additions and 15 deletions

View File

@ -26,9 +26,11 @@ When running a coverage-instrumented program, the counter values are written to
## Enable coverage profiling in the Rust compiler
*IMPORTANT:* Rust's coverage profiling features may not be enabled, by default. To enable them, you may need to build a version of the Rust compiler with the `profiler` feature enabled.
Rust's source-based code coverage requires the Rust "profiler runtime". Without it, compiling with `-Zinstrument-coverage` generates an error that the profiler runtime is missing.
First, edit the `config.toml` file, and find the `profiler` feature entry. Uncomment it and set it to `true`:
The Rust `nightly` distribution channel should include the profiler runtime, by default.
*IMPORTANT:* If you are building the Rust compiler from the source distribution, the profiler runtime is *not* enabled in the default `config.toml.example`, and may not be enabled in your `config.toml`. Edit the `config.toml` file, and find the `profiler` feature entry. Uncomment it and set it to `true`:
```toml
# Build the profiler runtime (required when compiling with options that depend
@ -40,7 +42,15 @@ Then rebuild the Rust compiler (see [rustc-dev-guide-how-to-build-and-run]).
### Building the demangler
LLVM coverage reporting tools generate results that can include function names and other symbol references, and the raw coverage results report symbols using the compiler's "mangled" version of the symbol names, which can be difficult to interpret. To work around this issue, LLVM coverage tools also support a user-specified symbol name demangler. Rust's symbol name demangler can be built with:
LLVM coverage reporting tools generate results that can include function names and other symbol references, and the raw coverage results report symbols using the compiler's "mangled" version of the symbol names, which can be difficult to interpret. To work around this issue, LLVM coverage tools also support a user-specified symbol name demangler.
One option for a Rust demangler is [`rustfilt`](https://crates.io/crates/rustfilt), which can be installed with:
```shell
cargo install rustfilt
```
Another option, if you are building from the Rust compiler source distribution, is to use the `rust-demangler` tool included in the Rust source distribution, which can be built with:
```shell
$ ./x.py build rust-demangler
@ -102,13 +112,14 @@ If `LLVM_PROFILE_FILE` contains a path to a non-existent directory, the missing
## Creating coverage reports
LLVM's tools to process coverage data and coverage maps have some version dependencies. If you encounter a version mismatch, try updating your LLVM tools, or use the LLVM tools bundled with the same Rust distrubition used to rebuild the Rust compiler (as shown in the following examples).
LLVM's tools to process coverage data and coverage maps have some version dependencies. If you encounter a version mismatch, try updating your LLVM tools.
If you are building the Rust compiler from source, you can optionally use the bundled LLVM tools, built from source. Those tool binaries can typically be found in your build platform directory at something like: `rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-*`. (Look for `llvm-profdata` and `llvm-cov`.)
Raw profiles have to be indexed before they can be used to generate coverage reports. This is done using [`llvm-profdata merge`] (which can combine multiple raw profiles and index them at the same time):
```shell
$ $HOME/rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-profdata merge \
-sparse formatjson5.profraw -o formatjson5.profdata
$ llvm-profdata merge -sparse formatjson5.profraw -o formatjson5.profdata
```
Finally, the `.profdata` file is used, in combination with the coverage map (from the program binary) to generate coverage reports using [`llvm-cov report`]--for a coverage summaries--and [`llvm-cov show`]--to see detailed coverage of lines and regions (character ranges), overlaid on the original source code.
@ -116,11 +127,9 @@ Finally, the `.profdata` file is used, in combination with the coverage map (fro
These commands have several display and filtering options. For example:
```shell
$ $HOME/rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-cov show \
$ llvm-cov show -Xdemangler=rustfilt target/debug/examples/formatjson5 \
-instr-profile=formatjson5.profdata \
target/debug/examples/formatjson5 \
-show-line-counts-or-regions \
-Xdemangler=$HOME/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler \
-show-instantiations \
-name=add_quoted_string
```
@ -131,9 +140,9 @@ $ $HOME/rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-cov show \
Some of the more notable options in this example include:
* `--instr-profile=<path-to-file>.profdata` - the location of the `.profdata` file created by `llvm-profdata merge`
* `target/debug/examples/formatjson5` - the binary that generated the coverage profiling data (originally as a `.profraw` file)
* `--Xdemangler=<path-to>/rust-demangler` - the location of the `rust-demangler` tool
* `--Xdemangler=rustfilt` - the command name or path used to demangle Rust symbols (`rustfilt` in the example, but this could also be a path to the `rust-demangler` tool)
* `target/debug/examples/formatjson5` - the instrumented binary (from which to extract the coverage map)
* `--instr-profile=<path-to-file>.profdata` - the location of the `.profdata` file created by `llvm-profdata merge` (from the `.profraw` file generated by the instrumented binary)
* `--name=<exact-function-name>` - to show coverage for a specific function (or, consider using another filter option, such as `--name-regex=<pattern>`)
## Interpreting reports
@ -155,6 +164,6 @@ Rust's implementation and workflow for source-based code coverage is based on th
[`llvm.instrprof.increment`]: https://llvm.org/docs/LangRef.html#llvm-instrprof-increment-intrinsic
[LLVM Code Coverage Mapping Format]: https://llvm.org/docs/CoverageMappingFormat.html
[rustc-dev-guide-how-to-build-and-run]: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html
[`llvm-profdata merge`]: https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge
[`llvm-cov report`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-report
[`llvm-cov show`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show
[`llvm-profdata merge`]: https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge
[`llvm-cov report`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-report
[`llvm-cov show`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show