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