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 中无法解决的错误,是我必须忍受的东西,还是只是碰巧从裂缝中溜走的东西(九年前就完全被遗忘了)?如果是后者,该如何解决呢?
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;
}
The problem
Compile the above with options -fprofile-arcs -ftest-coverage
, runn the program, and then run gcov. The program output clearly shows that Foo::Foo(), main(), and Foo::~Foo() are called, in that order. The gcov output shows that Foo::Foo() and main() are called, but not Foo::~Foo().
Root cause
The global objects are destroyed by a GNU internal exit handler (function registered with at_exit()). The final gcov stats are produced by another exit handler. The gcov exit handler is obviously called before the global destruction exit handler, so gcov doesn't see the destructors being called.
Bug status
This is an old, old bug in gcov. Here's the Bugzilla link: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=7970. The bug still exists nine years later, at least in i686-apple-darwin10-g++-4.2.1.
The question
Is this an unresolvable bug in gcov, something I have to live with, or is it just something that happened to slip through the cracks (nine years old and utterly forgotten)? If the latter, how to fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,请注意该错误报告自 2005 年以来就没有得到重新确认;您可能应该添加一条注释,说明您仍然在 g++-4.2.1 中看到不良行为。即使没有人对您的信息采取行动,将这些信息公开也是很有用的。
短期来看,如果你想继续使用 gcov,你就必须忍受它。您可以考虑使用lcov,它使您能够从覆盖率分析中排除指定的行。公平警告:我听说它很好,但我自己从未使用过。
从中期来看,将该响应添加到错误跟踪器中!不能保证,但也许这会引起一些好心人的足够兴趣,为您写一个补丁。
从长远来看,如果没有人愿意为你修补它,你也许可以自己修补它。 gcc 并不是世界上最友好的代码库,让您的更改被接受可能是一次冒险,但如果您确实需要它,您可以实现它。
祝你好运。
First off, note that that bug report hasn't been reconfirmed since 2005; you should probably add a note saying that you're still seeing the bad behavior in g++-4.2.1. Even if no one acts on your message, it's useful to have that information out there.
Short term, if you want to go on using gcov you have to live with it. You might consider lcov instead, which gives you the ability to exclude specified lines from the coverage analysis. Fair warning: I've heard that it's nice, but I've never used it myself.
Medium term, add that response to the bug tracker! No guarantees, but perhaps that will generate enough interest for some kind soul to write you a patch.
Long term, if no one is willing to patch it for you, you may be able to patch it yourself. gcc is not the friendliest codebase in the world, and getting your changes accepted can be an adventure, but if you really need this, you can make it happen.
Best of luck.