¿Qué significa el error "no hay información de versión disponible" del enlazador dinámico de Linux?

89

En nuestro producto enviamos algunos binarios de Linux que enlazan 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, esto no es un error fatal, en realidad es solo una advertencia.

Me imagino que este error proviene del enlazador dinámico cuando a la biblioteca instalada del 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.?


fuente

Respuestas:

64

La "información de versión no 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 construyó el binario, y el número major.minor.patch es 7.12.1 en la máquina de instalación, ld imprimirá la advertencia.

Puede solucionar esto compilando con una biblioteca (encabezados y objetos compartidos) que coincida con la versión del objeto compartido enviada con su sistema operativo de destino. Por ejemplo, si va a instalar 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 específicos de distribución de Linux.

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 de biblioteca correctas).

El consejo de cambiar el nombre de los archivos .so (rellenarlos con números de versión) proviene de una época en la que las bibliotecas de objetos compartidos no usaban símbolos versionados. Así que no espere que jugar con el esquema de nomenclatura .so.nnn ayude (mucho, podría ayudar si su sistema se ha destruido).

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 hacer esto, necesitará escribir un script personalizado y necesitará un instalador personalizado que ejecute ld contra los objetos compartidos de su cliente, usando el script personalizado. Esto requiere que su cliente tenga gcc o ld en su sistema de producción.

Chris
fuente
21

Lo que este mensaje del enlazador dinámico glibc realmente significa es que la biblioteca mencionada ( /lib/libpam.so.0en su caso) no tiene la VERDEFsección ELF mientras que el binario ( authpamen su caso) tiene algunas definiciones de versión en la VERNEEDsección de esta biblioteca (presumiblemente libpam.so.0). Puede verlo fácilmente con readelfsolo mirar las secciones .gnu.version_dy .gnu.version_r(o la falta de ellas).

Por lo tanto, no es una discrepancia de versión de símbolo, porque si el binario quisiera obtener alguna versión específica a través de VERNEEDy la biblioteca no la proporcionó en su versión real VERDEF, sería un error de enlace duro y el binario no se ejecutaría en absoluto (como este comparado con esto o aquello ). 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 simplemente funcionan ignorando el control de versiones. ¿Podrían romperse las cosas? Por supuesto, sí, por lo que las otras respuestas son correctas en el hecho de que se deben usar las mismas bibliotecas en tiempo de ejecución a las que se vinculó el binario en el momento de la compilación.

Se puede encontrar más información en Ulrich Dreppers " Control de versiones de símbolos ELF" .

Roman Khimov
fuente
5
Recomiendo ejecutar 'readelf -V <exePath>' para ver la sección de control de versiones. aviso capital V
Rayee Roded
Había deducido que esta era la razón de la advertencia para las bibliotecas (¡más nuevas! Del sistema) que construyo e instalo en un prefijo paralelo. Siempre pensé que era porque uso la cadena de herramientas LLVM, pero me di cuenta de que compilar con el sistema gcc no coloca esas etiquetas de versión en la biblioteca automáticamente. ¿Necesito agregar una opción a través de CFLAGS y / o LDFLAGS?
RJVB
5

Fwiw, 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 un LD_LIBRARY_PATH que hacía que usara las bibliotecas de zenoss, que emitían 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
(...)

De todos modos, lo que estoy tratando de decir: verifique sus variables como LD_LIBRARY_PATH, LD_PRELOAD, etc. también.

Dieter_be
fuente
3

¿Cómo estás compilando tu aplicación? ¿Qué banderas del compilador?

En mi experiencia, cuando se dirija al vasto ámbito de los sistemas Linux, cree 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, esta es la razón principal del control de versiones de la biblioteca: garantizar la compatibilidad con versiones anteriores.

Ted Percival
fuente
1

¿Has visto esto ya? 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

Vinko Vrsalovic
fuente
Encontré ese, pero realmente no ayudó a comprender la causa. No creo que sea una biblioteca pam antigua, porque se actualizaron a las últimas pruebas de Debian.
Entonces, ¿quizás estás compilando en una máquina vieja? :) ¿Ha intentado compilarlo en la máquina del cliente? nondot.org/sabre/Mirrored/libtool-2.1a/libtool_toc.html#TOC36
Vinko Vrsalovic