在添加了-rdynamic标志后,gcov停止生成gcda文件(通过gdb调用__gcov_flush())。

3

我有一些用c++编写的服务器(从构建系统获取命令):

g++ -o obj/server.o -c -m64 -isystem/opt/boost/include -Wall -Werror -march=core2 -ftest-coverage -fprofile-arcs -DGCOV_ENABLED= -Iinclude -I/opt/hydraOST/lzopro/include -I/usr/include/libxml2 -Idaemon/include src/server.cpp

g++ -o bin/server.exe -rdynamic -ftest-coverage -fprofile-arcs -m64 -Wl,-rpath=\$ORIGIN -Wl,-rpath=/opt/hydraOST/lzopro/lib  obj/server.o (+ other libs)

由于它是守护进程,我用信号停止它,但在执行kill $PID之前强制转储gcov数据,我使用gdb

gdb -p $PID -batch -x gcov/dumpGcovData

gcov/dumpGcovData 的内容在哪里:

call __gcov_flush()
thread apply all call __gcov_flush()

我知道链接应该使用 -lgcov,但是因为它以这种方式工作,所以我没有在构建系统中更改它。问题出现在添加了 -rdynamic 标志之后。(没有该标志,它可以正常工作)。

2个回答

1
我知道链接应该使用-lgcov。
这是不正确的:根据您的标志,gcc会自动添加-lgcov;不需要显式的-lgcov。
问题发生在添加-rdynamic标志之后(没有该标志,它可以正常工作)。
我无法想象-rdynamic可能与问题有关。一个简单的测试用例表明它可以以任何一种方式工作,因此要么您声称“添加-rdynamic后它停止工作”的说法是错误的,要么存在更复杂的交互作用(我在我的简单测试中没有复现)。
您可能希望从以下方面开始:
  1. 验证是否确实只有重新链接 server.exe 而不加上 -rdynamic 就可以使其再次工作。
  2. 展示从 g++ -o bin/server.exe ... -Wl,-y,__gcov_flushreadelf -s bin/server.exe | grep __gcov_flush 的输出。以下是正确的输出:

    g++ -ftest-coverage -fprofile-arcs cov.c -g -rdynamic -Wl,-y,__gcov_flush
    /usr/lib/gcc/x86_64-linux-gnu/4.4.3/libgcov.a(_gcov.o): definition of __gcov_flush
    
    readelf -s a.out | grep gcov_fl
    66: 00000000004023c0   131 FUNC    LOCAL  HIDDEN   14 __gcov_flush
    

答案1:是的,在删除-rdynamic标志后,已生成覆盖率。我将使用readelf进行实验,但当我编译它时,nm显示'__gcov_flush'在server.exe中定义(因此使用__gcov_flush应该可以工作...)。 - ddzialak
我无法想象 -rdynamic 与问题有什么关系 - 是的,这是我的主要问题 - 请注意,还有其他正常结束并生成正确 gcda 文件的二进制文件。 我认为 -rdynamic 只是导致某种方式通过 gdb 调用 __gcov_flush 不起作用...但不知道为什么(?) - ddzialak
@ddzialak "有任何想法为什么?" -- #2 命令的输出可能提供线索。请运行它们并更新您的问题与输出。然后,有人可能会知道原因。或者,尝试创建一个最小化的测试用例来展示问题。 - Employed Russian

1

在添加了-Wl,-y,__gcov_flush之后,它打印出了以下行(并且标志-rdynamic无关紧要):

/usr/lib/gcc/x86_64-redhat-linux/4.1.2/libgcov.a(_gcov.o): definition of __gcov_flush

很遗憾,看起来-rdynamic标志不会影响输出:

使用-rdynamic:

readelf -s server.exe | grep gcov_flush
  1203: 0000000000808370   107 FUNC    LOCAL  HIDDEN   12 __gcov_flush

并且不使用-rdynamic选项

readelf -s server.exe | grep gcov_flush
  1203: 0000000000808380   107 FUNC    LOCAL  HIDDEN   12 __gcov_flush

无论如何,我有一个非常简单的解决方案(或者说是变通方法):仅在构建不用于 gcov 时添加 -rdynamic。
if CONFIG == gcov:
    addFlags(["-ftest-coverage", "-fprofile-arcs"])
else:
    addFlags(["-rdynamic"])

所以,主要问题似乎没有解决,但是我找到了一些解决方法(对我来说有效,因为我不太使用gcov配置进行调试 - 只用于生成覆盖率报告)。无论如何,感谢您的帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接