[Bug gcov-profile/48463] New: gcov generating bad function coverage

lieutenantfeist at hotmail dot de gcc-bugzilla@gcc.gnu.org
Tue Apr 5 15:28:00 GMT 2011


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48463

           Summary: gcov generating bad function coverage
           Product: gcc
           Version: 4.3.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: gcov-profile
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: lieutenantfeist@hotmail.de


Created attachment 23882
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=23882
1.png, 2.png, src/ (has 3 source files)

Gcov is generating a lot of useless output when it comes to function coverage.
The problem really came to our attention when looking at classes with virtual
destructors like the one in the following class example:

[code]
class ClassA
{
public:
        ClassA();
        virtual ~ClassA();
};

class ClassB : public ClassA
{
public:
        ClassB();
        ~ClassB();
};
[/code]

The list of function names then contains three destructors for ClassA (two of
which are apparently not called, one which is) and three destructors for ClassB
(two of which are apparently not called, one which is). They all have the same
signature. When disabling then genhtml option --demangle-cpp, or by viewing the
.gcov files, you can see, that each of these destructors (of ClassA for
example) has a different name. Example (excerpt of gcov file for classA.cpp):

Function '_ZN6ClassAD0Ev'
Lines executed:0.00% of 3
Branches executed:0.00% of 2
Taken at least once:0.00% of 2
Calls executed:0.00% of 3

Function '_ZN6ClassAD1Ev'
No executable lines
Branches executed:0.00% of 2
Taken at least once:0.00% of 2
Calls executed:0.00% of 3

Function '_ZN6ClassAD2Ev'
No executable lines
Branches executed:100.00% of 2
Taken at least once:50.00% of 2
Calls executed:66.67% of 3

The mangled names differ only in the parts: D0, D1, D2. It's odd that one
destructor apparently has 3 executable lines (in the attached source, you can
see it's only one line), and that the two others have no executable lines, yet
they have branches that can be covered. 
These "IDs" 'D0', 'D1', 'D2' are given to the mangled function names by the gcc
compiler, yet I am unsure of what the difference is supposed to be. 
Nevertheless, it isn't really of interest to the person analyzing the coverage
of his code, what gcc generates in the background. Only those desctructors,
that the programmer can actually see in HIS code, should show up in the list of
covered (or not covered) functions. 
This goes for the other functions that show up in the example's list as well:
global destructors keyed to _ZN6ClassAC2Ev 
global constructors keyed to _ZN6ClassAC2Ev
__static_initialization_and_destruction_0(int, int)

It leads to wrong numbers for the function and branch coverage of what you
really want to see.

To reproduce:

I wrote a two classes: ClassA and ClassB. ClassA has a public constructor (no
args, just prints something) and a public virtual destructor (no args, just
prints something). ClassB inherits from ClassA (publicly) and has a public
constructor (no args, just prints something) and a public destructor (no args,
just prints something). The main file just creates an instance of ClassB,
stores it in a pointer to ClassA and calls delete on that pointer variable. 

The source files were compiled using:
g++ -fprofile-arcs -ftest-coverage -o prog main.cpp classA.cpp

Then ./prog was run once.

A .info file was generated using lcov (version 1.9) in the following command:
lcov -d . -c -f -o NewInfo.info

The final html overview was generated using genhtml (also version 1.9) in the
following command:
genhtml --demangle-cpp --prefix . -o html/ NewInfo.info 

Alternatively, to reproduce, you can also use the attached source files. The
attachment also include two pictures, displaying a listing of all the functions
that have apparently been covered or not covered.

Hope this info helps solve the problem. 
Chris



More information about the Gcc-bugs mailing list