3

I have been using gcov to check code coverage. I now get a weird result, some functions are listed as not executed but the lines in the function is listed as executed.

lcov output:

  13           0 :     f<double>& operator*=(f<double>& lhs, const double& rhs)
  14             :     {
  15           9 :         // Some code...
  16           0 :         return lhs;
  17             :     }

gcov output:

#####:   13:    f<double>& operator*=(f<double>& lhs, const double& rhs)
    -:   14:    {
    9:   15:        // Some code...
#####:   16:        return lhs;
    -:   17:    }

How can the function be listed as NOT executed when the line(s) are? Is this possibly an artifact of GCC's optimization?

EDIT 1:

G++/gcov version: 4.9.2

lcov version: 1.11

EDIT 2:

Comping with -O2 yields the weird behavior. However, compiling with -O1 changes the #### to 9

Jonas
  • 6,915
  • 8
  • 35
  • 53
  • Which version of gcc/gcov are you running? And what command line options do you use for gcov? – quamrana Feb 01 '16 at 09:28
  • 1
    Could this be a result of inlining? – mindriot Feb 01 '16 at 09:33
  • When I run gcov I get a different file format: `#####: 89: uint8_t index = dbSize - 1;` So it is `#####` which indicates not executed followed by the line number, then the text of the line. – quamrana Feb 01 '16 at 09:35
  • @quamrana g++/gcov 4.9.2 and I used lgov to generate the output. – Jonas Feb 01 '16 at 09:38
  • Can you run an experiment and define a whole function which is never called to see the difference to above? – quamrana Feb 01 '16 at 09:39
  • @quamrana If a function is never called I believe the linker will remove it. And thus, the `x :`, where `x` is 0 or 9 in this case, would just not have an `x`. – Jonas Feb 01 '16 at 09:44
  • Well, you can take the address of a function without calling it. That will keep the linker happy. – quamrana Feb 01 '16 at 10:07

2 Answers2

2

The zero simply indicates that gcov had no data for the line of code. That could happen just because there's no convenient way for gcc to instrument — modify your program to add the counters (as in the entry to a function). For instance, if the optimizer removes or combines similar statements in nearby functions, there is nothing to count.

According to the manual:

The format is

 execution_count:line_number:source line text

Additional block information may succeed each line, when requested by command line option. The execution_count is ‘-’ for lines containing no code. Unexecuted lines are marked ‘#####’ or ‘====’, depending on whether they are reachable by non-exceptional paths or only exceptional paths such as C++ exception handlers, respectively.

Further reading:

Community
  • 1
  • 1
Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
2

You should run gcov on unoptimised code. This will give you output, perhaps interpreted by lcov, which will assure you that all lines have run.

You can then compile with optimisations on for a release version.

quamrana
  • 37,849
  • 12
  • 53
  • 71