C言語で標準関数のスタブを作るための方法を試してみました。


  • インターポジショニング(関数の上書き)

time関数(実行する度に結果が変わる関数)を題材にしています。まずこういうコードを単体試験しようとすると、時間が毎回変わるので一定の結果は得られません。
(main.c)

#include <stdio.h>
#include <time.h>

int main( int argc, char** argv )
{
    printf("%ld\n", time( NULL ) );
    return 0;
}
コンパイルして実行。現在のUNIX時間(数値)が表示されます。
$ gcc -g -o main main.c
$
$ ./main
$ 1555888123
常に0を返すtime関数のスタブを作ってみました。
(main.c)

#include <stdio.h>
#include <time.h>

time_t time( time_t * tloc )
{
    if( tloc == NULL ){
        return 0;
    }
    return *tloc = 0;
}

int main( int argc, char** argv )
{
    printf("%ld\n", time( NULL ) );
    return 0;
}
コンパイルして実行。常に0が返ります。
$ gcc -g -o main main.c
$
$ ./main
$ 0
main.cとstub.cを分離します。
(main.c)

#include <stdio.h>

int main( int argc, char** argv )
{
    printf("%ld\n", time( NULL ) );
    return 0;
}
(stub.c)

#include <time.h>

time_t time( time_t* tloc )
{
    if( tloc == NULL ){
        return 0;
    }
    return *tloc = 0;
}
stub.cを共有ライブラリとしてビルドして、main.cと動的リンクさせます。しかしこのまま実行すると共有ライブラリが見つからないというエラーが出ます。
$ gcc -shared -fPIC -o libstub.so stub.c
$ gcc -I./ -L./ -g -o main main.c -lstub
$ ./main
$ ./main: error while loading shared libraries: libstub.so: cannot open shared object file: No such file or directory
LD_LIBRARY‗PATHに、libstub.soのあるパスを指定することで、無事スタブ共有ライブラリを見つけることが出来ました。
$ export LD_LIBRARY_PATH=<libstub.soがあるディレクトリ>
$ ./main
$ 0
標準関数をローカル関数で再定義することをインターポジショニングと呼ぶそうです。単体試験に使えそうですね。
  • おまけ
UNIX時間(数値)を年月日時分秒に変換できるUNIX時間変換ツールが便利です。

IMG_20190324_083233

スポンサードリンク