Reputation: 41
I'm trying to generate a code coverage report for some individually compiled tests on Ubuntu 18.04 and running into a strange problem. If I compile with clang 5.0.0 and pass it the -fprofile-instr-generate
and -fcoverage-mapping
flags, it does actually work and running the compiled test causes it to spit out a .profraw file I can process with llvm-cov and turn into a coverage report. However, the only coverage that it seems to track is that of the test harness and any code directly included via #include
, completely ignoring code that was linked. As an example, if a header file is included via #include
it will show coverage for that file but not for the associated .c file that the actual called code is stored in. From some research it seemed like the solution was to add -fprofile-instr-generate
to the linking step as well, but this didn't change the result at all. It's terrible practice (and unsustainable) to manually #include
any files I want to see the coverage of, but I don't see another option that lets me view the coverage of linked code (specifically, the coverage of the function I'm calling in the test harness and anything that function calls). Is this a problem that other people have had, and does anyone know how to solve it?
Upvotes: 1
Views: 4838
Reputation: 105
I ran into this problem. It turns out that I need --object
option for each binary.
I got the report that includes both reports on library and executable with this command:
llvm-cov report --object mylib.so --object my_executable --instr-profile somewhere.profdata
Upvotes: 1
Reputation: 41
Fixed my own issue! Turns out the test was linking with a .so
shared library that contained my target functions, so the problem was solved by doing two things. First, instrumenting the step that compiled the .o
objects into the shared library allowed for visibility into the target functions. Second, using llvm-cov show/report with the .profdata
generated by the test and passing it the shared library as the binary instead of the test binary allowed for it to report coverage information for the target functions. Lesson learned, always check if your instrumented test is importing shared libraries and make sure your shared libraries are being compiled with the right flags to instrument them!
Upvotes: 1
Reputation: 12673
You need to add the flags when compiling the units to be covered. The compiler will instrument the object code, that means it adds the code that counts "passing control flow" to say it simply.
This means that you need to compile the unit-under-test again before you link it to your test harness. That test harness in contrary does not need to be compiled with the flags, because you are not interested in its coverage most probably.
There is no need to include the unit's source into another source. How you found, this is too hard to maintain.
However, the linker needs the flags, too.
For the production code you will compile your units without the flags.
Upvotes: 2