Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code coverage missing a branch if a function takes reference parameter

I have a following function which takes a reference parameter:

#include <iostream>

class A { static void TestA(const int &y) };

void A::TestA(const int &y) { std::cout << y; }

int main()
{
   A::TestA(2);
   return 0;
}

In my (lcov) code coverage with google unit tests, it is saying missing a branch with TestA() function, and symbols list have a stack_chk_fail symbol added. If I change the function parameter to non-reference then coverage is 100%.

I am using g++ compiler.

Am I missing anything ?

Thanks

like image 416
Dinesh Kumar Govinda Avatar asked Jan 29 '19 09:01

Dinesh Kumar Govinda


People also ask

What is an example of branch coverage in Python?

For example, in the above code if value sets (2, 3), (4, 2), (1, 1) are used then Branch Coverage would be 100%. When data set (2, 3) is used then (b > a) and the first ‘If’ branch gets executed.

What is the use of base branch coverage?

Branch Coverage is a white box testing method in which every outcome from a code module (statement or loop) is tested. The purpose of branch coverage is to ensure that each decision condition from every branch is executed at least once. It helps to measure fractions of independent code segments and to find out sections having no branches.

What is branch coverage in C++ example?

In the branch coverage, every outcome from a code module is tested. For example, if the outcomes are binary, you need to test both True and False outcomes. It helps you to ensure that every possible branch from each decision condition is executed at least a single time.

What is the purpose of function coverage in JavaScript?

Thus the purpose of Function Coverage is to ensure that we have each function called for. For example, in the source code above if our tests call the ‘Add’ function even once, then we would call this as a complete Function Coverage. In a source code wherever we have a condition, the result would be a Boolean value of either true or false.


1 Answers

The compiler inlines Test into main (because that's what a good compiler does). However, it also has to create code for Test because it has external linkage. Effectively, the code for the function exists twice: Once inlined into main and once in the code for Test that the linker can link with other compilation units.

If your compiler is bad with code attribution (in the debug symbols) for inlined functions (hello MSVC?) then your profiler will give you exactly the result you see: Executing the program does not lead to coverage for Test because no piece of the binary that is executed (i.e. main) has any line attribution into Test.

Changing the parameter type may affect inlining, but it's more likely that it changes how debug symbols are generated.

To verify this, step through the program with a debugger, with a breakpoint in Test. If that breakpoint is not hit when running main, your coverage tool won't see coverage for that line either. Or, if you really want, look into the debug symbols manually to see which lines have attribution. In Visual Studio you can also look at the disassembly while debugging (it will show the associated code lines).

For the above reasons you will generally get more reliable coverage results if you do coverage runs with debug builds (where e.g. inlining won't happen).

like image 115
Max Langhof Avatar answered Sep 30 '22 08:09

Max Langhof