Open()システムコールを完全に引き継いで、実際のsyscallをラップして、ロギングを実行したいとします。 これを行う1つの方法は、LD_PRELOADを使用することです open()エントリポイントを引き継ぐ(ユーザー作成の)共有オブジェクトライブラリをロードします。
次に、ユーザーが作成したopen()ルーチンは、それをopen()
して呼び出し、glibc関数dlsym()
へのポインターを取得します。
ただし、上記で提案したソリューションは動的ソリューションです。自分のopen()
ラッパーを静的にリンクしたいとします。どうすればいいですか?メカニズムは同じだと思いますが、ユーザー定義のopen()
とlibcopen()
の間にシンボルの衝突があると思います。
同じ目標を達成するために他のテクニックを共有してください。
ld
が提供するラップ機能を使用できます。 man ld
から:
--wrap symbol
シンボルのラッパー関数を使用します。symbol
への未定義の参照は、__wrap_symbol
に解決されます。
__real_symbol
への未定義の参照は、symbol
に解決されます。
したがって、ラッパー関数にはプレフィックス__wrap_
を使用し、実際の関数を呼び出す場合は__real_
を使用する必要があります。簡単な例は次のとおりです。
malloc_wrapper.c
:
#include <stdio.h>
void *__real_malloc (size_t);
/* This function wraps the real malloc */
void * __wrap_malloc (size_t size)
{
void *lptr = __real_malloc(size);
printf("Malloc: %lu bytes @%p\n", size, lptr);
return lptr;
}
テストアプリケーションtestapp.c
:
#include <stdio.h>
#include <stdlib.h>
int main()
{
free(malloc(1024)); // malloc will resolve to __wrap_malloc
return 0;
}
次に、アプリケーションをコンパイルします。
gcc -c malloc_wrapper.c
gcc -c testapp.c
gcc -Wl,-wrap,malloc testapp.o malloc_wrapper.o -o testapp
結果のアプリケーションの出力は次のようになります。
$ ./testapp
Malloc: 1024 bytes @0x20d8010
シンボルは、コマンドラインにリストした順序でリンカーによって解決されるため、標準ライブラリの前にライブラリをリストした場合は、信頼性が高くなります。 gccの場合、指定する必要があります
gcc <BLAH> -nodefaultlibs <BLAH BLAH> -lYOUR_LIB <OTHER_LIBS>
このようにして、ライブラリが最初に検索されて見つかります。