rust-lang / rust

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

`-C instrument-coverage` does not work with `crate-type = ["dylib"]` dependency on windows-msvc #124372

Open taiki-e opened 3 months ago

taiki-e commented 3 months ago

Repro

# Cargo.toml
[package]
name = "repro"
version = "0.1.0"
edition = "2021"

[dependencies]
dylib = { path = "dylib" }
// src\lib.rs
use dylib as _; // link dylib

pub fn double(x: i64) -> i64 {
    x * x
}

#[cfg(test)]
mod test {
    use crate::double;

    #[test]
    fn test_double() {
        assert_eq!(4, double(2))
    }
}
# dylib\Cargo.toml
[package]
name = "dylib"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["dylib"]
// dylib\src\lib.rs
// empty
# With powershell
$ $env:RUSTFLAGS="-C instrument-coverage"; cargo test --tests -v
   Compiling dylib v0.1.0 (C:\Users\taiki\projects\tmp\coverage_debugging\dylib)
     Running `rustc --crate-name dylib --edition=2021 dylib\src\lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=183 --crate-type dylib --emit=dep-info,link -C prefer-dynamic -C embed-bitcode=no -C debuginfo=2 -C metadata=7a6a43aab10b14a1 --out-dir C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\deps -C incremental=C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\incremental -L dependency=C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\deps -C instrument-coverage`
   Compiling repro v0.1.0 (C:\Users\taiki\projects\tmp\coverage_debugging)
     Running `rustc --crate-name repro --edition=2021 src\lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=183 --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 --test -C metadata=ab884994c6371615 -C extra-filename=-ab884994c6371615 --out-dir C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\deps -C incremental=C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\incremental -L dependency=C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\deps --extern dylib=C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\deps\dylib.dll -C instrument-coverage`
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.40s
     Running `C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\deps\repro-ab884994c6371615.exe`

running 1 test
test test::test_double ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

LLVM Profile Error: Runtime and instrumentation version mismatch : expected 9, but get -1879048144

I expected to see this happen: no "LLVM Profile Error"

Instead, this happened: the above "LLVM Profile Error"

If the dependency is not dylib, or if the dylib crate itself is tested alone, this problem does not occur. This problem also occurs when both the repro crate and the dylib crate are dylib.

Originally reported in https://github.com/taiki-e/cargo-llvm-cov/issues/364 by @mdeering24.

Meta

rustc --version --verbose:

rustc 1.79.0-nightly (ef8b9dcf2 2024-04-24)
binary: rustc
commit-hash: ef8b9dcf23700f2e2265317611460d3a65c19eff
commit-date: 2024-04-24
host: aarch64-pc-windows-msvc
release: 1.79.0-nightly
LLVM version: 18.1.4
bjorn3 commented 3 months ago

Could this be related to libstd getting dynamically linked without being built with -Cinstrument-coverage itself? Maybe try if RUSTFLAGS="-Cprefer-dynamic" works for a regular crate without any dylibs other than libstd involved.

taiki-e commented 3 months ago

Maybe try if RUSTFLAGS="-Cprefer-dynamic" works for a regular crate without any dylibs other than libstd involved.

I tried with setting the dependency crate-type back to default and with -Cprefer-dynamic enabled, but no error occurred.

-[lib]
-crate-type = ["dylib"]
+#[lib]
+#crate-type = ["dylib"]
$ $env:RUSTFLAGS="-C instrument-coverage -Cprefer-dynamic"; cargo test --tests -v
   Compiling dylib v0.1.0 (C:\Users\taiki\projects\tmp\coverage_debugging\dylib)
     Running `rustc --crate-name dylib --edition=2021 dylib\src\lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=183 --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 -C metadata=66b504ff4471d6a2 -C extra-filename=-66b504ff4471d6a2 --out-dir C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\deps -C incremental=C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\incremental -L dependency=C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\deps -C instrument-coverage -Cprefer-dynamic`
   Compiling repro v0.1.0 (C:\Users\taiki\projects\tmp\coverage_debugging)
     Running `rustc --crate-name repro --edition=2021 src\lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=183 --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 --test -C metadata=c71f36c1d55bce77 -C extra-filename=-c71f36c1d55bce77 --out-dir C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\deps -C incremental=C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\incremental -L dependency=C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\deps --extern dylib=C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\deps\libdylib-66b504ff4471d6a2.rlib -C instrument-coverage -Cprefer-dynamic`
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.42s
     Running `C:\Users\taiki\projects\tmp\coverage_debugging\target\debug\deps\repro-c71f36c1d55bce77.exe`

running 1 test
test test::test_double ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s