rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.96k stars 12.69k forks source link

std::process::exit() on MSVC bypasses writing LLVM InstrProf counters to profraw file #77553

Open richkadel opened 4 years ago

richkadel commented 4 years ago

This bug does not occur on Linux or MacOS.

Note that I observed this unexpected behavior when compiling on Windows, targeting MSVC.

I have not confirmed the behavior on Windows targeting GNU.

The minimal reproducible example (MRE) here shows the problem even when returning a success status code (0), and while a Rust program will generate a 0 status for programs that return a Result::OK or a (), and a 1 status for programs that return Result::Err, as far as I know, we need to call std::process::exit(...) to return any other status code.

Therefore, any program that requires the ability to return a status other than 0 or 1 may get empty, or worse, incomplete, coverage results when testing coverage under MSVC.

I tried this code:

fn main() {
    std::process::exit(0);
}
$ build/x86_64-pc-windows-msvc/stage1/bin/rustc.exe -Zinstrument-coverage basic.rs
$ LLVM_PROFILE_FILE=basic.profraw ./basic.exe
$ ls -l basic.profraw
-rw-r--r-- 1 richkadel Domain Users 0 Oct  4 15:32 basic.profraw

I expected to see this happen: The same result as on Linux and MacOS, and the same result that I get if the call to std::process::exit(0) is removed. In both cases, the basic.profraw file size is greater than 0. In the working cases, the non-empty basic.profraw file can be used with llvm-profdata and llvm-cov tools to generate and view coverage reports.

Here is the expected result on Linux, for example:

$ build/x86_64-unknown-linux-gnu/llvm/bin/llvm-profdata merge -sparse basic.profraw -o basic.profdata
$ build/x86_64-unknown-linux-gnu/llvm/bin/llvm-cov show --instr-profile=basic.profdata basic
    1|      1|fn main() {
    2|      1|    std::process::exit(0);
    3|      1|}

Instead, this happened: The basic.profraw file size is 0 (as shown in the example above). LLVM coverage reports show no results.

Meta

./build/x86_64-unknown-linux-gnu/stage1/bin/rustc --version --verbose
rustc 1.49.0-dev
binary: rustc
commit-hash: unknown
commit-date: unknown
host: x86_64-unknown-linux-gnu
release: 1.49.0-dev
LLVM version: 11.0
wucke13 commented 1 year ago

I believe that I see this bug on Linux, contradicting the

This bug does not occur on Linux or MacOS.

claim. Further info here: https://github.com/taiki-e/cargo-llvm-cov/issues/235

Anything I can do to help?