This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug gcov/profile/24550] New: [4.x Regression] incorrect gcov code coverage output in 4.0 and 4.1


I have come across a number of cases where gcov 4.0 and beyond produces
incorrect output, causing false reporting of code coverage. For example, lines
beyond the end of the source file are marked as executable with zero coverage,
and some lines are marked with zero coverage even though they are directly
after a simple statement that was marked as being executed. These problems are
consistently reproducible on our platforms here.

I have confirmed that these problems did *not* occur in gcov 3.3.2, 3.3.3, or
3.4.3. I have further confirmed that they *do* occur in gcov 4.0.1 and gcov
4.1.0 (20051001). See below for more details on these versions.

Here's a simple test case that demonstrates the two problems I list above:

 % g++ -fprofile-arcs -ftest-coverage -c mytest.cpp -o mytest.o
 % g++ -fprofile-arcs -ftest-coverage mytest.o -o mytest
 % ./mytest
 % gcov mytest.cpp ; cat mytest.cpp.gcov

-------------- mytest.cpp ----------------
#include <string>

// this global string causes gcov to think there's executable lines
// beyond the end of the file, and that they have not been executed
std::string globalVar = "";

std::string
doSomething()
{
    // instantiating this string and calling a method on it causes the
    // 'return' line to be marked as having never been executed
    std::string localVar;
    localVar.size();
    return localVar;
}

int
main(int, char **)
{
    doSomething();
    return 0;
}
------------------------------------------

Under gcc/gcov 4.0.1 and 4.1.0 this produces:

        -:    0:Source:mytest.cpp
        -:    0:Graph:mytest.gcno
        -:    0:Data:mytest.gcda
        -:    0:Runs:1
        -:    0:Programs:1
        -:    1:#include <string>
        -:    2:
        -:    3:// this global string causes gcov to think there's executable
lines
        -:    4:// beyond the end of the file
        1:    5:std::string globalVar = "";
        -:    6:
        -:    7:std::string
        1:    8:doSomething()
        -:    9:{
        -:   10:    // instantiating this string and calling a method on it
causes the
        -:   11:    // 'return' line to be marked as executable but with zero
coverage
        1:   12:    std::string localVar;
        1:   13:    localVar.size();
    #####:   14:    return localVar;
        -:   15:}
        -:   16:
        -:   17:int
        1:   18:main(int, char **)
        -:   19:{
        1:   20:    doSomething();
        1:   21:    return 0;
        1:   22:}
        1:   23:/*EOF*/
    #####:   24:/*EOF*/

Note that the lines marked with "#####" mean that gcov thought that these were
executable lines of code, and that they where not actually executed. For
comparison, the same test case compiled using gcc/gcov 3.3.3 (20040412)
generates what I believe is more correct:

        -:    0:Source:mytest.cpp
        -:    0:Object:mytest.bb
        -:    1:#include <string>
        -:    2:
        -:    3:// this global string causes gcov to think there's executable
lines
        -:    4:// beyond the end of the file
        4:    5:std::string globalVar = "";
        -:    6:
        -:    7:std::string
        -:    8:doSomething()
        1:    9:{
        -:   10:    // instantiating this string and calling a method on it
causes the
        -:   11:    // 'return' line to be marked as executable but with zero
coverage
        1:   12:    std::string localVar;
        1:   13:    localVar.size();
        1:   14:    return localVar;
        -:   15:}
        -:   16:
        -:   17:int
        -:   18:main(int, char **)
        1:   19:{
        1:   20:    doSomething();
        1:   21:    return 0;
        1:   22:}

Here's the output of gcc -v for both of the 4.x versions that I have confirmed
these problems with:

Using built-in specs.
Target: x86_64-redhat-linux-gnu
Configured with: ../gcc-4.0.1/configure x86_64-redhat-linux-gnu
--prefix=/pixar/d2/sets/tools-30 --exec-prefix=/pixar/d2/sets/tools-30
--bindir=/pixar/d2/sets/tools-30/bin --sbindir=/pixar/d2/sets/tools-30/sbin
--sysconfdir=/pixar/d2/sets/tools-30/etc
--datadir=/pixar/d2/sets/tools-30/share
--includedir=/pixar/d2/sets/tools-30/include
--libdir=/pixar/d2/sets/tools-30/lib
--libexecdir=/pixar/d2/sets/tools-30/libexec
--localstatedir=/pixar/d2/sets/tools-30/var
--sharedstatedir=/pixar/d2/sets/tools-30/com
--mandir=/pixar/d2/sets/tools-30/man --infodir=/pixar/d2/sets/tools-30/info
--enable-version-specific-runtime-libs --enable-languages=c++,objc,f95
--enable-threads=posix --enable-shared
Thread model: posix
gcc version 4.0.1

Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: ../configure --prefix=/data/gcc/gcc-4.1-20051001
--enable-languages=c,c++,objc,obj-c++ --enable-version-specific-runtime-libs
Thread model: posix
gcc version 4.1.0 20051001 (experimental)


I suspect that this is something to do with allocating objects on the stack
(std::string in the example above, though I've tried this with other stl
container classes as well as other non-stl classes). For example, in the case
of coverage being produced beyond the end of the file for gcov 4.x, if I supply
the -b argument to gcov I get this at the end:

        1:   22:}
function _GLOBAL__I_globalVar called 1 returned 100% blocks executed 100%
        1:   23:/*EOF*/
call    0 returned 100%
function _GLOBAL__D_globalVar called 0 returned 0% blocks executed 0%
    #####:   24:/*EOF*/
call    0 never executed

Also, in the test case above, if I change the return value of doSomething() to
be an int instead of a std::string then the problem does not occur.

As another interesting datapoint, the above information is for running on a
Fedora Core 2 machine, but I get similar behavior using Apple's 4.0.0 compiler
that they ship with OSX 10.4 (Tiger) - However, in that case the /*EOF*/
coverage error on line 24 doe not occur. Only the one on line 14 occurs.
Perhaps that helps to isolate some part of this problem.

Please let me know if there is any more information that I can provide you to
help reproduce this problem. We are actively using gcov to quantify the code
coverage of our automated tests, so we'd love to see this problem get fixed and
I'm happy to help out as much as I can.

Cheers,

Martin.


-- 
           Summary: [4.x Regression] incorrect gcov code coverage output in
                    4.0 and 4.1
           Product: gcc
           Version: 4.1.0
            Status: UNCONFIRMED
          Severity: major
          Priority: P2
         Component: gcov/profile
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: reddy at pixar dot com
 GCC build triplet: x86_64-redhat-linux-gnu
  GCC host triplet: x86_64-redhat-linux-gnu
GCC target triplet: x86_64-redhat-linux-gnu


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]