tags:

views:

2480

answers:

6

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 th elocation 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
+2  A: 

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
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
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
You are still not passing the -ftest-coverage parameter in the final call to gcc. You need to specify it when linking too.
flodin
Like slicedlime says, it's not -ftest-coverage that is needed when linking but -fprofile-arcs.
Zitrax
A: 

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
+2  A: 

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
-fprofile-arcs implies -lgcov
slicedlime
+8  A: 

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 turing on / switching off optimizations if you're having problems with it.

slicedlime
This answer worked for me.
Zitrax
This answer worked for me as well. Thanks!
Runcible
This works beautifully. Thanks for doing your incredible amount of time debugging.
Wyatt
A: 

Hi,

I have the similar problem where when compiling and linking, it gives me

undefined reference to `__gcov_init' and followed by

undefined reference to `__gcov_merge_add'

and undefined reference to `global constructors keyed to long_name_of_file_and_function'

I tried the above suggestion by adding -lgcov in the linking part. Alternatively, I have also tried with -fprofile-arcs in the linking part. However, the same error still appear.

Any insight to this? When I remove those flags and instead just compile usually with gcc, it does not complain.

Please help.

Thanks.

jah