Skip to content

Commit 2ca1ab2

Browse files
meteorcloudyc-mita
andauthored
Make bazel_cc_code_coverage_test more robust against GCC version differences (bazelbuild#16254)
* -fprofile-dir shouldn't be used because on the g++ command line because it has different behaviour with different versions (w.r.t. where the output gcda file ends up). * The gcda and gcno files may end up in the same directory as the object file or in the current working directory. * The output of the gcov call in collect_cc_coverage may be "*.gcda.gcov.json.gz" or "*.gcov.json.gz" (as well as the original text file for much older GCC versions). Also re-enable the test for Ubuntu 20.04 pre and postsubmits. Fixes bazelbuild#16229 Closes bazelbuild#16235. PiperOrigin-RevId: 473218955 Change-Id: I1f4887f251da8f56f8ea525c1a1410e6257bf31b Co-authored-by: Charles Mita <[email protected]>
1 parent 6a2b1ae commit 2ca1ab2

File tree

1 file changed

+44
-25
lines changed

1 file changed

+44
-25
lines changed

src/test/shell/bazel/bazel_cc_code_coverage_test.sh

+44-25
Original file line numberDiff line numberDiff line change
@@ -107,24 +107,44 @@ int main(void) {
107107
EOF
108108

109109
generate_and_execute_instrumented_binary coverage_srcs/test \
110-
"$COVERAGE_DIR_VAR/coverage_srcs" \
111110
coverage_srcs/a.h coverage_srcs/a.cc \
112111
coverage_srcs/b.h \
113112
coverage_srcs/t.cc
114113

115-
# g++ generates the notes files in the current directory. The documentation
116-
# (https://gcc.gnu.org/onlinedocs/gcc/Gcov-Data-Files.html#Gcov-Data-Files)
117-
# says they are placed in the same directory as the object file, but they
118-
# are not. Therefore we move them in the same directory.
119-
agcno=$(ls *a.gcno)
120-
tgcno=$(ls *t.gcno)
121-
mv $agcno coverage_srcs/$agcno
122-
mv $tgcno coverage_srcs/$tgcno
114+
# Prior to version 11, g++ generates the notes files in the current directory
115+
# instead of next to the object file despite the documentation indicating otherwise:
116+
# https://gcc.gnu.org/onlinedocs/gcc/Gcov-Data-Files.html#Gcov-Data-Files
117+
# This is fixed in g++ 11 so we have to handle both cases.
118+
119+
local not_found=0
120+
ls coverage_srcs/*a.gcno > /dev/null 2>&1 || not_found=$?
121+
if [[ $not_found -ne 0 ]]; then
122+
agcno=$(ls *a.gcno)
123+
tgcno=$(ls *t.gcno)
124+
agcda=$(ls *a.gcda)
125+
tgcda=$(ls *t.gcda)
126+
mv $agcno coverage_srcs/$agcno
127+
mv $tgcno coverage_srcs/$tgcno
128+
mv $agcda coverage_srcs/$agcda
129+
mv $tgcda coverage_srcs/$tgcda
130+
fi
131+
agcno=$(ls coverage_srcs/*a.gcno)
132+
tgcno=$(ls coverage_srcs/*t.gcno)
133+
agcda=$(ls coverage_srcs/*a.gcda)
134+
tgcda=$(ls coverage_srcs/*t.gcda)
135+
# Even though gcov expects the gcda files to be next to the gcno files,
136+
# during Bazel execution this will not be the case. collect_cc_coverage.sh
137+
# expects them to be in the COVERAGE_DIR and will move the gcno files itself.
138+
# We cannot use -fprofile-dir during compilation because this causes the
139+
# filenames to undergo mangling; see
140+
# https://github.com/bazelbuild/bazel/issues/16229
141+
mv $agcda "$COVERAGE_DIR_VAR/$agcda"
142+
mv $tgcda "$COVERAGE_DIR_VAR/$tgcda"
123143

124144
# All generated .gcno files need to be in the manifest otherwise
125145
# the coverage report will be incomplete.
126-
echo "coverage_srcs/$tgcno" >> "$COVERAGE_MANIFEST_VAR"
127-
echo "coverage_srcs/$agcno" >> "$COVERAGE_MANIFEST_VAR"
146+
echo "$tgcno" >> "$COVERAGE_MANIFEST_VAR"
147+
echo "$agcno" >> "$COVERAGE_MANIFEST_VAR"
128148
}
129149

130150
# Generates and executes an instrumented binary:
@@ -138,17 +158,7 @@ EOF
138158
# - path_to_binary destination of the binary produced by g++
139159
function generate_and_execute_instrumented_binary() {
140160
local path_to_binary="${1}"; shift
141-
local gcda_directory="${1}"; shift
142-
# -fprofile-arcs Instruments $path_to_binary. During execution the binary
143-
# records code coverage information.
144-
# -ftest-coverage Produces a notes (.gcno) file that coverage utilities
145-
# (e.g. gcov, lcov) can use to show a coverage report.
146-
# -fprofile-dir Sets the directory where the profile data (gcda) appears.
147-
#
148-
# The profile data files need to be at a specific location where the C++
149-
# coverage scripts expects them to be ($COVERAGE_DIR/path/to/sources/).
150-
g++ -fprofile-arcs -ftest-coverage \
151-
-fprofile-dir="$gcda_directory" \
161+
g++ -coverage \
152162
"$@" -o "$path_to_binary" \
153163
|| fail "Couldn't produce the instrumented binary for $@ \
154164
with path_to_binary $path_to_binary"
@@ -274,6 +284,7 @@ EOF
274284

275285

276286
function test_cc_test_coverage_gcov() {
287+
local -r gcov_location=$(which gcov)
277288
"$gcov_location" -version | grep "LLVM" && \
278289
echo "gcov LLVM version not supported. Skipping test." && return
279290
# gcov -v | grep "gcov" outputs a line that looks like this:
@@ -316,8 +327,16 @@ function test_cc_test_coverage_gcov() {
316327
fail "Number of lines in C++ gcov coverage output file is "\
317328
"$nr_lines and different than 17"
318329
else
319-
agcda=$(ls $COVERAGE_DIR_VAR/*a.gcda.gcov.json.gz)
320-
tgcda=$(ls $COVERAGE_DIR_VAR/*t.gcda.gcov.json.gz)
330+
# There may or may not be "gcda" in the extension.
331+
local not_found=0
332+
ls $COVERAGE_DIR_VAR/*.gcda.gcov.json.gz > /dev/null 2>&1 || not_found=$?
333+
if [[ $not_found -ne 0 ]]; then
334+
agcda=$(ls $COVERAGE_DIR_VAR/*a.gcov.json.gz)
335+
tgcda=$(ls $COVERAGE_DIR_VAR/*t.gcov.json.gz)
336+
else
337+
agcda=$(ls $COVERAGE_DIR_VAR/*a.gcda.gcov.json.gz)
338+
tgcda=$(ls $COVERAGE_DIR_VAR/*t.gcda.gcov.json.gz)
339+
fi
321340
output_file_json="output_file.json"
322341
zcat $agcda $tgcda > $output_file_json
323342

@@ -332,4 +351,4 @@ function test_cc_test_coverage_gcov() {
332351
fi
333352
}
334353

335-
run_suite "Testing tools/test/collect_cc_coverage.sh"
354+
run_suite "Testing tools/test/collect_cc_coverage.sh"

0 commit comments

Comments
 (0)