mozilla / grcov

Rust tool to collect and aggregate code coverage data for multiple source files
Mozilla Public License 2.0
1.19k stars 149 forks source link

Windows w64devkit: no version found for gcov #919

Closed deltabeard closed 1 month ago

deltabeard commented 1 year ago

Hello. I am trying to use grcov within a w64devkit environment on Windows 10. w64devkit uses Mingw-w64 GCC, and includes gcov.

After compiling my project with cc -g3 -O2 -std=c99 -Wall -Wextra --coverage -opeanut-mini peanut-mini.c and running the project, I have the gcda and gcno files. I execute grcov . -s . -t html --branch -o . but I get the following error message:

$ grcov . -s . -t html --branch -o .
Failed to create a symlink, but successfully copied file (as fallback).
This is less efficient. You can enable symlinks without elevating to Administrator.
See instructions at https://github.com/mozilla/grcov/blob/master/README.md#enabling-symlinks-on-windows
12:00:21 [ERROR] A panic occurred at src\gcov.rs:102: no version found for `gcov`.

When running gcov --version, I get:

$ gcov --version
gcov (GCC) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

I'm not sure what the problem is or if I'm missing something.

Please find attached my project files. These files are MIT licensed. project-grcov.zip

Thanks.

marco-c commented 1 year ago

I run parse_version("gcov (GCC) 12.2.0") and it seems to be working fine for me. Could you log the output at https://github.com/mozilla/grcov/blob/ebde263b75846050fef9da3c6ce400fde9c7a6d6/src/gcov.rs#L76? The code in src/gcov.rs is pretty self-contained, so you can also extract it into a new Rust project and compile and run that if it's easier for you.

deltabeard commented 1 year ago

I made the following change as requested to log the output.

diff --git a/src/gcov.rs b/src/gcov.rs
index 9be3528..040f9fa 100644
--- a/src/gcov.rs
+++ b/src/gcov.rs
@@ -74,6 +74,7 @@ pub fn get_gcov_version() -> &'static Version {
                 .expect("Failed to execute `gcov`. `gcov` is required (it is part of GCC).");
             assert!(output.status.success(), "`gcov` failed to execute.");
             let output = String::from_utf8(output.stdout).unwrap();
+            println!("OUTPUT: {}", output);
             parse_version(&output)
         };
     }

I get the following output:

 $ ~/source/repos/grcov/target/debug/grcov.exe .
Failed to create a symlink, but successfully copied file (as fallback).
This is less efficient. You can enable symlinks without elevating to Administrator.
See instructions at https://github.com/mozilla/grcov/blob/master/README.md#enabling-symlinks-on-windows
OUTPUT: gcov (GCC) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

13:56:32 [ERROR] A panic occurred at src\gcov.rs:103: no version found for `gcov`.

Making an additional change to run parse_version("gcov (GCC) 12.2.0"),

diff --git a/src/gcov.rs b/src/gcov.rs
index 9be3528..4b344a1 100644
--- a/src/gcov.rs
+++ b/src/gcov.rs
@@ -74,7 +74,8 @@ pub fn get_gcov_version() -> &'static Version {
                 .expect("Failed to execute `gcov`. `gcov` is required (it is part of GCC).");
             assert!(output.status.success(), "`gcov` failed to execute.");
             let output = String::from_utf8(output.stdout).unwrap();
-            parse_version(&output)
+            println!("OUTPUT: {}", output);
+            parse_version("gcov (GCC) 12.2.0")
         };
     }
     &V

produces the following error:

 $ ~/source/repos/grcov/target/debug/grcov.exe .
Failed to create a symlink, but successfully copied file (as fallback).
This is less efficient. You can enable symlinks without elevating to Administrator.
See instructions at https://github.com/mozilla/grcov/blob/master/README.md#enabling-symlinks-on-windows
OUTPUT: gcov (GCC) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

14:09:38 [ERROR] A panic occurred at src\parser.rs:411: called `Result::unwrap()` on an `Err` value: Error("Unable to parse u64 from -993465152", line: 1, column: 3497)
marco-c commented 1 year ago

Could you try running the following on your machine?

use semver::Version;

fn parse_version(gcov_output: &str) -> Version {
    let mut versions: Vec<_> = gcov_output
        .split(|c| c == ' ' || c == '\n')
        .filter_map(|value| Version::parse(value).ok())
        .collect();
    assert!(!versions.is_empty(), "no version found for `gcov`.");

    versions.pop().unwrap()
}

fn main() {
    let gcov_output = "gcov (GCC) 12.2.0";
    let mut versions: Vec<_> = gcov_output.split(|c| c == ' ' || c == '\n').collect();
    let mut versions2: Vec<_> = gcov_output.split(|c| c == ' ' || c == '\n').map(|value| Version::parse(value)).collect();

    println!("{:?}", versions);
    println!("{:?}", versions2);
    println!("{}", parse_version(gcov_output));
}

The output should be:

["gcov", "(GCC)", "12.2.0"]
[Err(Error("unexpected character 'g' while parsing major version number")), Err(Error("unexpected character '(' while parsing major version number")), Ok(Version { major: 12, minor: 2, patch: 0 })]
12.2.0
deltabeard commented 1 year ago

I get the expected output.

["gcov", "(GCC)", "12.2.0"]
[Err(Error("unexpected character 'g' while parsing major version number")), Err(Error("unexpected character '(' while parsing major version number")), Ok(Version { major: 12, minor: 2, patch: 0 })]
12.2.0
marco-c commented 1 year ago

That's weird, in your earlier test parse_version("gcov (GCC) 12.2.0") was failing!

deltabeard commented 1 year ago

In my earlier test where I had parse_version("gcov (GCC) 12.2.0") I was getting a different error message:

14:09:38 [ERROR] A panic occurred at src\parser.rs:411: called `Result::unwrap()` on an `Err` value: Error("Unable to parse u64 from -993465152", line: 1, column: 3497)
marco-c commented 1 year ago

The weird thing is that you are not getting an error in the code I asked you to run, not even in the parse_version(gcov_output) call. It is the same call that is erroring out in your earlier run.

feo-elektronik-may commented 7 months ago

I just stumbled across this as well - it seems to be caused by Windows \r\n line terminators. A simple solution is to use trim() to discard whitespace at the beginning and end of any version number candidates.

I implemented this fix and added a simple unit test for it in #1179.