3

Python からライブラリ コードを呼び出す例から始めましょう。

これはライブラリ コードです ( library にコンパイルされますlibfoolib)。

#include <stdio.h>

void bar()
{
    printf("bar\n");
}

void foo()
{
    printf("foo\n");
}

これは、それを呼び出す python コードです。

#!/usr/bin/python25
import sys
import libfoolib
import processing

def callFoo():
    libfoolib.foo()

libfoolib.bar()

process = processing.Process(target=callFoo)
process.start()

ライブラリがコンパイルされ-ftest-coverage-fprofile-arcsコンパイラがファイルを適切に生成gcnoすると、Pythonコードが実行されると、gcdaファイルも生成されます。bar問題は、python の fork の前に呼び出される関数のカバレッジ番号のみが含まれていることです。fooPython の処理呼び出しの外でも呼び出された場合は、すべて問題ありません。

gcov生成されたカバレッジ データに対してツールを実行すると、次のようになります。

        -:    0:Source:/codeCoverageTests/pythonSIP/foo.c
        -:    0:Graph:debug/CMakeFiles/fooLib.dir/foo.c.gcno
        -:    0:Data:debug/CMakeFiles/fooLib.dir/foo.c.gcda
        -:    0:Runs:4
        -:    0:Programs:1
        -:    1:#include <stdio.h>
        -:    2:
        -:    3:void bar()
function bar called 4 returned 100% blocks executed 100%
        4:    4:{
        4:    5:    printf("bar\n");
call    0 returned 100%
        4:    6:}
        -:    7:
        -:    8:void foo()
function foo called 0 returned 0% blocks executed 0%
    #####:    9:{
    #####:   10:    printf("foo\n");
call    0 never executed
    #####:   11:}
        -:   12:

foo私が持っている質問は、「カバレッジ データはどこにありますか?」ということです。

環境に関する詳細:

  • CentOS 5.4
  • gcc: 4.1.2 20080704 (レッドハット 4.1.2-46)
  • CMake ビルド (バージョン 2.8.0)
  • パイソン2.5
  • python to C は SIP (バージョン 4.7.4) を使用します
4

1 に答える 1

1

問題は、python の処理ライブラリが を使用して終了していることos._exitです。この方法で終了すると、プロセスの通常のクリーンアップ ハンドラが呼び出されないため、これは問題です。インストルメンテーションがカバレッジ データをバッファに収集し、プロセスの終了時にのみ書き込み、通常のプロセス クリーンアップ ハンドラでそれを行うことが判明しました。これらの相互作用のため、子プロセスにはデータを書き込む機会がなく、呼び出しfooが書き込まれることはありません。

これを修正するため__gcov_flushに、プロセスが終了する前に手動で呼び出しています。これは静的ライブラリであるため、その作業のためだけに小さな C スタブが必要です。

于 2011-05-02T11:03:03.337 に答える