GCC:LD_PRELOADを使用したmallocの動作切替
今回もC言語の関数単体テスト系の話題です。mallocを利用する関数を試験する際にmallocのスタブを作成して単体試験を実行しようとすると単体試験のツール自体がmallocを使用していたりしてうまく動かないケースがあります。
このような場合、GDBを使用してmallocの戻り値を操作したりしていたのですが、LD_PRELOADを使用してmallocの動作を切り替えることができましたので紹介します。ネタもとは「Binary Hacks ―ハッカー秘伝のテクニック100選」のHACK#61「LD_PRELOADで既存の関数をラップする」です。
使用したのは以下のソースになります。
サンプルソースとコンパイル
malloc_stub.c
#define _GNU_SOURCE #include <dlfcn.h> #include <stdlib.h> static void *(*malloc0)(size_t size); void __attribute__((constructor)) init_malloc0(void) { malloc0 = dlsym(RTLD_NEXT, "malloc"); } void *malloc(size_t size) { if( !getenv("MALLOC_STUB") ) { /* 環境変数未定義時 */ return malloc0(size); } else { /* 環境変数定義時 */ return NULL; } }
環境変数MALLOC_STUBが定義されている場合はNULLを返すことにします。
このモジュールは共有ライブラリとしてコンパイルします。
$ gcc -shared -fPIC -o malloc_stub.so malloc_stub.c -ldl