This crate provides code coverage and profile-guided optimization (PGO) support
for no_std
and embedded programs.
This is done through a modified version of the LLVM profiling runtime (normally part of compiler-rt) from which all dependencies on libc have been removed.
All types of instrumentation using the LLVM profiling runtime are supported:
- Rust code coverage with -Cinstrument-coverage
.
- Rust profile-guided optimization with -Cprofile-generate
.
- Clang code coverage with -fprofile-instr-generate -fcoverage-mapping
.
- Clang profile-guided optimization with -fprofile-instr-generate
.
- Clang LLVM IR profile-guided optimization with -fprofile-generate
.
Note that to profile both C and Rust code at the same time you must use Clang
with the same LLVM version as the LLVM used by rustc. You can pass these flags
to C code compiled with the cc
crates using [environment variables].
Note: This crate requires a recent nightly compiler.
sh
export RUSTFLAGS="-Cinstrument-coverage -Zno-profiler-runtime"
Note that these flags also apply to build-dependencies and proc macros by default. This can be worked around by explicitly specifying a target when invoking cargo:
```sh
cargo build
cargo build --target x86_64-unknown-linux-gnu ```
minicov
crate as a dependency to your program:toml
[dependencies]
minicov = "0.3"
minicov::capture_coverage
with a sink (such
as Vec<u8>
) and then dump its contents to a file with the .profraw
extension:```ignore fn main() { // ...
let mut coverage = vec![];
unsafe {
// Note that this function is not thread-safe! Use a lock if needed.
minicov::capture_coverage(&mut coverage).unwrap();
}
std::fs::write("output.profraw", coverage).unwrap();
} ```
If your program is running on a different system than your build system then you will need to transfer this file back to your build system.
Sinks must implement the CoverageWriter
trait. If the default alloc
feature
is enabled then an implementation is provided for Vec<u8>
.
sh
grcov output.profraw -b ./target/debug/my_program -s . -t html -o cov_report
The steps for profile-guided optimzation are similar. The only difference is the
flags passed in RUSTFLAGS
:
```sh
export RUSTFLAGS="-Cprofile-generate -Zno-profiler-runtime" cargo run --target x86_64-unknown-linux-gnu --release
rust-profdata merge -o output.profdata output.profraw
export RUSTFLAGS="-Cprofile-use=output.profdata" cargo build --target x86_64-unknown-linux-gnu --release ```
Licensed under either of:
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.