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

Fix GCC 9 Code coverage by adding its JSON format #11538

Closed
wants to merge 5 commits into from

Conversation

helaan
Copy link
Contributor

@helaan helaan commented Jun 2, 2020

GCC 9 changed the intermediate format to a JSON based format and with it
changed the meaning of the -i flag. Because of these changes it was not
possible to generate code coverage with GCC 9. This patch addresses that
by adding its format next to the existing GCov parser.

Addresses: #9406

@helaan helaan requested a review from lberki as a code owner June 2, 2020 18:09
GCC 9 changed the intermediate format to a JSON based format and with it
changed the meaning of the `-i` flag. Because of these changes it was not
possible to generate code coverage with GCC 9. This patch addresses that
by adding its format next to the existing GCov parser.

Addresses: bazelbuild#9406
@helaan helaan force-pushed the fix/gcc9-coverage branch from a6781c8 to fc37c66 Compare June 2, 2020 18:14

// Classes for the Gson data mapper representing the structure of the GCov JSON format

class GcovJsonFormat {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having multiple top-level classes in a java file is against the style guide

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, at least provide a link to the documentation for the JSON file format.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be acceptable to make them inner classes? I think that separating these 5 small classes that do not have associated methods and can't really be reused in other parts of the codebase into their own file would be close to littering.

Furthermore I'm not following the styleguide w.r.t. field naming as well because the elements in the JSON file use this naming, is that an issue as well?

The GCov manpage contains a thorough explanation of the fomat, however I'm having issues finding a versioned permalink other than their git source: https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/doc/gcov.texi;h=dcdd7831ff063483d43e5347af0b67083c85ecc4;hb=4212a6a3e44f870412d9025eeb323fd4f50a61da#l184 which is only in texinfo format

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inner classes are fine. I don't know how strict the style check is on the names. Please add a comment saying that these have to match the upstream definitions, so they don't get 'auto-corrected' on import.

cat *.gcov >> "$output_file"
# Delete the .gcov files.
rm *.gcov
gcov_version=$("${GCOV}" --version | sed -n -r -e 's/^.*\s([0-9]\.[0-9]\.[0-9])\s?.*$/\1/p')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that changes to this file go live immediately, whereas the coverage collector must be released.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is a way to deliver this fix without making changes in both parts. Using a combination (updated script but old collector or vice versa) shouldn't be hurtful, you'll just get missing coverage as you did before the patch.

Is it possible to release an updated Coverage Collector when the bazel update containing this fix is released?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The coverage collector release is separate from the bazel release, but someone at Google will have to make the push.

gcov_version=$("${GCOV}" --version | sed -n -r -e 's/^.*\s([0-9]\.[0-9]\.[0-9])\s?.*$/\1/p')

# Check the gcov version so we can process the data correctly
if [ "$(printf '%s\n%s' "9.1.0" "$gcov_version" | sort -V | head -n 1)" != "$gcov_version" ]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the style guide says to prefer [[ ]] over [ ].

rm *.gcov
gcov_version=$("${GCOV}" --version | sed -n -r -e 's/^.*\s([0-9]\.[0-9]\.[0-9])\s?.*$/\1/p')

# Check the gcov version so we can process the data correctly
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to explain here how this check works. It took me a minute to figure out.

@@ -78,8 +79,13 @@ static int runWithArgs(String... args) throws ExecutionException, InterruptedExc
getTracefiles(flags, filesInCoverageDir),
LcovParser::parse,
flags.parseParallelism()),
parseFiles(
getGcovInfoFiles(filesInCoverageDir), GcovParser::parse, flags.parseParallelism()));
Coverage.merge(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd only use a single call to Coverage.merge here and pass all parsed files to that call. If merge only takes two arguments, then change that to take more than two. I think it's strictly better to pass everything in at once, so Coverage.merge has the full list - there may be optimizations it can do in that case.

helaan added 3 commits June 4, 2020 12:22
This allows merging more than 2 coverage sets together.
- Changed the regex to only select the major version
- As a result, remove the whole printf/sort/head pipeline
- Change the regex to accept versions that contain multiple digits
@ulfjack
Copy link
Contributor

ulfjack commented Jun 4, 2020

@meisterT

# Check the gcov version so we can process the data correctly, GCC 9
# contains the required changes
if [[ $gcov_major_version -ge 9 ]]; then
# GCOV 9.1.0 or higher generate a JSON based coverage format
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no GCOV 9.0.0?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GCC's versioning is a bit weird: 9.0.0 are development releases and the first actual release is 9.1.0. So there are only GCC 9.0.0 development snapshots, which no one (still) uses and even if they are in use, they'll probably already contain this JSON code.

I probably should have updated the comment to say GCOV 9 instead

Source: https://gcc.gnu.org/develop.html#num_scheme

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've clarified the comment a few days ago, is that better?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay. It's stuck in internal review for a while now. Let me see if I can do something about it.

@bazel-io bazel-io closed this in 3b75bc7 Jun 16, 2020

class GcovJsonLine {
GcovJsonBranch[] branches;
int count;
Copy link

@xingxinghuo1000 xingxinghuo1000 Jul 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type of count could be long?
Take a look at : #9406 (comment)

oliverlee added a commit to oliverlee/recorder that referenced this pull request Nov 21, 2020
Generate a coverage report in CI with Bazel. This requires using Linux
and version of GCC that works with the Bazel GCov parser[1]. In this
case, CI uses Ubuntu 18.04 with GCC 7.

[1]: bazelbuild/bazel#11538
oliverlee added a commit to oliverlee/recorder that referenced this pull request Nov 21, 2020
Generate a coverage report in CI with Bazel. This requires using Linux
and version of GCC that works with the Bazel GCov parser[1]. In this
case, CI uses Ubuntu 18.04 with GCC 7.

[1]: bazelbuild/bazel#11538
oliverlee added a commit to oliverlee/recorder that referenced this pull request Nov 21, 2020
Generate a coverage report in CI with Bazel. This requires using Linux
and version of GCC that works with the Bazel GCov parser[1]. In this
case, CI uses Ubuntu 18.04 with GCC 7.

[1]: bazelbuild/bazel#11538
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants