Несколько библиотек glibc на одном хосте - PullRequest
139 голосов
/ 11 мая 2009

Несколько библиотек glibc на одном хосте

Мой сервер Linux (SLES-8) в настоящее время имеет glibc-2.2.5-235, но у меня есть программа, которая не будет работать в этой версии и требует glibc-2.3.3.

Возможно ли установить несколько glibcs ​​на одном хосте?

Это ошибка, которую я получаю, когда запускаю программу на старом glibc:

./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./myapp)
./myapp: /lib/i686/libpthread.so.0: version `GLIBC_2.3.2' not found (required by ./myapp)
./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./libxerces-c.so.27)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by ./libstdc++.so.6)
./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./libstdc++.so.6)

Итак, я создал новый каталог с именем newglibc и скопировал следующие файлы в:

libpthread.so.0
libm.so.6
libc.so.6
ld-2.3.3.so
ld-linux.so.2 -> ld-2.3.3.so

и

export LD_LIBRARY_PATH=newglibc:$LD_LIBRARY_PATH

Но я получаю ошибку:

./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libpthread.so.0)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by libstdc++.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libm.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by ./newglibc/libc.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libc.so.6)

Похоже, что они все еще ссылаются на / lib и не получают оттуда, где я их положил?

Спасибо

Ответы [ 11 ]

198 голосов
/ 12 мая 2009

Очень возможно иметь несколько версий glibc в одной системе (мы делаем это каждый день).

Однако вы должны знать, что glibc состоит из множества частей (более 200 общих библиотек), которые должны соответствовать всем. Одним из компонентов является ld-linux.so.2, и он должен соответствовать libc.so.6, иначе вы увидите ошибки, которые вы видите.

Абсолютный путь к ld-linux.so.2 жестко запрограммирован в исполняемый файл во время соединения и не может быть легко изменен после установления связи.

Чтобы создать исполняемый файл, который будет работать с новым glibc, сделайте следующее:

g++ main.o -o myapp ... \
   -Wl,--rpath=/path/to/newglibc \
   -Wl,--dynamic-linker=/path/to/newglibc/ld-linux.so.2

Опция компоновщика -rpath заставит загрузчик среды выполнения искать библиотеки в /path/to/newglibc (поэтому вам не нужно будет устанавливать LD_LIBRARY_PATH перед его запуском), а опция -dynamic-linker будет "запекать" путь к исправить ld-linux.so.2 в приложении.

Если вы не можете связать приложение myapp (например, потому что это сторонний бинарный файл), не все потеряно, но становится хитрее. Одно из решений - установить для него подходящую среду chroot. Другая возможность - использовать rtldi и бинарный редактор .

36 голосов
/ 23 июня 2017

Этот вопрос старый, остальные ответы старые. Ответ «Занятого русского» очень хороший и информативный, но он работает только при наличии исходного кода. Если нет, альтернативы тогда были очень хитрыми. К счастью, в настоящее время у нас есть простое решение этой проблемы (как прокомментировано в одном из его ответов) с использованием patchelf . Все, что вам нужно сделать, это:

$ ./patchelf --set-interpreter /path/to/newglibc/ld-linux.so.2 --set-rpath /path/to/newglibc/ myapp

И после этого вы можете просто выполнить свой файл:

$ ./myapp

К счастью, нет необходимости chroot или редактировать двоичные файлы вручную. Но не забудьте сделать резервную копию вашего двоичного файла, прежде чем устанавливать его, если вы не уверены, что делаете, потому что он изменяет ваш двоичный файл. После того, как вы исправите его, вы не сможете восстановить старый путь к интерпретатору / rpath. Если это не сработает, вам придется продолжать его исправлять, пока вы не найдете путь, который действительно будет работать ... Ну, это не обязательно процесс проб и ошибок. Например, в примере с OP ему понадобился GLIBC_2.3, поэтому вы можете легко найти, какая библиотека предоставляет эту версию, используя strings:

$ strings /lib/i686/libc.so.6 | grep GLIBC_2.3
$ strings /path/to/newglib/libc.so.6 | grep GLIBC_2.3

Теоретически, первый grep будет пустым, потому что системный libc не имеет нужной версии, а второй должен вывести GLIBC_2.3, потому что он использует версию myapp, поэтому мы знаем, что можем patchelf наш двоичный файл, использующий этот путь.

Когда вы пытаетесь запустить бинарный файл в linux, бинарный файл пытается загрузить компоновщик, затем библиотеки, и все они должны быть в пути и / или в правильном месте. Если ваша проблема с компоновщиком, и вы хотите узнать, какой путь ищет ваш двоичный файл, вы можете узнать с помощью этой команды:

$ readelf -l myapp | grep interpreter
  [Requesting program interpreter: /lib/ld-linux.so.2]                                                                                                                                                                                   

Если ваша проблема с библиотеками, команды, которые дадут вам используемые библиотеки:

$ readelf -d myapp | grep Shared
$ ldd myapp 

В этом списке будут перечислены библиотеки, которые нужны вашему бинарному файлу, но вы, вероятно, уже знаете проблемные, поскольку они уже дают ошибки, как в случае с OP.

"patchelf" работает для многих различных проблем, с которыми вы можете столкнуться при попытке запустить программу, связанных с этими двумя проблемами. Например, если вы получите: ELF file OS ABI invalid, это можно исправить, установив новый загрузчик (часть команды --set-interpreter), как я объясняю здесь . Другой пример - проблема получения No such file or directory при запуске файла, который там находится и исполняется, как показано здесь . В этом конкретном случае в OP отсутствовала ссылка на загрузчик, но, возможно, в вашем случае у вас нет прав root и вы не можете создать ссылку. Установка нового переводчика решит вашу проблему.

Спасибо нанятым русским и Михаилу Панкову за понимание и решение!

17 голосов
/ 12 мая 2009

Использовать LD_PRELOAD: поместите вашу библиотеку куда-нибудь из каталогов man lib и запустите:

LD_PRELOAD='mylibc.so anotherlib.so' program

См .: статья в Википедии

8 голосов
/ 05 ноября 2017

Прежде всего, наиболее важной зависимостью каждой динамически связанной программы является компоновщик. Все библиотеки должны соответствовать версии компоновщика.

Давайте рассмотрим простой пример: у меня есть система Ubuntu Newset, в которой я запускаю какую-то программу (в моем случае это D-компилятор - ldc2). Я бы хотел запустить его на старом CentOS, но из-за старой библиотеки glibc это невозможно. Я получил

ldc2-1.5.0-linux-x86_64/bin/ldc2: /lib64/libc.so.6: version `GLIBC_2.15' not found (required by ldc2-1.5.0-linux-x86_64/bin/ldc2)
ldc2-1.5.0-linux-x86_64/bin/ldc2: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ldc2-1.5.0-linux-x86_64/bin/ldc2)

Мне нужно скопировать все зависимости из Ubuntu в Centos. Правильный метод следующий:

Сначала давайте проверим все зависимости:

ldd ldc2-1.5.0-linux-x86_64/bin/ldc2 
    linux-vdso.so.1 =>  (0x00007ffebad3f000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f965f597000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f965f378000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f965f15b000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f965ef57000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f965ec01000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f965e9ea000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f965e60a000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f965f79f000)

linux-vdso.so.1 не является настоящей библиотекой, и нам не нужно об этом заботиться.

/ lib64 / ld-linux-x86-64.so.2 - это компоновщик, который используется linux для связи исполняемого файла со всеми динамическими библиотеками.

Остальные файлы являются настоящими библиотеками, и все они вместе с компоновщиком должны быть скопированы где-то в centos.

Предположим, что все библиотеки и компоновщик находятся в каталоге "/ mylibs".

ld-linux-x86-64.so.2 - как я уже сказал - это компоновщик. Это не динамическая библиотека, а статический исполняемый файл. Вы можете запустить его и увидеть, что у него даже есть некоторые параметры, например --library-path (я вернусь к нему).

В Linux динамически связанная программа может запускаться только по имени, например,

/bin/ldc2

Linux загружает такую ​​программу в ОЗУ и проверяет, какой компоновщик для нее установлен. Обычно в 64-битной системе это /lib64/ld-linux-x86-64.so.2 (в вашей файловой системе это символическая ссылка на реальный исполняемый файл). Затем linux запускает компоновщик и загружает динамические библиотеки.

Вы также можете немного изменить это и сделать такой трюк:

/mylibs/ld-linux-x86-64.so.2 /bin/ldc2

Это метод принуждения linux к использованию определенного компоновщика.

И теперь мы можем вернуться к упомянутому ранее параметру --library-path

/mylibs/ld-linux-x86-64.so.2 --library-path /mylibs /bin/ldc2

Он будет запускать ldc2 и загружать динамические библиотеки из /mylibs.

Это метод для вызова исполняемого файла с помощью выбранных (не системных по умолчанию) библиотек.

6 голосов
/ 31 августа 2014

Можете ли вы рассмотреть возможность использования Nix http://nixos.org/nix/?

Nix поддерживает многопользовательское управление пакетами: несколько пользователей могут общее хранилище Nix безопасно, не нужно иметь привилегии root для установить программное обеспечение, и может устанавливать и использовать различные версии пакет.

4 голосов

Настройка 1: скомпилируйте свой собственный glibc без выделенного GCC и используйте его

Эта настройка может работать и быстро, так как не перекомпилирует весь набор инструментов GCC, просто glibc.

Но это ненадежно, так как использует объекты среды выполнения C, такие как crt1.o, crti.o и crtn.o, предоставленные glibc. Это упомянуто по адресу: https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_location Эти объекты выполняют раннюю настройку, на которую опирается glibc, поэтому я не удивлюсь, если что-то пойдет не так чудесным и удивительным образом.

Для более надежной настройки см. Настройку 2 ниже.

Сборка glibc и установка локально:

export glibc_install="$(pwd)/glibc/build/install"

git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout glibc-2.28
mkdir build
cd build
../configure --prefix "$glibc_install"
make -j `nproc`
make install -j `nproc`

Настройка 1: проверка сборки

test_glibc.c

#define _GNU_SOURCE
#include <assert.h>
#include <gnu/libc-version.h>
#include <stdatomic.h>
#include <stdio.h>
#include <threads.h>

atomic_int acnt;
int cnt;

int f(void* thr_data) {
    for(int n = 0; n < 1000; ++n) {
        ++cnt;
        ++acnt;
    }
    return 0;
}

int main(int argc, char **argv) {
    /* Basic library version check. */
    printf("gnu_get_libc_version() = %s\n", gnu_get_libc_version());

    /* Exercise thrd_create from -pthread,
     * which is not present in glibc 2.27 in Ubuntu 18.04.
     * /77411/kak-mne-nachat-temy-v-prostom-c#77428 */
    thrd_t thr[10];
    for(int n = 0; n < 10; ++n)
        thrd_create(&thr[n], f, NULL);
    for(int n = 0; n < 10; ++n)
        thrd_join(thr[n], NULL);
    printf("The atomic counter is %u\n", acnt);
    printf("The non-atomic counter is %u\n", cnt);
}

Скомпилируйте и запустите с test_glibc.sh:

#!/usr/bin/env bash
set -eux
gcc \
  -L "${glibc_install}/lib" \
  -I "${glibc_install}/include" \
  -Wl,--rpath="${glibc_install}/lib" \
  -Wl,--dynamic-linker="${glibc_install}/lib/ld-linux-x86-64.so.2" \
  -std=c11 \
  -o test_glibc.out \
  -v \
  test_glibc.c \
  -pthread \
;
ldd ./test_glibc.out
./test_glibc.out

Программа выводит ожидаемое:

gnu_get_libc_version() = 2.28
The atomic counter is 10000
The non-atomic counter is 8674

Команда адаптирована с https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_location, но --sysroot привела к сбою:

cannot find /home/ciro/glibc/build/install/lib/libc.so.6 inside /home/ciro/glibc/build/install

вот я и удалил.

Вывод

ldd подтверждает, что ldd и библиотеки, которые мы только что создали, фактически используются должным образом:

+ ldd test_glibc.out
        linux-vdso.so.1 (0x00007ffe4bfd3000)
        libpthread.so.0 => /home/ciro/glibc/build/install/lib/libpthread.so.0 (0x00007fc12ed92000)
        libc.so.6 => /home/ciro/glibc/build/install/lib/libc.so.6 (0x00007fc12e9dc000)
        /home/ciro/glibc/build/install/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007fc12f1b3000)

Вывод отладочной информации gcc показывает, что использовались мои объекты среды выполнения хоста, что плохо, как упоминалось ранее, но я не знаю, как обойти это, например. он содержит:

COLLECT_GCC_OPTIONS=/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crt1.o

Настройка 1: изменить glibc

Теперь давайте изменим glibc с помощью:

diff --git a/nptl/thrd_create.c b/nptl/thrd_create.c
index 113ba0d93e..b00f088abb 100644
--- a/nptl/thrd_create.c
+++ b/nptl/thrd_create.c
@@ -16,11 +16,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */

+#include <stdio.h>
+
 #include "thrd_priv.h"

 int
 thrd_create (thrd_t *thr, thrd_start_t func, void *arg)
 {
+  puts("hacked");
   _Static_assert (sizeof (thr) == sizeof (pthread_t),
                   "sizeof (thr) != sizeof (pthread_t)");

Затем перекомпилируйте и переустановите glibc, перекомпилируйте и перезапустите нашу программу:

cd glibc/build
make -j `nproc`
make -j `nproc` install
./test_glibc.sh

и мы видим hacked напечатанных несколько раз, как и ожидалось.

Это еще раз подтверждает, что мы фактически использовали скомпилированный нами glibc, а не хост.

Проверено на Ubuntu 18.04.

Настройка 2: первоначальная настройка crosstool-NG

Это альтернатива настройке 1, и это самая правильная установка, которую я достиг далеко: все, насколько я могу судить, правильно, включая объекты времени выполнения C, такие как crt1.o, crti.o и crtn.o.

В этой настройке мы скомпилируем полный выделенный набор инструментов GCC, который использует желаемый glibc.

Единственным недостатком этого метода является то, что сборка займет больше времени. Но я бы не стал рисковать производственной установкой с чем-то меньшим.

crosstool-NG - это набор скриптов, который загружает и компилирует для нас все из исходного кода, включая GCC, glibc и binutils.

Да, система сборки GCC настолько плоха, что для этого нам нужен отдельный проект.

Эта настройка не идеальна, потому что crosstool-NG не поддерживает сборку исполняемых файлов без дополнительных -Wl флагов , что кажется странным, так как мы создали сам GCC. Но все, кажется, работает, так что это только неудобство.

Получить crosstool-NG, настроить и собрать его:

git clone https://github.com/crosstool-ng/crosstool-ng
cd crosstool-ng
git checkout a6580b8e8b55345a5a342b5bd96e42c83e640ac5
export CT_PREFIX="$(pwd)/.build/install"
export PATH="/usr/lib/ccache:${PATH}"
./bootstrap
./configure --enable-local
make -j `nproc`
./ct-ng x86_64-unknown-linux-gnu
./ct-ng menuconfig
env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS=`nproc`

Сборка занимает от тридцати минут до двух часов.

Единственный обязательный параметр конфигурации, который я вижу, - это соответствие версии ядра вашего хоста для использования правильных заголовков ядра. Найдите версию ядра своего хоста с помощью:

uname -a

, который показывает мне:

4.15.0-34-generic

так в menuconfig я делаю:

  • Operating System
    • Version of linux

поэтому я выбираю:

4.14.71

, который является первой равной или более старой версией. Он должен быть старше, поскольку ядро ​​обратно совместимо.

Настройка 2: дополнительные конфигурации

.config, который мы сгенерировали с помощью ./ct-ng x86_64-unknown-linux-gnu, имеет:

CT_GLIBC_V_2_27=y

Чтобы изменить это, в menuconfig сделайте:

  • C-library
  • Version of glibc

сохраните .config и продолжите сборку.

Или, если вы хотите использовать свой собственный источник glibc, например, чтобы использовать glibc из последней версии git, выполните команду следующим образом :

  • Paths and misc options
    • Try features marked as EXPERIMENTAL: установить в true
  • C-library
    • Source of glibc
      • Custom location: скажи да
      • Custom location
        • Custom source location: указать каталог, содержащий ваш исходный код glibc

, где glibc был клонирован как:

git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout glibc-2.28

Настройка 2: проверить это

После того, как вы собрали нужный набор инструментов, протестируйте его с помощью:

#!/usr/bin/env bash
set -eux
install_dir="${CT_PREFIX}/x86_64-unknown-linux-gnu"
PATH="${PATH}:${install_dir}/bin" \
  x86_64-unknown-linux-gnu-gcc \
  -Wl,--dynamic-linker="${install_dir}/x86_64-unknown-linux-gnu/sysroot/lib/ld-linux-x86-64.so.2" \
  -Wl,--rpath="${install_dir}/x86_64-unknown-linux-gnu/sysroot/lib" \
  -v \
  -o test_glibc.out \
  test_glibc.c \
  -pthread \
;
ldd test_glibc.out
./test_glibc.out

Кажется, все работает как в программе установки 1, за исключением того, что теперь использовались правильные объекты времени выполнения:

COLLECT_GCC_OPTIONS=/home/ciro/crosstool-ng/.build/install/x86_64-unknown-linux-gnu/bin/../x86_64-unknown-linux-gnu/sysroot/usr/lib/../lib64/crt1.o

Настройка 2: неудачная попытка перекомпиляции glibc

Это не представляется возможным при использовании кросс-инструмента NG, как объясняется ниже.

Если вы просто перестроите;

env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS=`nproc`

тогда ваши изменения в пользовательском расположении исходного кода glibc будут приняты во внимание, но он строит все с нуля, что делает его непригодным для итеративной разработки.

Если мы сделаем:

./ct-ng list-steps

дает хороший обзор шагов сборки:

Available build steps, in order:
  - companion_tools_for_build
  - companion_libs_for_build
  - binutils_for_build
  - companion_tools_for_host
  - companion_libs_for_host
  - binutils_for_host
  - cc_core_pass_1
  - kernel_headers
  - libc_start_files
  - cc_core_pass_2
  - libc
  - cc_for_build
  - cc_for_host
  - libc_post_cc
  - companion_libs_for_target
  - binutils_for_target
  - debug
  - test_suite
  - finish
Use "<step>" as action to execute only that step.
Use "+<step>" as action to execute up to that step.
Use "<step>+" as action to execute from that step onward.

следовательно, мы видим, что есть этапы glibc, переплетенные с несколькими этапами GCC, прежде всего libc_start_files предшествует cc_core_pass_2, что, вероятно, является самым дорогим шагом вместе с cc_core_pass_1.

Чтобы построить только один шаг, вы должны сначала установить опцию «Сохранить промежуточные шаги» в .config для начальной сборки:

  • Paths and misc options
    • Debug crosstool-NG
      • Save intermediate steps

и тогда вы можете попробовать:

env -u LD_LIBRARY_PATH time ./ct-ng libc+ -j`nproc`

но, к сожалению, + требуется, как указано в: https://github.com/crosstool-ng/crosstool-ng/issues/1033#issuecomment-424877536

Обратите внимание, однако, что перезапуск на промежуточном этапе сбрасывает каталог установки в состояние, в котором он находился на этом этапе. Т.е. у вас будет восстановленный libc - но окончательный компилятор не будет собран с этим libc (и, следовательно, нет библиотек компиляторов, таких как libstdc ++).

и в основном все еще делает перестройку слишком медленной, чтобы ее можно было реализовать для разработки, и я не вижу, как преодолеть это, не исправляя crosstool-NG.

Более того, начиная с шага libc, похоже, больше не копируется источник с Custom source location, что еще больше делает этот метод непригодным для использования.

Бонус: stdlibc ++

Бонус, если вам также интересна стандартная библиотека C ++: Как редактировать и перестраивать исходный код библиотеки GCC libstdc ++ C ++?

2 голосов
/ 19 июля 2018

Я не уверен, что вопрос по-прежнему актуален, но есть и другой способ решения проблемы: Docker. Можно установить практически пустой контейнер исходного дистрибутива (дистрибутив, используемый для разработки) и скопировать файлы в контейнер. Таким образом, вам не нужно создавать файловую систему, необходимую для chroot.

1 голос
/ 13 апреля 2019

@ msb дает безопасное решение.

Я столкнулся с этой проблемой, когда делал import tensorflow as tf в среде conda в CentOS 6.5, которая имеет только glibc-2.12.

ImportError: /lib64/libc.so.6: version `GLIBC_2.16' not found (required by /home/

Я хочу предоставить некоторые детали:

Сначала установите glibc в свой домашний каталог:

mkdir ~/glibc-install; cd ~/glibc-install
wget http://ftp.gnu.org/gnu/glibc/glibc-2.17.tar.gz
tar -zxvf glibc-2.17.tar.gz
cd glibc-2.17
mkdir build
cd build
../configure --prefix=/home/myself/opt/glibc-2.17  # <-- where you install new glibc
make -j<number of CPU Cores>  # You can find your <number of CPU Cores> by using **nproc** command
make install

Во-вторых, следуйте тому же способу установки patchelf ;

В-третьих, исправьте свой Python:

[myself@nfkd ~]$ patchelf --set-interpreter /home/myself/opt/glibc-2.17/lib/ld-linux-x86-64.so.2 --set-rpath /home/myself/opt/glibc-2.17/lib/ /home/myself/miniconda3/envs/tensorflow/bin/python

как упомянуто @ msb

Теперь я могу использовать tensorflow-2.0 alpha в CentOS 6.5.

ref: https://serverkurma.com/linux/how-to-update-glibc-newer-version-on-centos-6-x/

1 голос
/ 08 июля 2015

«Занятый русский» - один из лучших ответов, и я думаю, что все другие предложенные ответы могут не сработать. Причина в том, что когда приложение создается впервые, все необходимые ему API-интерфейсы разрешаются во время компиляции. Используя "ldd" вы можете увидеть все статически связанные зависимости:

ldd /usr/lib/firefox/firefox
    linux-vdso.so.1 =>  (0x00007ffd5c5f0000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f727e708000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f727e500000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f727e1f8000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f727def0000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f727db28000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f727eb78000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f727d910000)

Но во время выполнения firefox также загрузит много других динамических библиотек, например (для firefox) загружено много библиотек, помеченных "glib" (даже если статически связанных нет):

 /usr/lib/x86_64-linux-gnu/libdbus-glib-1.so.2.2.2
 /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0
 /usr/lib/x86_64-linux-gnu/libavahi-glib.so.1.0.2

Во многих случаях вы можете видеть имена одной версии, которые мягко связаны с другой версией. Например:

lrwxrwxrwx 1 root root     23 Dec 21  2014 libdbus-glib-1.so.2 -> libdbus-glib-1.so.2.2.2
-rw-r--r-- 1 root root 160832 Mar  1  2013 libdbus-glib-1.so.2.2.2

Следовательно, это означает, что в одной системе существует другая версия «библиотек», что не является проблемой, поскольку это один и тот же файл, и это обеспечит совместимость, когда приложения имеют зависимости от нескольких версий.

Таким образом, на системном уровне все библиотеки почти взаимозависимы друг от друга, и просто изменение приоритета загрузки библиотек с помощью манипуляции LD_PRELOAD или LD_LIBRARY_PATH не поможет - даже если он может загружаться, во время выполнения он все равно может аварийно завершить работу.

http://lightofdawn.org/wiki/wiki.cgi/-wiki/NewAppsOnOldGlibc

Лучшая альтернатива - chroot (кратко упомянуто ER): но для этого вам нужно будет воссоздать всю среду, в которой выполняется исходное двоичное выполнение - обычно начиная с / lib, / usr / lib /, / usr / lib / x86 и т. д. Вы можете использовать «Buildroot», или YoctoProject, или просто tar из существующей среды Distro. (например, Fedora / Suse и т. д.).

1 голос
/ 11 мая 2009

Если вы внимательно посмотрите на второй вывод, вы увидите, что используется новое расположение для библиотек. Возможно, до сих пор отсутствуют библиотеки, входящие в состав glibc.

Я также считаю, что все библиотеки, используемые вашей программой, должны быть скомпилированы с этой версией glibc. Если у вас есть доступ к исходному коду программы, лучшим вариантом будет новая компиляция.

...