gcov和全球破坏者

时间:2011-06-16 13:11:10

标签: 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;

}

问题

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

根本原因

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

错误状态

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

问题

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

1 个答案:

答案 0 :(得分:2)

首先,请注意自2005年以来该错误报告尚未得到再次确认;你应该添加一个说明你仍然看到g ++ - 4.2.1中的不良行为。即使没有人对你的信息采取行动,在那里提供这些信息也很有用。

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

中期,将该响应添加到错误跟踪器!没有保证,但也许这会产生足够的兴趣让某些灵魂给你写一个补丁。

长期来看,如果没有人愿意为你修补它,你可以自己修补它。 gcc不是世界上最友好的代码库,接受你的更改可能是一次冒险,但如果你真的需要这个,你可以实现它。

祝你好运。