gcov和全球破坏者

Dav*_*men 9 c++ g++ gcov

MWE

#include <iostream>

struct Foo {
  Foo() {
    std::cout << "Constructing Foo " << this << std::endl;
  }

  ~Foo() {
    std::cout << "Destructing Foo " << this << std::endl;
  }
};

Foo global_foo;

int main () {
  std::cout << "Entering and exiting main()" << std::endl;
  return 0;
Run Code Online (Sandbox Code Playgroud)

}

问题

使用选项编译以上内容-fprofile-arcs -ftest-coverage,运行程序,然后运行gcov.程序输出清楚地表明按顺序调用Foo :: Foo(),main()和Foo :: ~Foo().gcov输出显示调用Foo :: Foo()和main(),但不调用Foo :: ~Foo().

根本原因

全局对象由GNU内部退出处理程序(使用at_exit()注册的函数)销毁.最终的gcov统计信息由另一个退出处理程序生成.gcov退出处理程序显然在全局销毁退出处理程序之前被调用,因此gcov看不到被调用的析构函数.

错误状态

这是gcov中一个古老的 bug.这是Bugzilla链接:http://gcc.gnu.org/bugzilla/show_bug.cgi?id = 7970.该错误在九年后仍然存在,至少在i686-apple-darwin10-g ++ - 4.2.1中存在.

这个问题

这是gcov中无法解决的错误,我必须忍受的东西,还是只是碰到裂缝(9岁而完全被遗忘)的东西?如果是后者,如何解决呢?

Dav*_*ler 2

首先,请注意该错误报告自 2005 年以来就没有得到重新确认;您可能应该添加一条注释,说明您仍然在 g++-4.2.1 中看到不良行为。即使没有人对您的信息采取行动,将这些信息公开也是很有用的。

短期来看,如果你想继续使用 gcov,你就必须忍受它。您可以考虑使用lcov,它使您能够从覆盖率分析中排除指定的行。公平警告:我听说它很好,但我自己从未使用过。

从中期来看,将该响应添加到错误跟踪器中!不能保证,但也许这会引起一些好心人的足够兴趣,为您写一个补丁。

从长远来看,如果没有人愿意为你修补它,你也许可以自己修补它。gcc 并不是世界上最友好的代码库,让您的更改被接受可能是一次冒险,但如果您确实需要它,您可以实现它。

祝你好运。

  • 感谢您的回复。我添加到 bugzilla 报告中。短期的答案显然是“忍受它”。我们的产品是一个 C++ 库,其主要用途是在自动编码的模拟环境中。由于这是我们的预期目标,因此我们的许多测试都是在该环境中完成的。该环境的最新版本创建了全局静态数据。我们还拥有绕过该环境的单元测试功能。所以一个显而易见的解决方案是要求开发人员开发ctor_dtor单元测试。(我已经做到了,而且我已经听到了抱怨声。) (2认同)