在库中使用__gcov_flush不会强制其他模块生成.gcda文件

时间:2015-01-27 06:32:20

标签: c++ c gcc code-coverage gcov

最近我一直在尝试使用gcc / gcov对C ++项目进行代码覆盖测试。该项目由其主要模块和几个.so库组成,这些都应该用于测量。

我已经使用gcc编译了带有 - coverage 参数的所有模块,并将它们保存在生成​​它们的位置,以及相应的.gcno标记文件。正常执行并正常退出后,可以正确生成.gcda文件。 问题是,该程序应该是一个没有中断或终止的服务,并且不允许将任何自定义代码(如信号处理程序)插入主模块。正如网上的解决方案所示,我在独立的.so库中编写了一个信号处理函数,它在接收 SIGUSR1 信号时调用 __ gcov_flush 以将运行时覆盖计数器刷新到文件

但是,有人观察到,虽然可以保证正确调用 __ gcov_flush 函数,但在运行时只会生成.so库的.gcda文件。在我看来, __ gcov_flush 负责刷新包装模块的数据而不是其他模块的数据。我想知道这是否应该如何工作,或者是否需要一些技巧来产生完整的结果?

1 个答案:

答案 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

即使您要求隐藏符号,链接器也不会导出隐藏符号    正如它提到herehere

所以我看到了第二个问题的两个解决方案。

  1. 您可以尝试在_gcov.olibgcov.a中编辑"default"的符号表 将可见性设置为"hidden"而不是_gcov.o。我没带 那样,因为我找不到任何好的精灵编辑。

    如果您设法这样做,请确保更新您的链接命令 它链接了这个修补的libgcov.a而不是默认的。{ --coverage。基本上,您需要从中删除__gcov_flush()选项 你的链接器标志。

  2. 您可以为{{1}}声明创建一个包装并将其导出 正如它在上面的链接中建议的那样。从你的电话中调用这个包装器 共享库中的信号处理程序。

    我建议你不要为小信号处理程序添加分析 图书馆 - 这真的没必要。