7

I'm successfully using gcov in my project:

  • I can build my project with gcov flags: -fprofile-arcs -ftest-coverage
  • I link with the -lgcov option
  • I run my unit test program and lots of gcda and gcno files are produced.
  • I run gcov lots of times and lots of gcov files are produced.
  • I summarise the results and produce a list of lines like this:
    • #####: 42: virtual double run_time() const { return 0; }

I then go 'doh!' and write a test which calls that missing method.

The above example line is quite easy to diagnose - gcov told me the exact method I was not calling.

I've also had an example of a copy constructor being flagged by gcov, but I'm able to step through it using my Visual Studio debugger. The solution there was to realise that gcov was suffering from RVO which elided the copy, but writing a test which forced a copy fixed that.

I have a couple of other examples which I cannot figure out:

1.
File.cpp
#####: 78:}

gcov seems to be flagging the close brace of a namespace which is the last line of a file.

2.
File.h
#####: 33:  class FooBase: public IResult {

What is gcov trying to tell me here? I can't think of a call to make here.
Update 1: I've detected that FooBase has a default constructor, which if only 'called' by a subclass is not the same as calling it by instantiating it, as far as gcov is concerned.

Update 2: I've been using djgpp/gcc 4.4.4 which produced the above results. However, by using MinGW/gcc 4.5.2 the 'aberrations' disappear and with a little more work I've been able to get to 100% line coverage.

Please write your answers with either a single tip for the unwary gcov user, or an answer to one of my examples.

quamrana
  • 37,849
  • 12
  • 53
  • 71

3 Answers3

2

The line you talk about is going to be inlined in release mode. That means the line itself will never be counted (although frankly the increment of the counter could have been moved to the place where the function gets inlined... but g++ does not do that yet.)

In order to fix the problem add -g to your g++ command line to keep all debug. You probably also want to make sure you defined -D_DEBUG. Actually, the documentation generally tells you to use -g.

Finally, you want to avoid optimizations with -O0.

On my end, I like to also use -fprofile-arcs and -ftest-coverage.

As mentioned in a comment in another answer, using -fno-elide-constructors and -fno-default-inline may also help with coverage of "missing" constructors and inline functions.

In regard to the opening brace being flagged, g++ is likely to create a constructor (possibly the copy constructor) and show it on that first class declaration line. There may be other compiler specific functions created like that and at times it is just impossible to hit them without extremely complicated test cases... I encounter that problem all the time.

As suggested by climbatizer, you could use lcov. That gives you HTML as output with easy to read tables that you can browse quickly. I have such an example here:

http://lcov.csspp.org/csspp-1.0.5/lib/index.html

As we can see, the library is 100% covered by all the tests. But somehow the assembler.cpp file says that one function is not covered. I have no idea which function that is though since 100% of the code I wrote is covered... So I just ignore such.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
  • Has time provided any insight into that "missing function" in `assembler.cpp`? I've got a similar situation except it happens on every single one of my interface headers, so it looks like I'm missing lots of functions, but I can't actually find them... – dwanderson Feb 24 '16 at 16:45
  • So far, that part has not been ameliorated from what I've seen. – Alexis Wilke Feb 24 '16 at 23:17
  • 2
    In the generated lcov HTML report you can see the methods/functions not covered. e.g.: [http://lcov.csspp.org/csspp-1.0.5/lib/assembler.cpp.func.html](http://lcov.csspp.org/csspp-1.0.5/lib/assembler.cpp.func.html). But somehow two different symbols are exported for the virtual destructor. – AmeyaVS May 10 '17 at 08:46
  • 1
    @AmeyaVS Interesting, I had never clicked on that link! That makes it a lot clearer. – Alexis Wilke May 10 '17 at 18:11
2

As it is said in gcov.c

  /* For lines which don't exist in the .bb file, print '-' before
     the source line.  For lines which exist but were never
     executed, print '#####' before the source line.  Otherwise,
     print the execution count before the source line.  There are
     16 spaces of indentation added before the source line so that
     tabs won't be messed up.  */

I suggest you use a debug builds for gcov and for VS when trying to get a coverage.

osgx
  • 90,338
  • 53
  • 357
  • 513
  • What constitutes a debug build for gcc? – quamrana May 26 '11 at 20:46
  • 1
    Optimizations disabled `-O0`, debug information added `-g`. Also, there are some `-f...`-styled optimization options, which should be turned off too. – osgx May 26 '11 at 21:06
  • I've now used '-g','-O','--coverage','-fno-elide-constructors','-fno-default-inline' and I have more lines marked as not covered! (That is -g and -O are extra) – quamrana May 26 '11 at 21:25
  • not `-O` but `-O0`. -O is a -O1, the first level of optimisation. You should use zero level or disable optimisation. – osgx May 26 '11 at 23:15
1

Recently I've been using cmake+"make Experimental"+lcov. I highly recommend that combination. Even if not using cmake, take a look at lcov.

climbatizer
  • 121
  • 1
  • 2