¿Por qué los sistemas Unix / Linux no atraviesan directorios hasta que encuentran la versión requerida de una biblioteca vinculada?

17

Tengo un ejecutable binario llamado "alfa" que requiere una biblioteca vinculada (libz.so.1.2.7) que se coloca en /home/username/myproduct/lib/libz.so.1.2.7

Exporte lo mismo a mi instancia de terminal antes de generar mi ejecutable binario ejecutando el siguiente comando.

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

Ahora, cuando engendro otra aplicación "bravo" que requiere la misma biblioteca pero de diferente versión, es decir (libz.so.1.2.8) que está disponible /lib/x86_64-linux-gnu/libz.so.1.2.8, el sistema arroja el siguiente error.

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

Si desarmado LD_LIBRARY_PATH, "bravo" comienza bien. Entiendo que el comportamiento anterior se debe a que LD_LIBRARY_PATHtiene prioridad sobre las rutas de directorio definidas /etc/ld.so.confal buscar bibliotecas vinculadas y, en consecuencia, se produjo el error anterior. Tengo curiosidad por saber por qué los desarrolladores de UNIX / LINUX no han diseñado el sistema operativo para buscar bibliotecas vinculadas en otros directorios según la jerarquía si la primera instancia de la biblioteca es de una versión diferente.

En pocas palabras, los sistemas UNIX / LINUX atraviesan un conjunto de directorios hasta encontrar la biblioteca requerida. Pero, ¿por qué no hace lo mismo hasta que encuentra la versión esperada en lugar de aceptar la primera instancia de la biblioteca, independientemente de su versión?

daedalus_hamlet
fuente
No estoy muy seguro, pero supongo que por seguridad. Personalmente, preferiría no tener que preocuparme por un enlace simbólico en ninguna parte de mis máquinas
Joe
@ Joe Muchas de las bibliotecas tienen enlaces simbólicos que apuntan a ellas. libz.so.1es un enlace simbólico alibz.so.1.2.8
Nasir Riley

Respuestas:

28

Pero, ¿por qué no hace lo mismo hasta que encuentra la versión esperada en lugar de aceptar la primera instancia de la biblioteca, independientemente de su versión?

Lo hace, por lo que sabe. zlib.so.1.2.7y zlib.so.1.2.8ambos tienen un soname de zlib.so.1, así que tu alphay los bravobinarios dicen que necesitan zlib.so.1. El cargador dinámico carga la primera biblioteca coincidente que encuentra; no sabe que la versión 1.2.8 proporciona símbolos adicionales que bravonecesita. (Esta es la razón por la cual las distribuciones se esfuerzan para especificar información de dependencia adicional, como zlib1g (>= 1.2.8)por ejemplo bravo).

Puede pensar que esto debería ser fácil de solucionar, pero no lo es, sobre todo porque los archivos binarios y las bibliotecas enumeran los símbolos que necesitan por separado de las bibliotecas que necesitan, por lo que el cargador no puede verificar que una biblioteca determinada proporcione todos los símbolos que son necesarios de ella. Los símbolos se pueden proporcionar de varias maneras, y la introducción de un enlace entre los símbolos y las bibliotecas que los proporcionan podría romper los archivos binarios existentes. También existe la diversión añadida de la interposición de símbolos para complicar las cosas (y hacer que los desarrolladores sensibles a la seguridad se rompan el pelo).

Algunas bibliotecas proporcionan información de la versión que termina siendo almacenada .gnu.version_r, con un enlace a la biblioteca proveedora, que ayudaría aquí, pero libzno es una de ellas.

(Teniendo en cuenta los sonames, espero que su alphabinario funcione bien zlib.so.1.2.8).

Stephen Kitt
fuente
Y también se debe tener en cuenta que las versiones de la biblioteca de estilo GNU son diferentes de las versiones semánticas (-ish) con las que estamos más acostumbrados. Dado que tienen el mismo número "actual", 1, zlib.so.1.2.8 no debe proporcionar ninguna característica que no tenga zlib.so.1.2.7, por lo tanto, no debería importar (desde una perspectiva ABI) cuál es encontró. Que sí importa debe considerarse un defecto.
John Bollinger
44
@John no, la única garantía es que las bibliotecas con el mismo nombre son compatibles con versiones anteriores; las bibliotecas más nuevas pueden agregar funciones, no pueden eliminar ninguna o cambiar ninguna de una manera incompatible con versiones anteriores. Es decir, un binario construido contra zlib 1.2.7 funcionará con eso o con cualquier zlib 1 más reciente; pero un binario construido contra zlib 1.2.8 no necesariamente funcionará con un zlib 1. anterior (y las versiones semánticas lo permiten; pero el manejo de soname no es versiones semánticas)
Stephen Kitt
1
Estoy diciendo específicamente sobre las convenciones de GNU, como dije, y supongo que sobre libtool en particular. No todos los proyectos siguen esa convención, por lo que tal vez sea demasiado fuerte para llamar zlib defectuoso, pero por otro lado, incluso una interpretación de versiones semánticas de los números de versión de la biblioteca involucrados llegaría a la misma conclusión. La compatibilidad directa (binaria) en tales casos no es una promesa inherente al soname, pero es una expectativa razonable en este caso.
John Bollinger
1
Sí, entiendo bien la relación entre los números de CRA y la SOVERSIÓN, que vuelve a mi punto original: la situación descrita por el OP parece ser inconsistente con el uso correcto del esquema de CRA . Evitar problemas como los OP es uno de los objetivos clave de ese esquema. Si zlib agrega una nueva interfaz binaria (versión de a), entonces su número C debería incrementarse. Que tal golpe puede conducir a un golpe de soversión también es secundario.
John Bollinger
2
@John cierto, sospecho que estamos en un acuerdo violento y que no entendí bien lo que estabas diciendo. zlibno se usa de libtooltodos modos, excepto en Darwin donde está ar;-).
Stephen Kitt