Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-12142] llvm-cov doesn't work on haswell CPU #54577

Closed
Mordil opened this issue Feb 7, 2020 · 16 comments
Closed

[SR-12142] llvm-cov doesn't work on haswell CPU #54577

Mordil opened this issue Feb 7, 2020 · 16 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.

Comments

@Mordil
Copy link

Mordil commented Feb 7, 2020

Previous ID SR-12142
Radar rdar://problem/59302413
Original Reporter @Mordil
Type Bug

Attachment: Download

Environment

Swift 5.1.4 (via swift:5.1 official docker image)

GitLab CI cloud runner

GitHub Actions cloud ubuntu-latest

Local docker (mac mini 2018 - macOS 10.15.2)

Additional Detail from JIRA
Votes 0
Component/s
Labels Bug
Assignee None
Priority Medium

md5: f866b8d9108475f7ba056e1f3f26f8f5

Issue Description:

I've been trying to use llvm-cov in the Swift docker images to generate and output code coverage reports.

On my local machine, the following commands work and I get expected test coverage output within the official swift:5.1 docker image (Swift 5.1.4):

swift test --enable-code-coverage

BINARY_PATH=".build/x86_64-unknown-linux/debug/swift-currencyPackageTests.xctest"
PROF_DATA_PATH=".build/x86_64-unknown-linux/debug/codecov/default.profdata"
IGNORE_FILENAME_REGEX="(.build|TestUtils|Tests)"

llvm-cov report \
    $BINARY_PATH \
    --format=text \
    -instr-profile="$PROF_DATA_PATH" \
    -ignore-filename-regex="$IGNORE_FILENAME_REGEX" 

On GitLab CI, all of the command executes fine - but llvm-cov finds no coverage data and just reports empty lines with 0 coverage.

GitHub Actions also works, but it correctly provides the expected code coverage like I get on my local machine.

I have confirmed that all 3 environments are using the exact same Docker image by verifying the digest SHA and Image ID.

The only difference I can find is the CPU architecture through llvm-cov --version.

Environment Reported CPU Generates Report?
Local Docker (iMac 2011) sandybridge yes
Local Docker (mac mini 2018) skylake yes
GitHub Actions docker skylake-avx512 yes
GitLab CI docker haswell no
@beccadax
Copy link
Contributor

@swift-ci create

@vedantk
Copy link
Member

vedantk commented Feb 11, 2020

Could you provide more information about what goes wrong on Gitlab CI? Specifically, what do you mean by 'llvm-cov finds no coverage data'? Is it that `llvm-cov report` prints out expected results in the "Filename" column, but that all the files have 0 coverage? Does this contradict what's inside the .profdata file? You can check by running `llvm-profdata show --all-functions --counts $the_profdata_file`.

There's nothing Haswell-specific about llvm's code coverage implementation, AFAIK. I wonder if something went wrong while collecting the profile data.

@Mordil
Copy link
Author

Mordil commented Feb 11, 2020

@vedantk Sure, sorry for the lack of details. I'm not 100% it's haswell specific, but it's the only (that I've found) difference.

Where I say "I get code coverage report" I mean, this is the output I receive:

Filename                                      Regions    Missed Regions     Cover   Functions  Missed Functions  Executed       Lines      Missed Lines     Cover
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ChannelHandlers/RedisByteDecoder.swift              5                 0   100.00%           3                 0   100.00%          10                 0   100.00%
ChannelHandlers/RedisCommandHandler.swift          15                 5    66.67%           8                 3    62.50%          45                11    75.56%
ChannelHandlers/RedisMessageEncoder.swift           3                 1    66.67%           3                 1    66.67%          13                 6    53.85%
Commands/BasicCommands.swift                       28                 4    85.71%          16                 2    87.50%          99                 7    92.93%
Commands/HashCommands.swift                        38                 4    89.47%          29                 1    96.55%         156                 1    99.36%
Commands/ListCommands.swift                        56                 8    85.71%          48                 5    89.58%         217                11    94.93%
Commands/SetCommands.swift                         46                12    73.91%          30                 4    86.67%         147                 4    97.28%
Commands/SortedSetCommands.swift                  172                19    88.95%         105                 6    94.29%         555                18    96.76%
Commands/StringCommands.swift                      23                 2    91.30%          21                 1    95.24%         100                 1    99.00%
Extensions/StandardLibrary.swift                   10                 2    80.00%           6                 1    83.33%          21                 1    95.24%
Extensions/SwiftNIO.swift                           9                 1    88.89%           7                 0   100.00%          38                 1    97.37%
RESP/RESPTranslator.swift                          69                 7    89.86%          10                 2    80.00%         172                10    94.19%
RESP/RESPValue.swift                               39                11    71.79%          14                 3    78.57%          69                17    75.36%
RESP/RESPValueConvertible.swift                    52                19    63.46%          15                 3    80.00%          99                22    77.78%
RedisClient.swift                                   2                 0   100.00%           2                 0   100.00%           7                 0   100.00%
RedisConnection.swift                              72                23    68.06%          47                10    78.72%         228                31    86.40%
RedisErrors.swift                                  12                 4    66.67%           6                 1    83.33%          23                 3    86.96%
RedisKey.swift                                     15                 9    40.00%          12                 6    50.00%          38                20    47.37%
RedisMetrics.swift                                  9                 2    77.78%           9                 2    77.78%          23                 2    91.30%
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TOTAL                                             675               133    80.30%         391                51    86.96%        2060               166    91.94% 

versus, on GitLab CI this is the output I receive:

 Filename                      Regions    Missed Regions     Cover   Functions  Missed Functions  Executed       Lines      Missed Lines     Cover
 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 TOTAL                               0                 0         -           0                 0         -           0                 0         - 

On all systems I also run ls -l and receive the following (same on all environments, working or not):

Profdata:  -rw-r--r--. 1 root root 575608 Feb 8 19:51 .build/x86_64-unknown-linux/debug/codecov/default.profdata
Test binary:  -rwxr-xr-x. 1 root root 16309424 Feb 8 19:51 .build/x86_64-unknown-linux/debug/redi-stackPackageTests.xctest 

@Mordil
Copy link
Author

Mordil commented Feb 11, 2020

I wrote a StackOverflow question about this, that admittedly has more clear details: https://stackoverflow.com/questions/60130969/llvm-cov-fails-to-generate-report-when-run-on-cloud-gitlab-ci

@vedantk
Copy link
Member

vedantk commented Feb 11, 2020

Interesting, the filenames are supposed to be encoded within the `.xctest` binary. The fact that they don't appear at all in one configuration is interesting. What's the output of running:

`llvm-cov report -dump-collected-paths $BINARY_PATH -instr-profile="$PROF_DATA_PATH"`

Do all the filenames match `IGNORE_FILENAME_REGEX`?

If not, perhaps the compiler fails to encode them (although, that's never been an issue before). Could you attach two versions of `.build/x86_64-unknown-linux/debug/redi-stackPackageTests.xctest`, one from a working configuration, and one from the non-working configuration?

@Mordil
Copy link
Author

Mordil commented Feb 13, 2020

@vedantk I've attached a zip with the xctest binary from a local docker instance (hosted on macOS Catalina), along with its codecov folder.

The files are found in the zip as well, generated from the GitLab CI job that ran the same docker instance.

While gathering these artifacts, I also ran the command you specified as -dump rather than -dump-collected-paths as the latter doesn't seem to be a supported argument.

llvm-cov report -dump $BINARY_PATH -instr-profile="$PROF_DATA_PATH" -ignore-filename-regex="$IGNORE_FILENAME_REGEX" 

The output from the local docker instance that is correctly outputting the code coverage is attached to the ticket.

The output of the same command on GitLab CI:

 Filename                      Regions    Missed Regions     Cover   Functions  Missed Functions  Executed       Lines      Missed Lines     Cover575 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------576 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------577 TOTAL                               0                 0         -           0                 0         -           0                 0         - 

I also tried with LLVM-8 & LLVM-9 with the same results on GitLab CI

@vedantk
Copy link
Member

vedantk commented Feb 13, 2020

It seems like something is wrong with your llvm-cov tool. Locally I'm able to inspect the .xctest binary:

```
$ ~/src/builds/llvm-project-master-RA/bin/llvm-cov report /Users/vsk/Downloads/SR-12142_XCTest_Binaries/SR-12142_LocalDocker_Swift-5.1.4_Ubuntu/redi-stackPackageTests.xctest -instr-profile /Users/vsk/Downloads/SR-12142_XCTest_Binaries/SR-12142_LocalDocker_Swift-5.1.4_Ubuntu/codecov/default.profdata -ignore-filename-regex='(.build|TestUtils|Tests)'
Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover

ChannelHandlers/RedisByteDecoder.swift 5 0 100.00% 3 0 100.00% 10 0 100.00%
ChannelHandlers/RedisCommandHandler.swift 15 5 66.67% 8 3 62.50% 45 11 75.56%
ChannelHandlers/RedisMessageEncoder.swift 3 1 66.67% 3 1 66.67% 13 6 53.85%
Commands/BasicCommands.swift 28 4 85.71% 16 2 87.50% 99 7 92.93%
Commands/HashCommands.swift 38 4 89.47% 29 1 96.55% 156 1 99.36%
Commands/ListCommands.swift 56 8 85.71% 48 5 89.58% 217 11 94.93%
Commands/SetCommands.swift 46 12 73.91% 30 4 86.67% 147 4 97.28%
Commands/SortedSetCommands.swift 172 19 88.95% 105 6 94.29% 555 18 96.76%
Commands/StringCommands.swift 23 2 91.30% 21 1 95.24% 100 1 99.00%
Extensions/StandardLibrary.swift 10 2 80.00% 6 1 83.33% 21 1 95.24%
Extensions/SwiftNIO.swift 9 1 88.89% 7 0 100.00% 38 1 97.37%
RESP/RESPTranslator.swift 69 7 89.86% 10 2 80.00% 172 10 94.19%
RESP/RESPValue.swift 39 11 71.79% 14 3 78.57% 69 17 75.36%
RESP/RESPValueConvertible.swift 52 19 63.46% 15 3 80.00% 99 22 77.78%
RedisClient.swift 2 0 100.00% 2 0 100.00% 7 0 100.00%
RedisConnection.swift 72 19 73.61% 47 7 85.11% 228 25 89.04%
RedisErrors.swift 12 4 66.67% 6 1 83.33% 23 3 86.96%
RedisKey.swift 15 9 40.00% 12 6 50.00% 38 20 47.37%
RedisMetrics.swift 9 2 77.78% 9 2 77.78% 23 2 91.30%

TOTAL 675 129 80.89% 391 48 87.72% 2060 160 92.23%
```

I'm not able to reproduce the issue with llvm-cov from llvm/master, or from swift 5.2.

Does removing the -ignore-filename-regex flag change the output? What is `llvm-cov show --version`?

@Mordil
Copy link
Author

Mordil commented Feb 13, 2020

Removing -ignore-filename-regex does not change any output (aside from adding the parts that were previously filtered).

Did you check the binary in the SR-12142_GitLabCIDocker_Swift-5.1.4_Ubuntu folder in the zip? That's the one that is failing, not the SR-12142_LocalDocker_Swift-5.1.4_Ubuntu

GitLab CI fails to show a report for Swift 5.1, Swift 5.2, and master every time I've tested

@vedantk
Copy link
Member

vedantk commented Feb 13, 2020

Sorry for not including both commands. On my machine, `llvm-cov report /Users/vsk/Downloads/SR-12142_XCTest_Binaries/SR-12142_GitLabCIDocker_Swift-5.1.4_Ubuntu/redi-stackPackageTests.xctest -instr-profile /Users/vsk/Downloads/SR-12142_XCTest_Binaries/SR-12142_GitLabCIDocker_Swift-5.1.4_Ubuntu/codecov/default.profdata` also produces a complete report.

@Mordil
Copy link
Author

Mordil commented Feb 13, 2020

So where does that leave us for trying to find a root cause? This is the official Docker image, with the llvm-cov that ships with the Swift tool chain.

The same Docker image is producing working test binaries on any platform, but llvm-cov from the same image is not producing a report when hosted on GitLab CI

@vedantk
Copy link
Member

vedantk commented Feb 17, 2020

Apologies, I should have been clearer. I'll need to set up a swift:5.1 docker image on a GitLab CI instance and step through what the llvm-cov binary is doing to determine the root cause (rdar://problem/59302413 tracks this). As things stand, I'm not sure that updating the llvm-cov binary would fix the issue, as the same version of the binary apparently behaves correctly on other machines.

At the moment I'm at a loss for an explanation of the output you see. FWIW, we do run integration tests for llvm-cov on a variety of different OS/hardware combinations to qualify each swift toolchain, and we've never detected an issue like this. The numbers 575, 576, and 577 show up in your output without any accompanying context/coverage data, and this seems very strange to me.

@Mordil
Copy link
Author

Mordil commented Feb 17, 2020

@vedantk Ah, thanks for the clarification.

This might require deeper help with the GitLab team, then. I wrote this bug against their services: https://gitlab.com/gitlab-org/gitlab/issues/202793

The reason for this, is that this only occurs when using their cloud Docker runner, which will be difficult for us to try and debug in a black-box way. If I trigger a build using GitLab CI on my own personal Docker runner - this bug does not reproduce. So it seems isolated directly to their cloud Docker CI hosts.

@Austinpayne
Copy link

For anyone who runs into this we had this problem as well. I don't believe it is a haswell CPU specific issue. The problem is that gitlab CI checks out your code into a directory that starts "/build/..." so the regex `(.build|TestUtils|Tests)` doesn't actually ignore the "/build/.build" directory. The solution is to instead fix the regex:

(\.build|TestUtils|Tests)

Cheers!

@Mordil
Copy link
Author

Mordil commented Feb 25, 2022

@Austinpayne And that works for you? Oh my gosh![]( Regex AGAIN)

@Austinpayne
Copy link

Yup! Very good find by another member of our team.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@Mordil
Copy link
Author

Mordil commented Sep 25, 2022

I have confirmed this was an issue related to the Regex pattern used for filtering file names.

@Mordil Mordil closed this as completed Sep 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.
Projects
None yet
Development

No branches or pull requests

4 participants