Getting Useful Gcov Results for Header-Only Libraries

Getting useful GCov results for header-only libraries

Apart from the usual flags to GCC controlling inlining;

--coverage -fno-inline -fno-inline-small-functions -fno-default-inline

You can instantiate your template classes at the top of your unit test files;

template class std::map<std::string, std::string>;

This will generate code for every method in that template class making the coverage tools work perfectly.

Also, make sure that you initialise your *.gcno files (so for lcov)

lcov -c -i -b ${ROOT} -d . -o Coverage.baseline
<run your tests here>
lcov -c -d . -b ${ROOT} -o Coverage.out
lcov -a Coverage.baseline -a Coverage.out -o Coverage.combined
genhtml Coverage.combined -o HTML

gcov reporting wrong result for header only class

As it seems the problem wasn't the fact that my class is header only but that I called gcov with

gcov unittest_myclass.cpp -o .obj/

if I instead run it with

gcov *.cpp -o .obj/

it reports

File '../include/myclass.h'
Lines executed:95.56% of 248
Creating 'myclass.h.gcov'

and the resulting myclass.h.gcov file looks a lot more than what I expected.

How to get correct code coverage for member functions in header files

The methods with 0% coverage were inline methods in a header.

I did compile the library I was testing with gcc --coverage which instruments the machine code to collect coverage. However, I did not instrument the test executable since I am not interested in the coverage of the tests themselves. So the test executable contained code for the inline methods without instrumenting them.

As a result, the methods were known to gcov but no coverage was collected (only the non-instrumented inline version was executed).

The solution:

  • also instrument the tests by using the --coverage compiler flag
  • filter out the unwanted coverage data of the tests with the -e/--exclude gcovr option

How to get gcov results for included C/CPP files

If I compile test with --coverage instead of -lgcov it does generate a test.gcda. I thought at first this was not what I wanted since I'm looking for coverage in lib.c

But if I run both testlib and test and then use gcov on all the files together, it combines the coverage data properly:

gcov lib.gcda lib.gcno test.gcda test.gcno

And this yields lib.c.gcov with code coverage from both test runs.

How can I get more accurate results from gcov?

As suggested in the comment by Mat, the option -fno-elide-constructors fixes this problem.

This answer was posted to get this already ancient question closed. If Mat posts an answer, I'll delete this and switch the accept to that.

Generating test coverage of C++ static library as called by separate test classes

From the ld manual

--whole-archive
For each archive mentioned on the command line after the --whole-archive option, include every object file in the archive
in the link, rather than searching the archive for the required object
files.

So link your static-library into your test using --whole-archive, which will result in your test binary having the entire static-library, and give gcov visibility of the entire code



Related Topics



Leave a reply



Submit