¿Qué significa el error "sin información de la versión disponible" del enlazador dinámico de Linux?
linker (5)
¿Cómo estás compilando tu aplicación? ¿Qué indicador del compilador?
En mi experiencia, al apuntar al vasto dominio de los sistemas Linux, crear sus paquetes en la versión más antigua que esté dispuesto a admitir, y debido a que más sistemas tienden a ser compatibles con versiones anteriores, su aplicación seguirá funcionando. En realidad, este es el motivo principal del control de versiones de la biblioteca, lo que garantiza la compatibilidad con versiones anteriores.
En nuestro producto enviamos algunos binarios de Linux que se vinculan dinámicamente a bibliotecas del sistema como "libpam". En algunos sistemas de clientes obtenemos el siguiente error en stderr cuando se ejecuta el programa:
./authpam: /lib/libpam.so.0: no version information available (required by authpam)
La aplicación funciona bien y ejecuta código de la biblioteca dinámica. Entonces este no es un error fatal, es solo una advertencia.
Me imagino que este es un error que proviene del enlazador dinámico cuando a la biblioteca instalada en el sistema le falta algo que nuestro ejecutable espera. No sé mucho sobre los aspectos internos del proceso de vinculación dinámica ... y buscar en Google el tema no ayuda mucho. :(
¿Alguien sabe qué causa este error? ... ¿cómo puedo diagnosticar la causa? ... y cómo podríamos cambiar nuestros ejecutables para evitar este problema?
Actualización: el cliente actualizó a la última versión de Debian "testing" y se produjo el mismo error. Entonces no es una biblioteca libpam desactualizada. Supongo que me gustaría entender de qué se queja el enlazador. ¿Cómo puedo investigar la causa subyacente, etc.?
¿Ya has visto this ? La causa parece ser un libpam muy antiguo en uno de los lados, probablemente en ese cliente.
O pueden faltar los enlaces para la versión: http://www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html
La "información de ninguna versión disponible" significa que el número de versión de la biblioteca es menor en el objeto compartido. Por ejemplo, si su número major.minor.patch es 7.15.5 en la máquina donde construye el binario, y el número major.minor.patch es 7.12.1 en la máquina de instalación, l imprimirá la advertencia.
Puede solucionar esto compilando con una biblioteca (encabezados y objetos compartidos) que coincida con la versión del objeto compartido incluida con su sistema operativo objetivo. Por ejemplo, si va a instalar en RedHat 3.4.6-9, no desea compilar en Debian 4.1.1-21. Esta es una de las razones por las que la mayoría de las distribuciones se envían para números de distribución linux específicos.
De lo contrario, puede vincular estáticamente. Sin embargo, no desea hacer esto con algo como PAM, por lo que desea instalar un entorno de desarrollo que coincida con el entorno de producción de su cliente (o al menos instalar y vincular con las versiones correctas de la biblioteca).
Los consejos para cambiar el nombre de los archivos .so (rellenarlos con números de versión) provienen de una época en que las bibliotecas de objetos compartidos no usaban símbolos versionados. Por lo tanto, no espere que jugar con el esquema de nombres .so.nnn ayude (en gran medida, podría ayudar si su sistema se ha descartado).
Su última opción será compilar con una biblioteca con un número de versión menor diferente, utilizando un script de enlace personalizado: http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/scripts.html
Para hacerlo, deberá escribir un script personalizado y necesitará un instalador personalizado que ejecute ld contra los objetos compartidos de su cliente, utilizando el script personalizado. Esto requiere que su cliente tenga gcc o ld en su sistema de producción.
Lo que este mensaje del enlazador dinámico glibc significa realmente es que la biblioteca mencionada ( /lib/libpam.so.0
en su caso) no tiene la sección VERDEF
ELF mientras que el binario ( authpam
en su caso) tiene algunas definiciones de versión en Sección VERNEED
para esta biblioteca (presumiblemente, libpam.so.0
). Puedes verlo fácilmente con readelf
, solo mira las secciones .gnu.version_d
y .gnu.version_r
(o la falta de ellas).
Así que no es un error de versión de símbolo, porque si el binario quería obtener una versión específica a través de VERNEED
y la biblioteca no lo proporcionaba en su VERDEF
real, sería un error de enlazador y el binario no se ejecutaría en absoluto ( como this comparación con this o that ). Es que el binario quiere algunas versiones, pero la biblioteca no proporciona ninguna información sobre sus versiones.
¿Qué significa en la práctica? Por lo general, exactamente lo que se ve en este ejemplo - nada, las cosas solo funcionan ignorando el control de versiones. Podrían las cosas romperse? Por supuesto, sí, entonces las otras respuestas son correctas en el hecho de que uno debe usar las mismas bibliotecas en tiempo de ejecución que aquellas a las que se vinculó el binario en tiempo de compilación.
Se puede encontrar más información en Ulrich Dreppers "ELF Symbol Versioning" .
Vaya, tuve este problema al ejecutar check_nrpe en un sistema que tenía instalado el sistema de monitoreo zenoss. Para aumentar la confusión, funcionó bien como usuario root pero no como usuario zenoss.
Descubrí que el usuario de zenoss tenía una LD_LIBRARY_PATH que hacía que utilizara las bibliotecas de zenoss, que emiten estas advertencias. Es decir:
root@monitoring:$ echo $LD_LIBRARY_PATH
su - zenoss
zenoss@monitoring:/root$ echo $LD_LIBRARY_PATH
/usr/local/zenoss/python/lib:/usr/local/zenoss/mysql/lib:/usr/local/zenoss/zenoss/lib:/usr/local/zenoss/common/lib::
zenoss@monitoring:/root$ /usr/lib/nagios/plugins/check_nrpe -H 192.168.61.61 -p 6969 -c check_mq
/usr/lib/nagios/plugins/check_nrpe: /usr/local/zenoss/common/lib/libcrypto.so.0.9.8: no version information available (required by /usr/lib/libssl.so.0.9.8)
(...)
zenoss@monitoring:/root$ LD_LIBRARY_PATH= /usr/lib/nagios/plugins/check_nrpe -H 192.168.61.61 -p 6969 -c check_mq
(...)
Entonces, de todos modos, lo que estoy tratando de decir: compruebe también sus variables como LD_LIBRARY_PATH, LD_PRELOAD, etc.