gcov warning: merge mismatch for summaries

mikelong picture mikelong · Apr 7, 2010 · Viewed 11.8k times · Source

Can anyone tell me what the gcov message "Merge mismatch for summaries" means? I have found the message in the gcc source here:

http://www.opensource.apple.com/source/gcc/gcc-5646/gcc/libgcov.c

It seems to be a sanity check that the tags in the .gcda files match, but I'm not sure. Anyone know how to work around this?

Answer

richq picture richq · Apr 20, 2010

This happens when one of the objects you're linking into an executable changes significantly. For example it gains or loses some lines of profilable code.

The minimal case to produce the error is with 2 source files. Here are 2 example source files called main.c...

/* main.c */
int do_stuff(int value);

int main(int argc, const char *argv[])
{
    do_stuff(argc);
    return 0;
}

and stuff.c

/* stuff.c */
#include <stdio.h>

#if 0
int more_stuff()
{
    int i;
    i = 0;
    return i;
}
#endif

int do_stuff(int value)
{
    if (value > 1) {
        printf("Value > 1\n");
    } else {
        printf("Value <= 1\n");
    }
    return 0;
}

What they do isn't important. To build them, here is a simple Makefile:

CFLAGS := -fprofile-arcs -ftest-coverage
LDFLAGS := -fprofile-arcs -ftest-coverage

testexe: main.o stuff.o
    $(CC) $(LDFLAGS) -o $@ $^

The Makefile is set up so that the compilation is main.c -> main.o, stuff.c -> stuff.o and finally stuff.o + main.o -> testexe. If we compile and link those C files with the -fprofile-arcs -ftest-coverage options then the executable file has profiling. Run that execuatable and you'll get 2 output files, main.gcda and stuff.gcda. So far so good.

Now change the line #if 0 to #if 1. The Makefile should cause just stuff.c to recompile, and the executable to relink. Next time you the test executable gets run you'll get the "Merge mismatch" message for the main.gcda file. The stuff.gcda file is not affected since its object file has been recreated with all the new summary information. If you recompile main.c and relink the executable, then the error message goes away.

So what can be done? I'd love to know! At the moment I run find . -name '*.gcda' | xargs rm whenever I need to re-check coverage, which is not really ideal. Another solution would be to recompile everything when using profiling "just in case", but that seems like overkill.