gcov 符号在哪里?

Posted

技术标签:

【中文标题】gcov 符号在哪里?【英文标题】:Where are the gcov symbols? 【发布时间】:2010-10-08 15:56:55 【问题描述】:

我正在尝试使用 gcov 编译一个简单的应用程序并收到以下链接错误:

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

我似乎找不到丢失符号的位置。 gcov 存在于运行 gcc 版本 4.1.2 的机器上

有什么想法吗?谢谢。

编辑时:

将 gcov 与包含一个 .c 文件的应用程序一起使用时,似乎一切正常。当我有多个 .c 文件(因此有多个 .o 文件)时,我遇到了上述问题。

编译步骤如下:

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

【问题讨论】:

【参考方案1】:

我刚刚花费了大量时间来调试一个非常相似的错误。这是我学到的:

编译时必须传递-fprofile-arcs -ftest-coverage。 链接时必须传递-fprofile-arcs

链接时仍然会出现奇怪的链接器错误。它们看起来像这样:

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

这意味着 gconv 与您的编译器生成的构造函数之一(在我的例子中是复制构造函数)有问题。检查错误消息中提到的函数,查看它复制构造的对象类型,并查看这些类中是否有任何类没有复制构造函数。添加一个,错误就会消失。

编辑:您是否优化也会影响这一点。如果您遇到问题,请尝试打开/关闭优化。

【讨论】:

这很好用。感谢您花费大量时间进行调试。 使用 "CFLAGS="-O0 -fprofile-arcs -ftest-coverage" LDFLAGS="-fprofile-arcs" ./configure " 配置软件似乎可以解决问题我。谢谢。 @John146, @SlicedLime:很遗憾,这个答案在两年后仍未被接受。这为我节省了一大堆时间。 似乎没有必要在 LDFLAGS 中指定 -fprofile-arcs。因为这些事情是在创建目标文件时完成的。您唯一需要的是在程序中链接 libgcov。 是的,-lgcov 为我解决了这一切。谢谢【参考方案2】:

您要查找的标志是-lgcov when linking。也就是改变:

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

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

【讨论】:

也可以使用--coverage 代替-lgcov 作为链接器标志。【参考方案3】:

我发现,as suggested here,在构建包含使用 -fprofile-arcs -ftest-coverage 构建的 .o 的共享库时,将 -lgcov 添加到构建行为我解决了这个问题。当然,将可执行文件与 -lgcov 链接起来。像这样构建共享库:

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

可执行文件如下:

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

将 -lgov 添加到共享库的构建中(不仅仅是 exe),为我解决了这个额外的错误:

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

请注意,-lgcov 必须是最后一个链接的库。

【讨论】:

太棒了。当开发人员使用 CMake 时,我尝试添加新信息,但建议的编辑被拒绝...谢谢,伙计们。 我更愿意在答案中写下一个解释。无论如何,使用 CMake,您可以在 target_link_libraries ($LIBRARY_NAME gcov) 之后添加 target_link_libraries ($LIBRARY_NAME gcov) 获得相同的行为 这应该可以工作。还没试过,我试过后再更新反馈。 Nonrepresentable section on output 错误可能发生在您编译的某些内容声明了标记为隐藏但内部不满足依赖关系的内容。例如:extern __attribute__((visibility ("hidden"))) void some_function();,其中 some_function() 不是在链接时通过对象或静态库提供的。【参考方案4】:

编译和链接时,您应该只能在命令行上指定--coverage

根据man gcc

该选项是 -fprofile-arcs -ftest-coverage 的同义词(当 编译)和-lgcov(链接时)。

【讨论】:

【参考方案5】:

我用gcc -ftest-coverage -fprofile-arcs test.c 尝试了一个简单的测试文件,没有你描述的问题。

如果链接时-ftest-coverage 标志存在,我怀疑gcc 会引入gcov 库。尝试在 gcc 命令行上传递该标志。

【讨论】:

用单个文件应用程序尝试过,它可以工作。我的多文件应用程序出现问题。它编译得很好,但似乎混淆了链接。 p7539c@localhost 可爱> 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 您仍然没有在对 gcc 的最终调用中传递 -ftest-coverage 参数。您也需要在链接时指定它。 就像 slicedlime 所说,链接时需要的不是 -ftest-coverage,而是 -fprofile-arcs。【参考方案6】:

也许很明显,当与非 gcc 链接器链接时会产生这个确切的错误消息。我们在与 ifort 链接时看到此错误(因为我们的代码同时包含 Fortran 和 C 模块)。切换到使用 gcc 链接就可以了。

【讨论】:

由于其他链接器无法识别-fprofile-arcs 选项【参考方案7】:

伟大的麦克斯·莱伯特, 基本上在使用 autoconf 的情况下添加 _LDADD = -lgcov ...

这将解决问题。

【讨论】:

【参考方案8】:

所以我将 -shared 添加到 CFLAGS,现在它似乎可以处理多个文件。当然,它在一个奇怪的地方取芯,所以我还不知道那是什么。

【讨论】:

以上是关于gcov 符号在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

Xcode13 未定义符号:___gcov_flush

内核符号 __tracepoint_module_load 在哪里定义?

引用符号 & 到底应该写在哪里?

GDB 符号来自哪里?

C99 标准在哪里说有符号整数溢出是未定义的行为?

如何调试丢失的符号 - 从哪里需要?