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

Несколько библиотек 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 и не поднимают, откуда я их положил?

Спасибо

10 ответов

Решение

Очень возможно иметь несколько версий 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 и бинарный редактор.

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

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

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

$ ./myapp

Не нужно chroot или вручную редактировать двоичные файлы, к счастью. Но не забудьте сделать резервную копию вашего бинарного файла перед его исправлением, если вы не уверены, что делаете, потому что он изменяет ваш бинарный файл. После того, как вы исправите его, вы не сможете восстановить старый путь к интерпретатору /rpath. Если это не сработает, вам придется исправлять его до тех пор, пока вы не найдете путь, который на самом деле будет работать... Ну, это не должен быть процесс проб и ошибок. Например, в примере с ОП ему понадобилось 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-доступа и вы не можете создать ссылку. Установка нового переводчика решит вашу проблему.

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

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

LD_PRELOAD='mylibc.so anotherlib.so' program

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

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

Давайте рассмотрим простой пример: у меня есть система 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.

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

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

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

Но это ненадежно, так как использует объекты среды выполнения C, такие как crt1.o, crti.o, а также crtn.o предоставлено glibc. Об этом упоминается по адресу: https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21. Эти объекты выполняют раннюю настройку, на которую опирается 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.
     * https://stackru.com/questions/56810/how-do-i-start-threads-in-plain-c/52453291#52453291 */
    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, но --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 flags, что кажется странным с тех пор, как мы создали 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

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

uname -a

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

4.15.0-34-generic

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

  • Operating System
    • Version of linux

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

4.14.71

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

Теперь вы можете построить с:

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

и теперь подождите от тридцати минут до двух часов для компиляции.

Настройка 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

Это не представляется возможным с Crosstool-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

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

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

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

Бонус: stdlibC++

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

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

Я встретил эту проблему, когда я сделал import tensorflow as tf в среде Конда в 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,

ссылка: https://serverkurma.com/linux/how-to-update-glibc-newer-version-on-centos-6-x/

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

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

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

Когда я захотел запустить браузер chromium в Ubuntu (glibc-2.15), я получил (типичное) сообщение "...libc.so.6: версия`GLIBC_2.19'не найдена...". Я учел тот факт, что файлы нужны не постоянно, а только для запуска. Поэтому я собрал файлы, необходимые для браузера и sudo, и создал среду mini-glibc-2.19, запустил браузер и снова скопировал исходные файлы. Необходимые файлы находятся в оперативной памяти, и оригинальный glibc такой же.

as root
the files (*-2.15.so) already exist 

mkdir -p /glibc-2.19/i386-linux-gnu

/glibc-2.19/ld-linux.so.2 -> /glibc-2.19/i386-linux-gnu/ld-2.19.so
/glibc-2.19/i386-linux-gnu/libc.so.6 -> libc-2.19.so
/glibc-2.19/i386-linux-gnu/libdl.so.2 -> libdl-2.19.so
/glibc-2.19/i386-linux-gnu/libpthread.so.0 -> libpthread-2.19.so

mkdir -p /glibc-2.15/i386-linux-gnu

/glibc-2.15/ld-linux.so.2 -> (/glibc-2.15/i386-linux-gnu/ld-2.15.so)
/glibc-2.15/i386-linux-gnu/libc.so.6 -> (libc-2.15.so)
/glibc-2.15/i386-linux-gnu/libdl.so.2 -> (libdl-2.15.so)
/glibc-2.15/i386-linux-gnu/libpthread.so.0 -> (libpthread-2.15.so)

скрипт для запуска браузера:

#!/bin/sh
sudo cp -r /glibc-2.19/* /lib
/path/to/the/browser &
sleep 1
sudo cp -r /glibc-2.15/* /lib
sudo rm -r /lib/i386-linux-gnu/*-2.19.so

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

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

"Занятый русский" - один из лучших ответов, и я думаю, что все другие предложенные ответы могут не сработать. Причина в том, что когда приложение создается впервые, все необходимые ему 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 и т. д.).

Другие вопросы по тегам