9

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;

}

問題

上記を options-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。このバグは 9 年経った今でも、少なくとも i686-apple-darwin10-g++-4.2.1 には存在しています。

質問

これは gcov の解決不可能なバグであり、私が対処しなければならないものですか、それともたまたま見過ごされたものですか (9 年前のことで、完全に忘れられています)。後者の場合、どのように修正しますか?

4

1 に答える 1

2

まず、バグレポートは2005年以降再確認されていないことに注意してください。おそらく、g++-4.2.1でまだ悪い動作が見られるというメモを追加する必要があります。誰もあなたのメッセージに行動を起こさない場合でも、そこにその情報があると便利です。

短期的には、gcovを使い続けたい場合は、それと一緒に暮らす必要があります。代わりにlcovを検討することもできます。これにより、カバレッジ分析から指定された回線を除外できます。公正な警告:それは素晴らしいと聞きましたが、私はそれを自分で使ったことがありません。

中期的には、その応答をバグトラッカーに追加してください。保証はありませんが、おそらくそれはある種の魂があなたにパッチを書くのに十分な関心を生み出すでしょう。

長期的には、誰もあなたのためにパッチを当てる気がない場合は、自分でパッチを当てることができるかもしれません。gccは世界で最もフレンドリーなコードベースではなく、変更を受け入れることは冒険かもしれませんが、本当にこれが必要な場合は、それを実現することができます。

幸運を祈ります。

于 2011-06-17T17:07:16.677 に答える