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: unassig...@gcc.gnu.org ReportedBy: lieutenantfe...@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