最近我一直在尝试使用gcc / gcov对C ++项目进行代码覆盖测试。该项目由其主要模块和几个.so库组成,这些都应该用于测量。
我已经使用gcc编译了带有 - coverage 参数的所有模块,并将它们保存在生成它们的位置,以及相应的.gcno标记文件。正常执行并正常退出后,可以正确生成.gcda文件。 问题是,该程序应该是一个没有中断或终止的服务,并且不允许将任何自定义代码(如信号处理程序)插入主模块。正如网上的解决方案所示,我在独立的.so库中编写了一个信号处理函数,它在接收 SIGUSR1 信号时调用 __ gcov_flush 以将运行时覆盖计数器刷新到文件
但是,有人观察到,虽然可以保证正确调用 __ gcov_flush 函数,但在运行时只会生成.so库的.gcda文件。在我看来, __ gcov_flush 负责刷新包装模块的数据而不是其他模块的数据。我想知道这是否应该如何工作,或者是否需要一些技巧来产生完整的结果?
答案 0 :(得分:0)
我在这里看到两个问题。
如果你的可执行文件加载了几个共享库,那就太难了
获得所需的功能。链接器添加了分析代码
libgcov.a
用于每个共享库,很难调用每个库
图书馆的__gcov_flush()
来自一个中心位置,如信号处理程序
在另一个共享库中定义。
声明了来自__gcov_flush()
的函数libgcov.a
函数
__attribute__ ((__visibility__ ("hidden")))
如果从存档中提取_gcov.o并运行
objdump -t _gcov.o
_gcov.o: file format elf32-littlearm
SYMBOL TABLE:
000014b4 g F .text 00000016 .hidden __gcov_flush
即使您要求隐藏符号,链接器也不会导出隐藏符号 正如它提到here或here
所以我看到了第二个问题的两个解决方案。
您可以尝试在_gcov.o
和libgcov.a
中编辑"default"
的符号表
将可见性设置为"hidden"
而不是_gcov.o
。我没带
那样,因为我找不到任何好的精灵编辑。
如果您设法这样做,请确保更新您的链接命令
它链接了这个修补的libgcov.a
而不是默认的。{
--coverage
。基本上,您需要从中删除__gcov_flush()
选项
你的链接器标志。
您可以为{{1}}声明创建一个包装并将其导出 正如它在上面的链接中建议的那样。从你的电话中调用这个包装器 共享库中的信号处理程序。
我建议你不要为小信号处理程序添加分析 图书馆 - 这真的没必要。