2

The question may seem weird.

I tried to use GCOV/LCOV for my small project and practiced with simple code before applying it. While practicing it, I encountered an error that I had no idea how to solve.

The report created by LCOV showed that the functions declared before the unused function inside the source code file are reported as unused functions. In contrast, the functions displayed correct outputs when the binary file was executed.

The followings are actual codes used for the practice.

# makefile
CC  = g++
CFLAG = -g -fPIC -fprofile-arcs -ftest-coverage
RM  = rm -rf

main.o : main.cpp
    $(CC) $(CFLAG) -c -Wall -Werror main.cpp

dummy_class.o : dummy_class.cpp
    $(CC) $(CFLAG) -c -Wall -Werror dummy_class.cpp

build : main.o dummy_class.o
    $(CC) $(CFLAG) -o main main.o dummy_class.o

gcov: main.cpp dummy_class.cpp
    gcov main.cpp dummy_class.cpp

coverage.info: gcov
    lcov --capture --directory . --output-file coverage.info
    lcov -remove coverage.info "/usr/include/*" "/usr/local/include/*" --output-file coverage.info

report : coverage.info
    genhtml coverage.info --output-directory ./out

clean :
    rm -f main
    rm -f  *.o *.so *.gcno *.gcda *.gcov coverage.info 
    rm -r out

do :
    make build
    ./main
    make report
// dummy_class.hpp
#pragma once

void func_even_case(void);

void func_odd_case(void);

void func_not_reachable(void);

void dummy(void);

void dummy2(void);

void dummy3(void);
// dummy_class.cpp
#include <iostream>
#include <vector>
#include "dummy_class.hpp"

void func_even_case(void)
{
    std::cout << "This is even case" << std::endl;
}

void func_odd_case(void)
{
    std::cout << "This is odd case" << std::endl;
}

void func_not_reachable(void)
{
    std::cout << "This is not reachable" << std::endl;
}

void dummy(void)
{
    std::cout << "This is dummy1." << std::endl;
}

void dummy2(void)
{
    std::cout << "This is dummy2." << std::endl;
}

void dummy3(void)
{
    std::cout << "This is dummy3." << std::endl;
}

// main.cpp
#include <iostream>
#include "dummy_class.hpp"

int main(void)
{
    for (int i = 0; i < 10; ++i)
    {
        if (i % 2 == 0)
        {
            func_even_case();
        }
        else if (i % 2 != 0)
        {
            func_odd_case();
        }
        else
        {
            func_not_reachable();
        }
    }

    func_not_reachable();

    dummy();
    dummy2();
    dummy3();

    return 0;
}

When func_not_reachable() is placed outside the for-loop, the report returns

Overall coverage rate:
  lines......: 96.7% (29 of 30 lines)
  functions..: 100.0% (7 of 7 functions)

and the result is expected.

When func_not_reachable() is removed, the expected result was

Overall coverage rate:
  lines......: 86.5% (25 of 29 lines)
  functions..: 100.0% (6 of 7 functions)

since func_not_reachable() is the one that will not be executed.

However, the actual result was

Overall coverage rate:
  lines......: 65.5% (19 of 29 lines)
  functions..: 57.1% (4 of 7 functions)

If the dummy_class.cpp is modified as following

#include <iostream>
#include <vector>
#include "dummy_class.hpp"

void func_even_case(void)
{
    std::cout << "This is even case" << std::endl;
}

void func_odd_case(void)
{
    std::cout << "This is odd case" << std::endl;
}

void dummy(void)
{
    std::cout << "This is dummy1." << std::endl;
}

void dummy2(void)
{
    std::cout << "This is dummy2." << std::endl;
}

void dummy3(void)
{
    std::cout << "This is dummy3." << std::endl;
}

// unused function declared at the end of the source code.
void func_not_reachable(void)
{
    std::cout << "This is not reachable" << std::endl;
}

The report result becomes follows.

Overall coverage rate:
  lines......: 34.5% (10 of 29 lines)
  functions..: 14.3% (1 of 7 functions)

I am sure I made errors while using GCOV and LCOV, but I cannot figure out where I made a mistake. Can someone tell me where I made a mistake?

The above code was executed on the following.

  • Ubuntu 20.04.4 LTS
  • g++ (Ubuntu 11.1.0-1ubuntu1~20.04) 11.1.0
  • gcov (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
  • lcov: LCOV version 1.14

1 Answers1

1

Find out the source of the problem.

The problem was related to the compiler (g++ 11.1.0) or gcov (9.3.0) I used.

The code coverage reported the correct result when the compiler changed from g++ to clang.

To ensure the problem is related to the specific version of the compiler (g++ 11.1.0), I upgraded the system from Ubuntu 20.04.4 LTS to Ubuntu 22.04.4 LTS.

The test condition became as follow

  • Ubuntu 22.04.4 LTS
  • g++ (Ubuntu 11.2.0-19ubuntu1) 11.2.0
  • gcov (Ubuntu 11.2.0-19ubuntu1) 11.2.0

After the update had been made, the code coverage reported the correct result with g++.