Ваш модуль (libphp5.so
) связан с двумя общими библиотеками, которые предоставляют один и тот же символ (в данном случае символ iconv
, а библиотеки libiconv.so.2
и, вероятно, libc.so.6
).
Когда это происходит, используется первый загруженный символ: вероятно, libc.so.6
загружается раньше, чем libiconv.so.2
, и, следовательно, именно он предоставляет вам символ iconv
.
Вы можете заставить динамический загрузчик загружать библиотеку перед любой другой; Вы можете сделать это, установив переменную окружения LD_PRELOAD
в библиотеку, которую вы хотите предварительно загрузить.
Я не эксперт по Apache, поэтому я не совсем уверен в том, как он работает, как он запускает свой процесс и какие процессы он использует, но я думаю, что настройка LD_PRELOAD
перед запуском apache должна помочь :
LD_PRELOAD=/usr/local/lib/libiconv.so.2
Небольшой пример, показывающий LD_PRELOAD
в действии:
Скомпилирует myfopen.c
как разделяемую библиотеку (myfopen.so
): она предоставит символ fopen
(уже определенный в libc
):
$ cat myfopen.c
int fopen(const char *path, const char *mode){ return -1; }
$ gcc -o libmyfopen.so myfopen.c -shared
Компиляция printfopen.c
в виде исполняемого файла (printfopen
), который просто печатает результат fopen
; свяжет его как с libc
, так и с libmyfopen
(необходимо LD_LIBRARY_PATH
, чтобы компоновщик мог искать библиотеки также в .
):
$ cat printfopen.c
#include <stdio.h>
int main( ) {
printf( "%d\n", fopen("","") );
return 0;
}
$ gcc -o printfopen printfopen.c -L. -lmyfopen
$ LD_LIBRARY_PATH=. ldd printfopen
linux-gate.so.1 => (0xb779d000)
libmyfopen.so => ./libmyfopen.so (0xb779a000)
libc.so.6 => /lib/libc.so.6 (0xb762f000)
/lib/ld-linux.so.2 (0xb779e000)
Теперь я запускаю его, чтобы проверить, работает ли LD_PRELOAD
:
$ LD_LIBRARY_PATH=. ./printfopen
-1
$ LD_PRELOAD=/lib/libc.so.6 LD_LIBRARY_PATH=. ./printfopen
0
$ LD_PRELOAD=libmyfopen.so LD_LIBRARY_PATH=. ./printfopen
-1
По умолчанию он загружает libmyfopen
до libc
, затем я попытался принудительно загрузить libc
, а затем libmyfopen
.
Я полагаю, что в вашем случае libc
загружается до libiconv
, поскольку первый загружается приложением (apache?) До загрузки модуля PHP.