-
Notifications
You must be signed in to change notification settings - Fork 12.4k
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
[gcov] source file location error due to miss current_working_directory in gcno file #121368
Comments
cc @MaskRay for visibility please feel free to share your thoughts |
llvm omitting the working directory helps with local determinism (https://blog.llvm.org/2019/11/deterministic-builds-with-clang-and-lld.html), but I agree that the directory is useful in some scenarios. In GCC, If we add the CWD to .gcno files, |
It seems non-trivial to remap the path. |
@MaskRay Thank you for your feedback. I agree that adding the CWD would break the local determinism. Implementing Do you have any suggestions on how to handle changes in the CWD? Specifically, how can we manage situations where the source files are in one directory and Error Output:
I have also added the test case in this commit. Here is the code Directory Structure:
Top-Level $ cat Makefile
all:
$(MAKE) -C src all
clean:
$(MAKE) -C src $@
$(MAKE) -C codecoverage $@
$ cat codecoverage/Makefile
all:
report: /usr/bin/lcov
lcov --directory .. --capture --output-file app.info
genhtml app.info -o html
clean:
rm -rf html *.info
.PHONY: report
$ cat src/Makefile
all: main
CFLAGS = --coverage
ifeq ($(shell $(CC) --version | grep "clang"),)
CC = gcc
else
CC = clang
GCC_VERSION := $(shell gcc --version | grep -oP '\d+\.\d+\.\d+' | head -1)
GCOV_VERSION_OPTION := ""
ifeq ($(GCC_VERSION), 10.2.1)
GCOV_VERSION_OPTION := -Xclang -coverage-version=B02A
else
$(echo Unsupported GCC version: $(GCC_VERSION))
endif
CFLAGS += $(GCOV_VERSION_OPTION)
endif
%: %.o
$(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
main.o: main.c
main: main.o
$(CC) $(CFLAGS) $^ -o main.bin.$(CC)
clean:
rm -rf *.o main.bin.* *.gcno *.gcda
// main.c
#include <stdio.h>
int main() {
printf("Hello World\n");
return 0;
} |
GCC 12 has significantly changed its gcov format.
I have implemented GCC compatible instrumentation up to 11 (e.g.
However, you can use Clang with lcov by default probes
then use
You could also migrate to https://clang.llvm.org/docs/SourceBasedCodeCoverage.html . It is based on Clang AST instead of debug info and more precise region information. The "current_working_directory" field in .gcno seems to be read by lcov: linux-test-project/lcov@75fbae1 If your source files are all in the same directory, perhaps you could invoke chdir then lcov.... |
Background
I am migrating an internal codebase from GCC to Clang and have encountered a discrepancy in code coverage reporting between the two compilers. Specifically, Clang fails to correctly locate source files when generating coverage data, whereas GCC operates as expected.
Reproducer
Building with GCC (Works Correctly)
GCC Version: 10.2.1
Building with Clang (Fails)
Clang Options:
-Xclang -coverage-version=B02A
to ensure compatibility of .gcno and .gcda filesif gcc is 9.2.1, use
-Xclang -coverage-version=A92A
Error Output
I also provide a demo repository that reproduces the issue using GitHub Actions (Ubuntu 22.04, GCC 11.4.0, lcov 1.14). You can view the workflow run here.
Root Cause
The issue arises because the
current_working_directory
field in the.gcno
file is empty when using Clang. GCC correctly sets this field, allowing gcov and related tools to resolve the relative paths of source files. Clang's omission leads to the inability of lcov and genhtml to locate the source files, resulting in coverage data processing errors.Relevant Code Snippet from LLVM:
llvm-project/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
Line 977 in f590963
Fix
tested with GCC 9.2.1 and GCC 10.2.1, lcov 1.0.0
Reference
The text was updated successfully, but these errors were encountered: