2017-02-16 7 views
-1

予期せぬ結果を返す何らかの数学的計算のために失敗しているユニットテストがあります。make/gcc:「不良ビルド」の考えられる原因は何ですか?

  • コード自体は正しいことがわかっています。
  • ビルドシステムは、私たちが私のmakefileが正しいことを高い信頼度を与える、私たちのmakefileを生成するためにcmakeのを使用するコンパイラフラグが

を変更していない

  • を変更していません。

    ビルドは何ヶ月も働いていますが、それはまさにこのようなものです。

    私は失敗したテストのためのオブジェクトファイルを見ました。そして期待どおり、ソースファイルよりも新しいので、makeは再ビルドする必要はないと考えています。

    -rw------- 1 steve steve 64578 Feb 7 11:13 foo_tests.cc 
    -rw------- 1 steve steve 12930760 Feb 14 13:18 foo_tests.cc.o 
    

    オブジェクトファイルを削除して再構築すると、テストに合格するようになりました。

    -rw------- 1 steve steve 12931080 Feb 16 13:57 foo_tests.cc.o 
    

    私は新しいオブジェクトファイルが少し大きかったことに気付きました。それはやや困惑している。

    • このような不良ビルドの原因は何ですか?

    • 実行前に誤ったビルドを検出して偽のエラーを検出する方法はありますか?

    ビルドの詳細:

    これは、メイクファイルとリリースモードのバイナリでは、我々が使用コンパイラフラグがあるcmakeのを使用して生成、およびCentOSに7.2

    上のgcc 5.2.1を使用して構築

    CXX_FLAGS 
    -Werror 
    -Wall 
    -Wextra 
    -m64 
    -msse2 
    -msse4.2 
    -mfpmath=sse 
    -ftemplate-depth-128 
    -Wno-unused-parameter 
    -Wno-maybe-uninitialized 
    -Wno-strict-aliasing 
    -pthread 
    -DBOOST_DATE_TIME_POSIX_TIME_STD_CONFIG 
    -ggdb2 
    -DNDEBUG 
    -O3 
    -funroll-loops 
    -fdevirtualize 
    -finline-functions 
    -fno-builtin-malloc 
    -fno-builtin-calloc 
    -fno-builtin-realloc 
    -fno-builtin-free 
    
    LINKER_FLAGS: 
    -m64 
    -rdynamic 
    
  • +0

    _「悪いビルドを検出して偽のエラーを発見するためにできることはありますか?」_一部のビルドシステムでは_dry runs_を実行できます。 –

    +2

    あまりにも広すぎると投票する。ビルドを壊す原因となるものが多すぎます。 –

    +0

    '.cc'ファイルが使うヘッダファイルが変わったかもしれませんが、あなたのmakefileはヘッダファイルを' .o'ファイルの前提条件としてリストアップしていません。おそらくあなたのソースファイルのタイムスタンプが誤って古い値にリセットされていたか、 '.o'ファイルのタイムスタンプが再構築されずに間違って更新された可能性があります。あなたのmakefileを見たり、あなたの設定についてもっと知ることなく、言うことは不可能です。 – MadScientist

    答えて

    1
    • Whをこのような悪いビルドを引き起こす可能性がありますか?

    最も可能性の高い原因は、単に時代遅れの意味することができます「悪い」悪いソースコード、です。メイクファイルでと表記されていない場合、それぞれのターゲットの依存関係があるため、実際に再構築する必要がある場合はmakeがいくつかのコンポーネントを再構築できない可能性があります。結果は、一緒に正しく動作しないオブジェクトファイルの集合になります。

    もう1つの可能性は、コンパイラーのオプションが正しくないか矛盾していることです。あなたのプログラムの動作がコンパイラオプションに依存する場合(シンボル定義が特に有望な原因です)、間違ったオプションでコンポーネントをビルドすると、オプションを変更してもmakeに何かを再構築するよう説得するのに十分ではありません。そのような場合には、きれいなビルドが最善の方針です。

    「悪い」ビルドでも、(間違っていても)作業中のプログラムにリンクできるオブジェクトが生成され、オブジェクトファイルを削除して同じツールチェーンで再ビルドすると、 、他の可能性のあるオプションはありません。

    • 私は前にそれを実行しているとスプリアスエラーを見つけることに悪いビルドを検出するために何かできることはありますか?

    実際にビルドが最初に成功するとします。これはのテストの1つで、です。しかし、失敗したビルドを実行することは、私が説明した問題のいずれかの結果として、成功しても悪いビルドを作成するための入り口になることに注意してください。

    +0

    ビルドシステム、コンパイラフラグなどを変更せずにビルドが何ヶ月も働いているので、すべての依存関係が正しくリストされていると思います。私たちはcmakeを使用しています。これは、ターゲットを作成して依存関係をリンクするときに依存関係が正しくなることを期待しています。私は過去に、コンパイラフラグcmakeを変更したときに、影響を受けるすべてのターゲットが期限切れとみなされることに気付きました。これはまさにこの特別なものであり、通常の偽りの失敗であり、したがって疑問です。 –

    +0

    @SteveLorimer、私にとっては、「悪い」ビルドが明らかに有効なオブジェクトファイルを生成しているという意味で、実行可能な実行可能ファイルにリンクして不正な結果しか生成しないということです。コードの実行時の振舞いが何か間違っていることを示す唯一のものであるため、テスト以外の悪質なビルドを検出する良い方法はありません。 –

    +0

    入力していただきありがとうございます。非常に混乱している! –

    関連する問題