I want to generate a coverage report for my github repo, it's a big C++ project built with CMake.
I add --coverage(equals to -fprofile-arcs -ftest-coverage) option to g++ build and link arguments in my CMakeLists.txt, and I use gcov to generate code coverage data and upload the data to codecov.io.
These automated builds and tests are done in my Jenkins CI. The related code of Jenkins's execute shell is here:
cmake -DCODE_COVERAGE=ON -Dasan=OFF -DNEBULA_ASAN_PRELOAD= ..
make -j8
ctest -j8
#generate code coverage report and upload it to codecov.io
TEST_FILES=$(find . -name '*.cpp.o')
#gcov -abcr $TEST_FILES
for test_file in $TEST_FILES; do gcov -abcr $test_file; done
curl -s https://codecov.io/bash | bash -s - -t c85ebdca-ec7c-4301-a6ed-7967cf175db5
When Jenkins excutes make -j8 and ctest -j8, and gcov -abcr $test_file I do get the related .gcno files, .gcda files, and gcov files. But when Jenkins excutes curl -s https://codecov.io/bash | bash -s - -t c85ebdca-ec7c-4301-a6ed-7967cf175db5 to upload the data files to codecov, the output seems strange. I see a lot of similar errors like:
ExecutionPlan.gcno:'_ZNK6nebula4cpp29ValueType8get_typeEv' has arcs to entry block
ExecutionPlan.gcno:'_ZNK6nebula4cpp29ValueType8get_typeEv' has arcs from exit block
And the -r option of gcov seems doesn't work because I also get a lot of coverage report of system header files.
And at the last the Jenkins tells me the build fails, so I can't see the coverage report in codecov.
Ps:
The source cpp files is not in the same directory with the .cpp.o(CMake's default C++ object type is .cpp.o not .o) files. And I do the above excute shell's code in the build directory, the .gcno, .gcda, and .gcov files are generated in the same directory.
Bucause the CMake's default object type is .cpp.o, the gcno and gcda files type generated is .cpp.gcno and .cpp.gcdas. So I use gcov filename.cpp.o insead of gcov filename.cpp which will tell me couldn't open filename.gcno errors.
I do some experiments to find the reason of errors. I find when I give gcov one input file like gcov 1.cpp.o, I will get no has arcs from exit block errors, but when I give gcov more than one input files like gcov 1.cpp.o 2.cpp.o , I get the errors of has arcs from exit block. I think a probably reason is about combing multiple gcov files.
Related
I am writting a small C++ static library. Within GitHub Actions I have a "unit test" workflow which compiles and runs a test program and the code coverage is submitted to the Codecov service afterwards. It runs: g++ test.cpp library/library.cpp --coverage -o test, then ./test, followed by gcov -o . test.cpp. In the next step the results are submitted to my Codecov account with a standard bash <(curl -s https://codecov.io/bash) (having a CODECOV_TOKEN set as an env. variable). Everything works fine up to this point.
However, in the coverage I see reports for both .cpp and .h files inslide the library directory but also a coverage of the test.cpp. I am not interested in the coverage of my test code and it is skewing the statistics. Is there any way to submit only coverage reports of the library files?
There is no easy way to exclude files at the gcov level, but I solved the issue by restricting the codecov submission: https://docs.codecov.io/docs/ignoring-paths
I have lcov report of my c++ code on each of my integration tests. I would like to merge it in one global report, I know it is possible but it only adds up hit lines count. I wish to have the information about which test hit each line.
I dunno if there is a way instead of writing a script myself.
Thanks
You can use geninfo in combination with lcov to achieve something similar.
If you have both .gcno and .gcda files available then first we will need to generate .info files.
To generate .info files use :
geninfo "path for .gcda files" -b "path for the source files" -o ./coverage1.info
So this will generate .info for your first test. Similarly, generate .info for all of your tests.
Now you can use lcov to combine these info files and get a combined report. To do that use:
lcov --add-tracefile coverage1.info -a coverage2.info ...coverageN -o merged.info
Now you have combined .info file and you can use genhtml to generate a HTML report for better view.
genhtml merged.info -o CodeCoverage
Problem:
I'm using the following flags to generate the code coverage of my Qt application (.pro file):
QMAKE_CXXFLAGS += --coverage
QMAKE_LFLAGS += --coverage
The code coverage is correctly generated, the problem is that if I want to run only one test function/class (and the GCDA files were already created) I get the following error message:
profiling: /Users/user/.../build-myapp/myclass.gcda: cannot merge previous GCDA file: corrupt arc tag (0x00000000)
Note that the error message is shown for each GCDA file. Also, note that it doesn't seem to affect the test cases.
Workaround:
As explained here, it "is a result of the build tools failing to merge current results into the existing .gcda coverage files". As answered in the question, an option is to delete the GCDA files before running the tests. For example, by adding the following command in the build phase:
find . -name "*.gcda" -print0 | xargs -0 rm
Question:
My problem is that I don't want to delete the old GCDA files every time I run the test cases. As I'm running only one test function/class, I want to keep the old GCDA files as they are, and only merge the GCDA file related to the current class. As I manually checked, it is already being done because only the coverage of my current class is updated, and the old coverages remain the same.
So, is there a command to just ignore (don't show) the error messages related to the GCDA merging problems? Or even better, a command to only update the GCDA files related to the current test class?
Note: I'm using Qt 5.3.2 on macOS Sierra with Clang.
Related questions:
Code coverage warnings spam output
How to merge multiple versions of gcda files?
.gcda files don't merge on multiple runs
When you compile with profiling, the results of each run are stored in a file that ends with .gcda.
The error appears when your existing .gcda file is in a different format than the current program that just finished running.
This happened to me when I had run a Linux version of my executable, then recompiled for MacOS and ran it. The MacOS program saw the existing .gcda file and generated pages of errors.
Eliminate the errors by removing the existing .gcda file.
I came across the same problem. My solution is:
There is a general Test.pro project which uses SUBDIRS to include every test project as subproject.
In each test subproject I have the following line
QMAKE_POST_LINK = rm -f "*.gcda"
This deletes the *.gcda files only for the subproject which was just relinked. Unmodified projects keep their *.gcda files.
I am tring to generate coverage report by gcovr. But got invalid report or 0% coverage report
My project structure look like.
Myproject:
src-----where my all source files stored
testCases---Where my all source files stored
RunTestCases--From where I run my testCases
First I build src by scons from src directory.
Then I build TestCases from testCases directory by scons
Then I run test cases form RunTestCases directory
Last I generated coverage report for source file from src directory
Everthings is ok. My test Cases got pass but coverage report is 0%
I used below command to generated coverage report
gcovr -r . -e "include.*" --html --html-details -o $result_dir/result.html
Please help me..
I'm doing unit testing for device drivers for that i need to use gcov and lcov tools to generate reports.I compiled my code in native machine and the .gcno files are generated perfectly.Then i executed my output file in a arm based board and the gcda files also generated correctly.Then i have taken those files to my native and i generated .gcov files.
But when i use lcov to that files it is showing errors like "negative length in /usr/src/geninfo line no 2414".
1.So,For this what i need to do.?.
2.And one more question is I'm using "arm-none-gnueabi-" toolchain(2011.03) for this it has gcov seperately but lcov is not present in the executables.Is it possible to use lcov.?.If yes how to use.?..Thanks in advance.
Once you are able to generate the .gcda & .gcno files correctly, you need lcov tool to capture the code coverage. Here you should cross compile your lcov tool and add it into the file system.
I am working on similar kind of task, where i am trying to capture the coverage for ARMv7 based system. I have used yocto for the build framework. In yocto, meta-oe layer provides the support of the lcov. you can add it into the conf/local.conf file by adding following line into the configuration file.
CORE_IMAGE_EXTRA_INSTALL += "lcov"
after following all steps of your build, you will have the lcov tool on to the target board in /bin directory. Refer the lcov man page
You can use below command to generate the coverage files.
lcov --capture --directory <path-to-your-generated-files-dir> --gcov-tool /usr/bin/arm-linux-gnueabi-gcov --output-file <file_name>
Above command will generate a file, if your target board does not have enough capability then you can copy the generated file into your build system.
At the build system,
you can execute below command to generate the HTML output with the exact coverage details,
genhtml <path_to_generated_file> --output-directory <out_dir>
Refer below links for more details about the GCOV & LCOV integration.
1. How to use GCOV & LCOV
GCOV in linux kernel