web-dev-qa-db-fra.com

Pourquoi les systèmes Unix / Linux ne parcourent-ils pas les répertoires jusqu'à ce qu'ils trouvent la version requise d'une bibliothèque liée?

J'ai un exécutable binaire nommé "alpha" qui nécessite une bibliothèque liée (libz.so.1.2.7) qui est placée à /home/username/myproduct/lib/libz.so.1.2.7

J'exporte le même vers mon instance de terminal avant de générer mon exécutable binaire en exécutant la commande suivante.

export LD_LIBRARY_PATH=/home/username/myproduct/lib/:$LD_LIBRARY_PATH

Maintenant, quand je lance une autre application "bravo" qui nécessite la même bibliothèque mais de version différente, c'est-à-dire (libz.so.1.2.8) qui est disponible dans /lib/x86_64-linux-gnu/libz.so.1.2.8, le système renvoie l'erreur suivante.

version `ZLIB_1.2.3.3' not found (required by /usr/lib/x86_64-linux-gnu/libxml2.so.2)

Si je désactive le LD_LIBRARY_PATH, "bravo" démarre bien. Je comprends que le comportement ci-dessus est dû au fait que LD_LIBRARY_PATH a priorité sur les chemins de répertoire définis dans /etc/ld.so.conf lors de la recherche de bibliothèques liées et par conséquent l'erreur ci-dessus s'est produite. Je suis simplement curieux de savoir pourquoi les développeurs d'UNIX/LINUX n'ont pas conçu le système d'exploitation pour rechercher des bibliothèques liées dans d'autres répertoires selon la hiérarchie si la première instance de bibliothèque est de version différente.

Autrement dit, les systèmes UNIX/LINUX parcourent un ensemble de répertoires jusqu'à ce qu'ils trouvent la bibliothèque requise. Mais pourquoi ne fait-il pas la même chose jusqu'à ce qu'il trouve la version attendue plutôt que d'accepter la première instance de bibliothèque quelle que soit sa version?

17
daedalus_hamlet

Mais pourquoi ne fait-il pas la même chose jusqu'à ce qu'il trouve la version attendue plutôt que d'accepter la première instance de bibliothèque quelle que soit sa version?

Pour autant qu'il en soit conscient. zlib.so.1.2.7 Et zlib.so.1.2.8 Ont tous deux un soname de zlib.so.1, Donc vos binaires alpha et bravo disent qu'ils ont besoin de zlib.so.1 . Le chargeur dynamique charge la première bibliothèque correspondante qu'il trouve; il ne sait pas que la version 1.2.8 fournit des symboles supplémentaires dont bravo a besoin. (C'est pourquoi les distributions s'efforcent de spécifier des informations de dépendance supplémentaires, telles que zlib1g (>= 1.2.8) pour bravo.)

Vous pourriez penser que cela devrait être facile à corriger, mais ce n'est pas le cas, notamment parce que les binaires et les bibliothèques répertorient les symboles dont ils ont besoin séparément des bibliothèques dont ils ont besoin, de sorte que le chargeur ne peut pas vérifier qu'une bibliothèque donnée fournit tous les symboles qui en sont nécessaires. Les symboles peuvent être fournis de différentes manières, et l'introduction d'un lien entre les symboles et les bibliothèques qui les fournissent pourrait casser les fichiers binaires existants. Il y a aussi le plaisir supplémentaire de l'interposition de symboles pour compliquer les choses (et faire en sorte que les développeurs sensibles à la sécurité se déchirent les cheveux).

Certaines bibliothèques fournissent des informations de version qui finissent par être stockées dans .gnu.version_r, Avec un lien vers la bibliothèque fournissant, ce qui pourrait aider ici, mais libz n'en fait pas partie.

(Compte tenu des sonames, je m'attends à ce que votre binaire alpha fonctionne correctement avec zlib.so.1.2.8.)

28
Stephen Kitt