Skip to content

fix: silence gcov's per-file summary under bazel coverage - #241

Merged
f0rmiga merged 1 commit into
mainfrom
fix/quiet-gcov-under-coverage
Aug 11, 2026
Merged

f0rmiga merged 1 commit into
mainfrom
fix/quiet-gcov-under-coverage

Conversation

@f0rmiga

@f0rmiga f0rmiga commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Problem

Bazel's collect_cc_coverage.sh invokes gcov without redirecting its stdout: the script declares gcov_log with a comment promising to save gcov's output there, but the variable is never used (still unfixed on Bazel master). gcov's per-file summary for the test's whole transitive C++ closure therefore lands in the test's test.log.

For large closures (e.g. pybind-heavy Python tests) this is megabytes of Lines executed:0.00% noise per test — one observed test.log was 9.2 MB with 237k gcov summary lines and 2 lines of actual test output. It buries the test's own output and can overflow --experimental_ui_max_stdouterr_bytes, at which point Bazel prints nothing at all for a failing test.

gcov itself has no quiet flag (-q is --use-hotness-colors), so the wrapper is the right interposition point.

Fix

Before the final exec, when the wrapped tool is gcov and COVERAGE_DIR is set (only true inside a Bazel coverage test action), redirect stdout to /dev/null. Bazel only consumes the .gcov.json.gz data files gcov writes to disk, never its stdout. stderr is untouched so real gcov errors still surface. All other tools wrapped by the same template are unaffected.

Verification

Ran bazel coverage on a downstream repo with --override_repository=gcc_toolchain=<this checkout>:

  • gcov summary lines in test.log: 1877 → 0 (test.log 185 KB → 26 KB)
  • combined lcov report byte-identical coverage content (same SF entries, same 392 nonzero DA records)
  • a failing test now prints its log inline exactly like bazel test

Bazel's collect_cc_coverage.sh invokes gcov without redirecting its
stdout (it declares gcov_log but never uses it, still unfixed on Bazel
master), so the per-file summary of the test's whole transitive C++
closure lands in the test's test.log. For large closures that is
megabytes of 'Lines executed:0.00%' noise that buries the test's own
output and can overflow Bazel's --experimental_ui_max_stdouterr_bytes,
hiding real failures.

Bazel only consumes the .gcov.json.gz data files gcov writes to disk,
never its stdout, so the wrapper now drops stdout when the wrapped tool
is gcov running under a Bazel coverage test action (COVERAGE_DIR is only
set there). stderr is left alone so real gcov errors still surface.
@f0rmiga
f0rmiga merged commit ed8c2ab into main Aug 11, 2026
29 checks passed
@f0rmiga
f0rmiga deleted the fix/quiet-gcov-under-coverage branch August 11, 2026 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant