大坂と申します。
はじめまして、よろしくお願いします。
glibcライブラリのラッパー方法に関して質問させていただきます。
open や close のエントリを持つ独自のライブラリを作成して、システ
ムの glibc にあるエントリをラッパーしようと考えています。
Linux では $LD_PRELOAD という環境変数が対応されています。この変数
は動的リンカ/ローダが設定したライブラリを先だってロードし、他の
共有ライブラリにある関数を選択的に置き換えるものと認識しています。
この機能を使用することで実現しようと考えたのですが、環境の違いで
テストプログラムの動作が変わってしまいました。
環境・テストプログラムはそれぞれ以下の様になっています。
環境(1)
<OS>
Redhat Linux 7.3
<ライブラリ>
glibc-2.2.5-34
<ldd --version>
ldd (GNU libc) 2.2.5
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
<ld -V>
GNU ld version 2.11.93.0.2 20020207
Supported emulations:
elf_i386
i386linux
elf_i386_glibc21
環境(2)
<OS>
Redhat Linux 8.0
<Kernel>
2.4.18-14
<ライブラリ>
glibc-2.2.93-5
<ldd --version>
ldd (GNU libc) 2.2.93
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
<ld -V>
GNU ld version 2.13.90.0.2 20020802
Supported emulations:
elf_i386
i386linux
elf_i386_glibc21
テストプログラム(sample.c)
open64 を呼び出すだけのプログラム
glibc のソースを解析したところ、open64 は glibc 内部にエ
ントリがあり、open のエントリを呼び出していました。
(sample.cのソース)
---------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define FILE "xxx/xxx"
main()
{
int fd;
fd = open64(FILE, O_RDONLY);
close(fd);
}
---------------------------------------
作成したライブラリ(libsample.so)
ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), not stripped
openのエントリを持ち、呼び出された際にデバッグ文を出力する。
結果としては以下の様になりました。
(1)作成したライブラリのエントリから open が呼び出された
(2)既存の glibc のエントリから open が呼び出された
(以下はテスト結果)
---------------------------------------
環境(1)
$ export LD_PRELOAD=libsample.so
$ export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
$ ./sample
sample library open! <--- デバッグ文
$
環境(2)
$ export LD_PRELOAD=libsample.so
$ export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
$ ./sample
$
---------------------------------------
試しに open を呼び出すだけのプログラムをテストした時は、双方とも
作成したライブラリのエントリから open が呼び出されていました。
(sample2.c:sample.cのopen64をopenに変更した)
(以下はテスト結果)
---------------------------------------
環境(1)
$ export LD_PRELOAD=libsample.so
$ export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
$ ./sample2
sample library open! <--- デバッグ文
$
環境(2)
$ export LD_PRELOAD=libsample.so
$ export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
$ ./sample2
sample library open! <--- デバッグ文
$
---------------------------------------
この違いはどのようなために発生しているのでしょうか。
また、回避する方法があれば教えてください。
ご助力よろしくお願いいたします。