diff --git a/.github/workflows/reusable-test.yml b/.github/workflows/reusable-test.yml index b9780a37e..e8981e899 100644 --- a/.github/workflows/reusable-test.yml +++ b/.github/workflows/reusable-test.yml @@ -107,7 +107,7 @@ jobs: - name: Combine code coverage data if: ${{ inputs.dev-gcov }} run: | - make coverage-combine FASTCOV_JOBS=2 + make coverage-combine mv obj_coverage/verilator.info obj_coverage/verilator-${{ inputs.suite }}.info ls -lsha obj_coverage diff --git a/Makefile.in b/Makefile.in index cc6f18084..386b69744 100644 --- a/Makefile.in +++ b/Makefile.in @@ -712,7 +712,8 @@ override undefine COVERAGE_BASE # Use the above variabels instead FASTCOV := nodist/fastcov.py FASTCOV_JOBS ?= $(shell nproc) FASTCOV_OPT := -j $(FASTCOV_JOBS) -FASTCOV_OPT += --gcov $(GCOV) +# gcov does not free memory between files, so run it in batches via a wrapper +FASTCOV_OPT += --gcov nodist/gcov_batch FASTCOV_OPT += --lcov FASTCOV_OPT += --process-gcno FASTCOV_OPT += --branch-coverage @@ -786,7 +787,7 @@ $(COVERAGE_DIR)/verilator.info: $(GCNO_FILES) $(GCDA_FILES) @echo "# fastcov: combining all .gcda files into lcov .info" @echo "####################################################################" @mkdir -p $(COVERAGE_DIR) - /usr/bin/time -f "That took %E" \ + GCOV=$(GCOV) /usr/bin/time -f "That took %E" \ $(FASTCOV) $(FASTCOV_OPT) --output $@ # Filter combined .info file for patch coverage diff --git a/nodist/gcov_batch b/nodist/gcov_batch new file mode 100755 index 000000000..2a4bd8031 --- /dev/null +++ b/nodist/gcov_batch @@ -0,0 +1,36 @@ +#!/bin/bash +# DESCRIPTION: Verilator: gcov wrapper for fastcov, bounding gcov memory usage +# +# Usage: GCOV= nodist/gcov_batch [gcov options] +# +# fastcov passes all coverage files of a worker to a single gcov process, but +# gcov does not free memory between input files, which can exhaust memory with +# many files. This wrapper runs the gcov in $GCOV on batches of at most 16 +# files at a time instead. The output is the same as if all files were passed +# to a single gcov. +# +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +gcov="${GCOV:-gcov}" +batch=16 + +opts=() +files=() +for arg in "$@"; do + case "$arg" in + -*) opts+=("$arg") ;; + *) files+=("$arg") ;; + esac +done + +# No files, e.g.: 'gcov -v' +if [ ${#files[@]} -eq 0 ]; then + exec "$gcov" "${opts[@]}" +fi + +status=0 +for ((i = 0; i < ${#files[@]}; i += batch)); do + "$gcov" "${opts[@]}" "${files[@]:i:batch}" || status=$? +done +exit $status