#coverage #no-std #llvm-cov

no-std minicov

Code coverage support for no_std and embedded programs

6 releases

new 0.2.2 Nov 24, 2021
0.2.1 Nov 24, 2021
0.2.0 Jan 22, 2021
0.1.2 Nov 13, 2020
0.1.1 Apr 20, 2020

#59 in No standard library

Download history 1/week @ 2021-08-09 6/week @ 2021-08-16 4/week @ 2021-09-27 2/week @ 2021-10-04 4/week @ 2021-10-11 2/week @ 2021-10-25 7/week @ 2021-11-01 6/week @ 2021-11-08 1/week @ 2021-11-15 43/week @ 2021-11-22

57 downloads per month

Apache-2.0/MIT

43KB
723 lines

minicov

Crates.io Documentation

This crate provides code coverage 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 -Zinstrument-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.

Usage

Note: This crate requires a recent nightly compiler.

  1. Ensure that the following environment variables are set up:
export RUSTFLAGS="-Zinstrument-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:

# Applies RUSTFLAGS to everything
cargo build

# Doesn't apply RUSTFLAGS to build dependencies and proc macros
cargo build --target x86_64-unknown-linux-gnu
  1. Add the minicov crate as a dependency to your program:
[dependencies]
minicov = "0.2"
  1. Before your program exits, call minicov::capture_coverage which returns a Vec<u8> and dump its contents to a file with the .profraw extension:
fn main() {
    // ...

    let coverage = minicov::capture_coverage();
    std::fs::write("output.profraw", coverage).unwrap();
}

If you're program doesn't have the default alloc feature enabled you can use minicov::get_coverage_data_size, to get the size required for the coverage data and minicov::capture_coverage_to_buffer to serialize the coverage data:

fn main() {
    // ...

    // with COVERAGE_DATA_SIZE as a const usize
    let mut buffer: [u8; COVERAGE_DATA_SIZE] = [0; COVERAGE_DATA_SIZE];
    
    let actual_size = minicov::get_coverage_data_size();
    assert!(actual_size <= COVERAGE_DATA_SIZE, "Not enough space reserved for coverage daa");
    minicov::capture_coverage_to_buffer(&mut buffer[0..actual_size]);
    
    // Transfer coverage data somewhere else
}

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.

  1. Use a tool such as grcov or llvm-cov to generate a human-readable coverage report:
grcov output.profraw -b ./target/debug/my_program -t html -o cov_report

Change log

License

Licensed under either of:

at your option.

Contribution

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.

No runtime deps

~155KB

Ga