67

I'm trying to compile a simple app with gcov and getting the following link errors:

gcc AllTests.o CuTestTest.o CuTest.o -o TestTest
AllTests.o: In function `global constructors keyed to 0_RunAllTests':
/home/p7539c/cutest/AllTests.c:26: undefined reference to `__gcov_init'
AllTests.o:(.data+0x44): undefined reference to `__gcov_merge_add'
CuTestTest.o: In function `global constructors keyed to 0_TestCuStringNew':
/home/p7539c/cutest/CuTestTest.c:30: undefined reference to `__gcov_init'
CuTestTest.o:(.data+0x64): undefined reference to `__gcov_merge_add'
CuTest.o: In function `global constructors keyed to 0_CuStrAlloc':
/home/p7539c/cutest/CuTest.c:379: undefined reference to `__gcov_init'
CuTest.o:(.data+0x184): undefined reference to `__gcov_merge_add'
collect2: ld returned 1 exit status
make: *** [TestTest] Error 1

I can't seem to find the location of the missing symbols. gcov is present on the machine running gcc version 4.1.2

Any ideas? Thanks.

On Edit:

Everything seems to work fine when using gcov with an application that consists of one .c file. When I have multiple .c files (hence multiple .o files) I have the above problem.

The compile steps look like the following:

cc -fprofile-arcs -ftest-coverage -g   -c -o AllTests.o AllTests.c
cc -fprofile-arcs -ftest-coverage -g   -c -o CuTestTest.o CuTestTest.c
cc -fprofile-arcs -ftest-coverage -g   -c -o CuTest.o CuTest.c
john146
  • 977
  • 2
  • 11
  • 15

8 Answers8

84

I just spent an incredible amount of time debugging a very similar error. Here's what I learned:

  • You have to pass -fprofile-arcs -ftest-coverage when compiling.
  • You have to pass -fprofile-arcs when linking.
  • You can still get weird linker errors when linking. They'll look like this:

    libname.a(objfile.o):(.ctors+0x0): undefined reference to 'global constructors keyed to long_name_of_file_and_function'

This means that gconv's having problem with one of your compiler-generated constructors (in my case, a copy-constructor). Check the function mentioned in the error message, see what kinds of objects it copy-constructs, and see if any of those classes doesn't have a copy constructor. Add one, and the error will go away.

Edit: Whether or not you optimize can also affect this. Try turning on / switching off optimizations if you're having problems with it.

user
  • 5,335
  • 7
  • 47
  • 63
slicedlime
  • 2,142
  • 1
  • 17
  • 16
  • 2
    This works beautifully. Thanks for doing your incredible amount of time debugging. – Wyatt May 20 '10 at 07:02
  • 2
    Configuring the software with "CFLAGS="-O0 -fprofile-arcs -ftest-coverage" LDFLAGS="-fprofile-arcs" ./configure " seem to do the trick for me. Thanks. – oherrala Jan 10 '11 at 11:33
  • @John146, @SlicedLime: It's a shame that this answer has not been accepted after two years. This just saved me a whole heap of time. – johnsyweb May 30 '11 at 07:01
  • 4
    It seems it's not necessary to specify -fprofile-arcs in the LDFLAGS. Because these things done while creating the object files. The only thing you need is linking the libgcov in your program. – Calmarius Oct 06 '11 at 09:56
16

The flag you're looking for is -lgcov when linking. That is, change:

gcc AllTests.o CuTestTest.o CuTest.o -o TestTest

to

gcc -lgcov AllTests.o CuTestTest.o CuTest.o -o TestTest
Max Lybbert
  • 19,717
  • 4
  • 46
  • 69
14

I found, as suggested here, that adding -lgcov to the build line when building a shared library that contains .o's built with -fprofile-arcs -ftest-coverage solved this for me. And of course linking the executable with -lgcov. Built the shared library like so:

g++    -shared -o libMyLib.so src_a.o src_b.o src_c.o -lgcov

And the executable like so:

g++ -o myExec myMain.o -lMyLib -lgcov

Adding the -lgov to the build of the shared library (not just the exe), solved this additional error for me:

hidden symbol `__gcov_merge_add' in /usr/lib/gcc/x86_64-redhat-linux/4.1.2/libgcov.a(_gcov_merge_add.o) is referenced by DSO
/usr/bin/ld: final link failed: Nonrepresentable section on output

Please note that -lgcov must be the last linked library.

ewitter
  • 23
  • 3
Ogre Psalm33
  • 21,366
  • 16
  • 74
  • 92
  • Amazing. I tried to add new information when the developer uses CMake but the Suggested Edit was rejected... thanks, guys. – Tarod May 26 '15 at 06:25
  • 2
    I'd prefer to write the next explanation within the answer. Anyway, with CMake, you can get the same behaviour adding `target_link_libraries (${LIBRARY_NAME} gcov)` after `target_link_libraries (${LIBRARY_NAME} gcov)` – Tarod May 26 '15 at 06:28
  • This should be working. Not yet tried , I'll update my feedback after I tried. – sandun dhammika Jul 21 '15 at 01:50
  • The `Nonrepresentable section on output` error can happen if something compiled on your end declares something that's marked hidden but the dependency isn't satisfied internally. For example: `extern __attribute__((visibility ("hidden"))) void some_function();`, where `some_function()` isn't provided at link time through an object or static library. – Brian Vandenberg Oct 07 '15 at 22:11
14

You should be able to specify only --coverage on the command line when compiling and linking.

According to man gcc:

The option is a synonym for -fprofile-arcs -ftest-coverage (when compiling) and -lgcov (when linking).

uvsmtid
  • 4,187
  • 4
  • 38
  • 64
Oskari Timperi
  • 311
  • 3
  • 5
6

I tried a simple test file with gcc -ftest-coverage -fprofile-arcs test.c and had no problems like you describe.

I suspect that gcc brings in the gcov library if the -ftest-coverage flag is there when it is linking. Try passing that flag on your gcc command line.

flodin
  • 5,215
  • 4
  • 26
  • 39
  • Tried that with a single file application and it works. I'm having problems with my multi-file application. It compiles fine, but seems to get confused linking. – john146 Feb 19 '09 at 20:21
  • p7539c@localhost cutest> make cc -fprofile-arcs -ftest-coverage -g -c -o AllTests.o AllTests.c cc -fprofile-arcs -ftest-coverage -g -c -o CuTestTest.o CuTestTest.c cc -fprofile-arcs -ftest-coverage -g -c -o CuTest.o CuTest.c gcc AllTests.o CuTestTest.o CuTest.o -o TestTest – john146 Feb 19 '09 at 20:21
  • 2
    You are still not passing the -ftest-coverage parameter in the final call to gcc. You need to specify it when linking too. – flodin Feb 20 '09 at 07:59
  • 2
    Like slicedlime says, it's not -ftest-coverage that is needed when linking but -fprofile-arcs. – Zitrax Feb 02 '10 at 17:11
3

Perhaps obviously, this exact error message is produced when linking with a non-gcc linker. We seeing this error when linking with ifort (because our code includes both Fortran and C modules). Switching to linking with gcc did the trick.

dbn
  • 13,144
  • 3
  • 60
  • 86
2

Great Max Lybbert, Basically in case of autoconf usage add _LDADD = -lgcov ...

This will solve the issue.

siddhusingh
  • 1,832
  • 4
  • 25
  • 30
-1

So I added -shared to the CFLAGS, and now it seems to work with multiple files. Of course, it's coring in a strange place, so I don't know what that's about yet.

john146
  • 977
  • 2
  • 11
  • 15