2017-11-09 10 views
4

私はいくつかのCプログラムのテストを使って実装しています。この目的のために私はstdlibのopen()関数を模倣し、正しいオプションで呼び出されたことを確認するためにGCCの-Wl,--wrap=openを使用しています。ユニットテストのためにopen()を実行すると、gcovはgcdaファイルを開くことができなくなります

ただし、gcovには、.gcdaファイルを書き込む際にいくつかの問題があります。私が定義したモックは私のテストだけでなく、gcovでも使用されていると思います。

#include <stdio.h> 

int __wrap_open(const char *path, int flags, int mode) 
{ 
    printf("hello from __wrap_open\n"); 
    return -1; 
} 


int main(void) 
{ 
    return 0; 
} 

そしてgcc main.c -Wl,--wrap=open -fprofile-arcs -ftest-coverage -lgcovでそれをコンパイルします。ここではこれを再現する方法の小さな一例です。サンプルをシンプルにするために、私が直面しているバグを表示するためにCMockaを使って単体テスト部分を削除しました。

実行a.outを実行している私は、GCCとgcovの6.3.0と次の出力があります。

$ ./a.out 
hello from __wrap_open 
hello from __wrap_open 
profiling:/home/romain/wrap-bug/main.gcda:Cannot open 

をすることができるように私のユニットテストの目的のためにopen()機能を模擬する方法はありますコードカバレッジデータを生成するためにgcovを使用しますか?おそらく、gcovに__real_open()を使用するよう指示する方法がありますか?

答えて

3

それを達成する簡単な方法は、次のようになります。

  • チェック、open()に渡されたファイルのパスがあなたのプロファイリングファイル
  • であればyesの場合、__real_open()
にコールを渡します

つまり

int __real_open(const char *path, int flags, int mode); 

int __wrap_open(const char *path, int flags, int mode) 
{ 
    if (strlen(path) > 5 && !strcmp(path + strlen(path) - 5, ".gcda")) 
     return __real_open(path, flags, mode); 
    printf("hello from __wrap_open\n"); 
    return -1; 
} 

もちろん、改ざんすべきではないファイルを簡単に追加できます。

+0

これはうまくいきます!私は '__real_open()'の宣言を追加する必要がありました。あなたの回答にこれを追加し、オペレータの周りにスペースを入れて、それを受け入れられた回答としてマークすることはできますか? – MicroJoe

+0

@MicroJoeそれでは気分が良いのであれば問題ありません;) – Ctx

+0

また、私もそれをラップするとclose()について心配すべきですか?私は実際にはopen()とclose()の両方をラップしていますが、実際には '__wrap_close'の中では何も閉じていません。私のカバレッジレポートは、 '__real_close'を呼び出さなくてもうまくいきます。終了したらOSは自動的にファイル記述子を閉じますか? – MicroJoe

関連する問題