LD_PRELOADで複数のライブラリを指定する方法

LD_PRELOADで共有ライブラリを複数指定する場合は,ファイル名を":"で区切って列挙する

LD_PRELOAD=ライブラリ1:ライブラリ2

LD_PRELOADを使って,malloc()を自作関数に差し替える

ソースコード

main.c

#include <malloc.h>

int
main()
{
    void *p = malloc(1024);
    free(p);
    return 0;
}


自作のmalloc()の定義(その1)mymalloc1.c

#include <stdio.h>

void *
malloc(size_t size)
{
    fprintf(stderr, "mymalloc1: malloc() called\n");
    return NULL;
}

void
free(void *p)
{
    fprintf(stderr, "mymalloc1: free() called\n");
}

自作のmalloc()の定義(その2)mymalloc2.c

#include <stdio.h>

void *
malloc(size_t size)
{
    fprintf(stderr, "mymalloc2: malloc() called\n");
    return NULL;
}

void
free(void *p)
{
    fprintf(stderr, "mymalloc2: free() called\n");
}
コンパイル
$ gcc     main.c   -o main
$ gcc -shared -fpic mymalloc1.c -o mymalloc1.so
$ gcc -shared -fpic mymalloc2.c -o mymalloc2.so
実行

LD_PRELOADなしで実行する .システム標準のmalloc()/free()を使う

$ ./main

LD_PRELOADで mymalloc1.so を指定 .

$ LD_PRELOAD=mymalloc1.so  ./main
mymalloc1: malloc() called
mymalloc1: free() called

mymalloc1.c で実装したmalloc()/free()がコールされる

LD_PRELOADで mymalloc2.so を指定 .

$ LD_PRELOAD=mymalloc2.so  ./main
mymalloc2: malloc() called
mymalloc2: free() called

mymalloc2.c で実装したmalloc()/free()がコールされる


LD_PRELOADで 両方を指定 .

$ LD_PRELOAD=mymalloc1.so:mymalloc2.so  ./main
mymalloc1: malloc() called
mymalloc1: free() called

mymalloc1.c で実装したmalloc()/free()がコールされている

LD_PRELOADの指定順を入れ替える

$ LD_PRELOAD=mymalloc2.so:mymalloc1.so  ./main
mymalloc2: malloc() called
mymalloc2: free() called

mymalloc2.c で実装したmalloc()/free()がコールされている


LD_PRELOADで複数の共有ライブラリを指定した場合は,先頭の共有ライブライから順番にシンボル名のサーチが行われる模様

つまり

  • LD_PRELOADで指定した共有ライブラリ
    • mymalloc1.so
    • mymalloc2.so
  • main にリンクしているライブラリ
    • libc.so など (ldd ./mainで確認できる)

の順番に malloc()やfree()のシンボルをサーチしている(と思われる)

まとめ

  • LD_PRELOADで共有ライブラリを複数指定するばあいは,ファイル名を区切り文字":"で連結すれば良い
  • 同名のシンボルが複数存在する場合は, 先に指定した共有ライブラリのオブジェクトが優先される.