web-dev-qa-db-fra.com

Plusieurs bibliothèques glibc sur un seul hôte

Plusieurs bibliothèques glibc sur un seul hôte

Mon serveur linux (SLES-8) a actuellement la glibc-2.2.5-235, mais j'ai un programme qui ne fonctionnera pas sur cette version et qui nécessite la glibc-2.3.3.

Est-il possible d'avoir plusieurs glibcs ​​installés sur le même hôte?

C'est l'erreur que j'ai quand je lance mon programme sur l'ancienne 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)

J'ai donc créé un nouveau répertoire appelé newglibc et copié les fichiers suivants dans:

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

et

export LD_LIBRARY_PATH=newglibc:$LD_LIBRARY_PATH

Mais je reçois une erreur:

./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)

Donc, il semble qu'ils continuent à se lier à/lib et ne récupèrent pas d'où je les ai mis?

Merci

146
dogbane

Il est très possible d'avoir plusieurs versions de glibc sur le même système (nous le faisons tous les jours).

Cependant, vous devez savoir que la glibc comprend plusieurs éléments (plus de 200 bibliothèques partagées) auxquels tous doivent correspondre. Un des morceaux est ld-linux.so.2, et il doit correspondre à libc.so.6, sinon vous verrez les erreurs que vous êtes voyant.

Le chemin absolu vers ld-linux.so.2 est codé en dur dans l'exécutable au moment du lien et ne peut pas être facilement modifié une fois le lien établi.

Pour construire un exécutable qui fonctionnera avec la nouvelle glibc, procédez comme suit:

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

L’option -rpath de l’éditeur de liens obligera le chargeur d’exécution à rechercher les bibliothèques dans /path/to/newglibc (vous n’auriez donc pas à définir LD_LIBRARY_PATH avant de l’exécuter), et l’option -dynamic-linker "cuire" le chemin pour corriger ld-linux.so.2 dans l'application.

Si vous ne pouvez pas relier l'application myapp (par exemple, parce que c'est un binaire tiers), tout n'est pas perdu, mais cela devient plus compliqué. Une solution consiste à définir un environnement chroot approprié. Une autre possibilité consiste à utiliser rtldi et un éditeur binaire .

205
Employed Russian

Cette question est ancienne, les autres réponses sont anciennes. La réponse de "Employed Russian" est très bonne et informative, mais elle ne fonctionne que si vous avez le code source. Si vous ne le faites pas, les alternatives à l'époque étaient très délicates. Heureusement, de nos jours, nous avons une solution simple à ce problème (comme indiqué dans l’une de ses réponses), en utilisant patchelf . Tout ce que tu dois faire est:

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

Et après cela, vous pouvez simplement exécuter votre fichier:

$ ./myapp

Pas besoin de chroot ou d'éditer manuellement les fichiers binaires, heureusement. Mais n'oubliez pas de sauvegarder votre binaire avant de le corriger, si vous n'êtes pas sûr de ce que vous faites, car cela modifie votre fichier binaire. Après l'avoir corrigé, vous ne pouvez pas restaurer l'ancien chemin d'accès à interpreter/rpath. Si cela ne fonctionne pas, vous devrez le corriger jusqu'à ce que vous trouviez le chemin qui fonctionnera réellement ... Eh bien, il n'est pas nécessaire que ce soit un processus d'essai et d'erreur. Par exemple, dans l'exemple d'OP, il avait besoin de GLIBC_2.3, vous pouvez donc facilement trouver quelle bibliothèque fournit cette version en utilisant strings:

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

En théorie, le premier grep serait vide car le système libc ne possède pas la version voulue, et le second devrait afficher GLIBC_2.3 car il possède la version myapp utilisée, nous savons donc que nous pouvons patchelf notre binaire utilisant ce chemin.

Lorsque vous essayez d'exécuter un binaire sous Linux, le binaire essaie de charger le lieur, puis les bibliothèques, qui doivent toutes se trouver dans le chemin et/ou au bon endroit. Si votre problème concerne l'éditeur de liens et que vous voulez savoir quel chemin votre binaire recherche, vous pouvez le savoir avec cette commande:

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

Si votre problème concerne les bibliothèques, les commandes qui vous donneront les bibliothèques utilisées sont les suivantes:

$ readelf -d myapp | grep Shared
$ ldd myapp 

Ceci listera les bibliothèques dont votre binaire a besoin, mais vous connaissez probablement déjà celles qui posent problème, car elles génèrent déjà des erreurs comme dans le cas de OP.

"patchelf" fonctionne pour de nombreux problèmes que vous pouvez rencontrer lors de l'exécution d'un programme, liés à ces 2 problèmes. Par exemple, si vous obtenez: ELF file OS ABI invalid, il peut être corrigé en définissant un nouveau chargeur (le --set-interpreter une partie de la commande) comme je l'explique ici . Un autre exemple concerne le problème de l'obtention de No such file or directory lorsque vous exécutez un fichier existant et exécutable, comme dans l'exemple ici . Dans ce cas particulier, il manquait un lien vers le chargeur dans OP, mais peut-être que dans votre cas, vous n'avez pas d'accès root et ne pouvez pas créer le lien. La définition d’un nouvel interprète résoudrait votre problème.

Merci Employed Russian et Michael Pankov pour la perspicacité et la solution!

46
msb

Utilisez LD_PRELOAD: placez votre bibliothèque quelque part hors des répertoires man lib et exécutez:

LD_PRELOAD='mylibc.so anotherlib.so' program

Voir: l'article Wikipedia

17
PiedPiper

Tout d'abord, la dépendance la plus importante de chaque programme lié dynamiquement est l'éditeur de liens. Toutes les bibliothèques so doivent correspondre à la version de l'éditeur de liens.

Prenons un exemple simple: j’ai le système de newset ubuntu où j’exécute un programme (dans mon cas, c’est le compilateur D - ldc2). Je voudrais l'exécuter sur l'ancien CentOS, mais à cause de l'ancienne bibliothèque glibc, c'est impossible. j'ai eu

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)

Je dois copier toutes les dépendances d'ubuntu à centos. La méthode appropriée est la suivante:

Tout d'abord, vérifions toutes les dépendances:

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 n'est pas une vraie bibliothèque et nous n'avons pas à nous en soucier.

/lib64/ld-linux-x86-64.so.2 est l'éditeur de liens, qui est utilisé par linux pour lier l'exécutable à toutes les bibliothèques dynamiques.

Les fichiers restants sont de véritables bibliothèques et tous ensemble avec l’éditeur de liens doivent être copiés quelque part dans le centos.

Supposons que toutes les bibliothèques et l’éditeur de liens se trouvent dans le répertoire "/ mylibs".

ld-linux-x86-64.so.2 - comme je l'ai déjà dit - est l'éditeur de liens. Ce n'est pas une bibliothèque dynamique mais un exécutable statique. Vous pouvez l'exécuter et voir qu'il contient même certains paramètres, par exemple --library-path (j'y reviendrai).

Sur le Linux, un programme lié dynamiquement peut être appelé simplement par son nom, par exemple

/bin/ldc2

Linux charge ce programme dans la RAM et vérifie quel éditeur de liens est configuré pour cela. Habituellement, sur un système 64 bits, il s’agit de /lib64/ld-linux-x86-64.so.2 (dans votre système de fichiers, il s'agit d’un lien symbolique vers le véritable exécutable). Ensuite, Linux exécute l'éditeur de liens et charge des bibliothèques dynamiques.

Vous pouvez aussi changer cela un peu et faire un truc:

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

C'est la méthode pour forcer Linux à utiliser un éditeur de liens spécifique.

Et maintenant, nous pouvons revenir au paramètre mentionné plus haut --library-path

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

Il exécutera ldc2 et chargera des bibliothèques dynamiques à partir de/mylibs.

C'est la méthode pour appeler l'exécutable avec des bibliothèques choisies (pas par défaut du système).

9

Pouvez-vous envisager d'utiliser Nix http://nixos.org/nix/ ?

Nix prend en charge la gestion de paquets multi-utilisateurs: plusieurs utilisateurs peuvent partager un magasin Nix commun en toute sécurité, il n’est pas nécessaire de disposer des privilèges root pour installer un logiciel, et peut installer et utiliser différentes versions d’un package.

6
Igor

Setup 1: compilez votre propre glibc sans GCC dédié et utilisez-la

Cette configuration peut fonctionner et est rapide car elle ne recompile pas la totalité de la chaîne d’outils de GCC, elle est simplement glibc.

Mais il n’est pas fiable car il utilise des objets d’exécution de l’hôte C tels que crt1.o, crti.o Et crtn.o Fournis par la glibc. Ceci est mentionné à: https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_location Ces objets sont installés de manière précoce, glibc s'appuie sur, alors je ne le ferais pas soyez surpris si les choses se brisent de manière merveilleuse et étonnamment subtile.

Pour une configuration plus fiable, voir la configuration 2 ci-dessous.

Construisez glibc et installez localement:

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`

Setup 1: vérifier la construction

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://stackoverflow.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);
}

Compilez et exécutez avec 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

Le programme produit les résultats attendus:

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

Commande adaptée de https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_location mais --sysroot L'a fait échouer avec:

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

alors je l'ai enlevé.

La sortie ldd confirme que les bibliothèques ldd et celles que nous venons de construire sont effectivement utilisées comme prévu:

+ 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)

La sortie de débogage de la compilation gcc montre que mes objets d’exécution de l’hôte ont été utilisés. il contient:

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

Configuration 1: modifier la glibc

Modifions maintenant la glibc avec:

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)");

Recompilez et réinstallez glibc, puis recompilez et exécutez à nouveau notre programme:

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

et nous voyons hacked imprimé quelques fois comme prévu.

Cela confirme que nous avons réellement utilisé la glibc que nous avons compilée et non celle de l'hôte.

Testé sur Ubuntu 18.04.

Configuration 2: configuration vierge de crosstool-NG

C'est une alternative à la configuration 1, et c'est la configuration la plus correcte que j'ai réalisée jusqu'à présent: tout est correct, dans la mesure où je peux l'observer, y compris les objets d'exécution C tels que crt1.o, crti.o et crtn.o.

Dans cette configuration, nous allons compiler une chaîne d’outils GCC entièrement dédiée qui utilise la glibc que nous voulons.

Le seul inconvénient de cette méthode est que la compilation prendra plus de temps. Mais je ne risquerais pas une configuration de production avec rien de moins.

crosstool-NG est un ensemble de scripts qui télécharge et compile tout depuis la source, y compris GCC, glibc et binutils.

Oui, le système de construction de GCC est si grave que nous avons besoin d’un projet séparé pour cela.

Cette configuration n’est pas seulement parfaite parce que crosstool-NG ne prend pas en charge la création d’exécutables sans indicateurs supplémentaires -Wl , ce qui est étrange depuis que nous avons créé GCC. Mais tout semble fonctionner, ce n’est donc qu’un inconvénient.

Récupérez crosstool-NG, configurez-le et construisez-le:

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`

La construction prend environ trente minutes à deux heures.

La seule option de configuration obligatoire que je puisse voir consiste à faire correspondre la version de votre noyau hôte à l'utilisation des en-têtes de noyau appropriés. Trouvez la version de votre noyau hôte avec:

uname -a

ce qui me montre:

4.15.0-34-generic

donc dans menuconfig je fais:

  • Operating System
    • Version of linux

alors je sélectionne:

4.14.71

qui est la première version égale ou plus ancienne. Il doit être plus ancien puisque le noyau est rétro-compatible.

Setup 2: configurations optionnelles

Le .config Que nous avons généré avec ./ct-ng x86_64-unknown-linux-gnu A:

CT_GLIBC_V_2_27=y

Pour changer cela, dans menuconfig, faites:

  • C-library
  • Version of glibc

enregistrez le .config et continuez avec la construction.

Ou, si vous souhaitez utiliser votre propre source glibc, par exemple. Pour utiliser la glibc du dernier git, continuez comme ceci :

  • Paths and misc options
    • Try features marked as EXPERIMENTAL: Défini sur true
  • C-library
    • Source of glibc
      • Custom location: Dites oui
      • Custom location
        • Custom source location: Pointez sur un répertoire contenant votre source glibc

où glibc a été cloné en tant que:

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

Setup 2: testez-le

Une fois que vous avez construit la chaîne d'outils que vous voulez, testez-la avec:

#!/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

Tout semble fonctionner comme dans la configuration 1, sauf que les objets d'exécution corrects ont maintenant été utilisés:

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

Configuration 2: échec de la tentative de recompilation efficace de la glibc

Cela ne semble pas possible avec crosstool-NG, comme expliqué ci-dessous.

Si vous venez de reconstruire;

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

ensuite, vos modifications apportées à l'emplacement source glibc personnalisé sont prises en compte, mais tout est construit à partir de zéro, ce qui le rend inutilisable pour un développement itératif.

Si nous faisons:

./ct-ng list-steps

cela donne un bon aperçu des étapes de construction:

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.

par conséquent, nous voyons qu'il y a des étapes glibc entrelacées avec plusieurs étapes GCC, notamment libc_start_files précède cc_core_pass_2, qui est probablement l'étape la plus chère avec cc_core_pass_1.

Afin de ne construire qu'une étape, vous devez d’abord définir l’option "Enregistrer les étapes intermédiaires" dans .config Pour la construction initiale:

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

et alors vous pouvez essayer:

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

mais malheureusement, le + requis comme indiqué à: https://github.com/crosstool-ng/crosstool-ng/issues/1033#issuecomment-424877536

Notez toutefois que le redémarrage à une étape intermédiaire réinitialise le répertoire d'installation à l'état qu'il avait lors de cette étape. C'est-à-dire que vous aurez une libc reconstruite - mais pas de compilateur final construit avec cette libc (et par conséquent, aucune bibliothèque de compilateur comme libstdc ++ non plus).

et, fondamentalement, rend la reconstruction trop lente pour être réalisable pour le développement, et je ne vois pas comment résoudre ce problème sans appliquer de correctif à Crosstool-NG.

De plus, à partir de l'étape libc, il semble que le code source ne soit plus copié de Custom source location, Rendant ainsi cette méthode inutilisable.

Bonus: stdlibc ++

Un bonus si vous êtes également intéressé par la bibliothèque standard C++: Comment éditer et reconstruire la source de la bibliothèque standard GCC libstdc ++ C++?

@msb donne une solution sûre.

J'ai rencontré ce problème quand je l'ai fait import tensorflow as tf in conda environment in CentOS 6.5 qui n'a que glibc-2.12.

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

Je veux fournir quelques détails:

Commencez par installer glibc dans votre répertoire personnel:

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

Deuxièmement, suivez la même procédure pour installer patchelf ;

Troisièmement, corrigez votre 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

comme mentionné par @msb

Maintenant je peux utiliser tensorflow-2.0 alpha dans CentOS 6.5.

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

2
Belter

Je ne suis pas sûr que la question soit toujours d'actualité, mais il existe un autre moyen de résoudre le problème: Docker. On peut installer un conteneur presque vide de la distribution source (la distribution utilisée pour le développement) et copier les fichiers dans le conteneur. De cette façon, vous n'avez pas besoin de créer le système de fichiers nécessaire pour le chroot.

2
user1396055

Si vous examinez attentivement la deuxième sortie, vous constaterez que le nouvel emplacement des bibliothèques est utilisé. Peut-être existe-t-il encore des bibliothèques manquantes faisant partie de la glibc.

Je pense aussi que toutes les bibliothèques utilisées par votre programme devraient être compilées avec cette version de glibc. Si vous avez accès au code source du programme, une nouvelle compilation semble être la meilleure solution.

1
rsarro

"Employed Russian" est la meilleure réponse, et je pense que toutes les autres réponses suggérées risquent de ne pas fonctionner. La raison en est simplement parce que lors de la création d'une application, toutes les API dont elle a besoin sont résolues au moment de la compilation. En utilisant "ldd", vous pouvez voir toutes les dépendances liées statiquement:

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)

Mais au moment de l’exécution, firefox chargera également de nombreuses autres bibliothèques dynamiques, par exemple (pour firefox), de nombreuses bibliothèques portant la mention "glib" sont chargées (même si elles sont liées statiquement):

 /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

Plusieurs fois, vous pouvez voir les noms d'une version liée de manière souple à une autre version. Par exemple:

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

Cela signifie donc que des versions différentes de "bibliothèques" existent dans un même système - ce qui n’est pas un problème, car il s’agit du même fichier, et il fournira des compatibilités lorsque les applications dépendent de plusieurs versions.

Par conséquent, au niveau du système, toutes les bibliothèques sont presque interdépendantes. Changer la priorité de chargement des bibliothèques en manipulant LD_PRELOAD ou LD_LIBRARY_PATH n’aidera pas - même si elle peut se charger, l’exécution risque de se bloquer.

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

La meilleure alternative est chroot (mentionné brièvement par ER): mais pour cela, vous devrez recréer tout l'environnement dans lequel est exécuté le binaire original - généralement à partir de/lib,/usr/lib /,/usr/lib/x86, etc. Vous pouvez utiliser "Buildroot", ou YoctoProject, ou simplement tar depuis un environnement Distro existant. (comme Fedora/Suse etc).

1
Peter Teoh

Lorsque j'ai voulu exécuter un navigateur chrome sur Ubuntu precise (glibc-2.15), j'ai reçu le message (typique) "... libc.so.6: la version` GLIBC_2.19 'n'a pas été trouvée ... ". J'ai considéré le fait que les fichiers ne sont pas nécessaires en permanence, mais seulement pour commencer. J'ai donc rassemblé les fichiers nécessaires au navigateur et à Sudo, créé un environnement mini-glibc-2.19, lancé le navigateur, puis copié les fichiers d'origine. Les fichiers nécessaires sont dans RAM et la glibc originale est la même.

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)

le script pour exécuter le navigateur:

#!/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
0
dudu