O que significa o erro “nenhuma informação de versão disponível” do vinculador dinâmico do linux?

91

Em nosso produto, fornecemos alguns binários do Linux que se vinculam dinamicamente às bibliotecas do sistema como "libpam". Em alguns sistemas do cliente, obtemos o seguinte erro em stderr quando o programa é executado:

./authpam: /lib/libpam.so.0: no version information available (required by authpam)

O aplicativo funciona bem e executa o código da biblioteca dinâmica. Portanto, este não é um erro fatal, é apenas um aviso.

Imagino que esse erro venha do vinculador dinâmico quando a biblioteca instalada do sistema está faltando algo que nosso executável espera. Não sei muito sobre os aspectos internos do processo de linkagem dinâmica ... e pesquisar o tópico não ajuda muito. :(

Alguém sabe o que causa esse erro? ... como posso diagnosticar a causa? ... e como poderíamos mudar nossos executáveis ​​para evitar esse problema?

Update: O cliente atualizou para a última versão do debian "testando" e ocorreu o mesmo erro. Portanto, não é uma biblioteca libpam desatualizada. Acho que gostaria de entender do que o vinculador está reclamando. Como posso investigar a causa subjacente, etc?


fonte

Respostas:

65

A "nenhuma informação de versão disponível" significa que o número da versão da biblioteca é menor no objeto compartilhado. Por exemplo, se o seu número principal.minor.patch for 7.15.5 na máquina em que você construiu o binário e o número principal.minor.patch for 7.12.1 na máquina de instalação, ld imprimirá o aviso.

Você pode corrigir isso compilando com uma biblioteca (cabeçalhos e objetos compartilhados) que corresponda à versão do objeto compartilhado enviada com seu sistema operacional de destino. Por exemplo, se você for instalar no RedHat 3.4.6-9, você não deseja compilar no Debian 4.1.1-21. Esta é uma das razões pelas quais a maioria das distribuições vem para números específicos de distro do Linux.

Caso contrário, você pode vincular estaticamente. No entanto, você não deseja fazer isso com algo como o PAM, então você deseja realmente instalar um ambiente de desenvolvimento que corresponda ao ambiente de produção do seu cliente (ou pelo menos instalar e vincular as versões corretas da biblioteca).

O conselho que você recebe para renomear os arquivos .so (preenchendo-os com números de versão) vem de uma época em que as bibliotecas de objetos compartilhados não usavam símbolos versionados. Portanto, não espere que brincar com o esquema de nomenclatura .so.nnn vá ajudar (muito - pode ajudar se seu sistema foi destruído).

Sua última opção será compilar com uma biblioteca com um número de versão secundária diferente, usando um script de link personalizado: http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/scripts. html

Para fazer isso, você precisará escrever um script personalizado e de um instalador personalizado que execute ld nos objetos compartilhados do seu cliente, usando o script personalizado. Isso requer que seu cliente tenha gcc ou ld em seu sistema de produção.

Chris
fonte
22

O que esta mensagem do vinculador dinâmico glibc realmente significa é que a biblioteca mencionada ( /lib/libpam.so.0no seu caso) não tem a VERDEFseção ELF, enquanto o binário ( authpamno seu caso) tem algumas definições de versão na VERNEEDseção para esta biblioteca (presumivelmente, libpam.so.0). Você pode vê-lo facilmente com readelf, basta olhar as seções .gnu.version_de .gnu.version_r(ou a falta delas).

Portanto, não é uma incompatibilidade de versão de símbolo, porque se o binário quisesse obter alguma versão específica via VERNEEDe a biblioteca não a fornecesse em seu real VERDEF, isso seria um erro de vinculador físico e o binário não funcionaria (como este em comparação com isso ou aquilo ). É que o binário deseja algumas versões, mas a biblioteca não fornece nenhuma informação sobre suas versões.

O que isso significa na prática? Normalmente, exatamente o que é visto neste exemplo - nada, as coisas funcionam ignorando o controle de versão. As coisas podem quebrar? Claro, sim, então as outras respostas estão corretas no fato de que se deve usar as mesmas bibliotecas em tempo de execução que aquelas às quais o binário estava vinculado no tempo de construção.

Mais informações podem ser encontradas em Ulrich Dreppers "ELF Symbol Versioning" .

Roman Khimov
fonte
5
Eu recomendo executar 'readelf -V <exePath>' para ver a seção de controle de versão. aviso V maiúsculo
Rayee Roded
Eu deduzi que esse era o motivo do aviso para bibliotecas (versões mais recentes do sistema) que eu mesmo construo e instalo em um prefixo paralelo. Sempre pensei que era porque uso o conjunto de ferramentas LLVM, mas acabei de notar que construir com o sistema gcc não coloca essas marcas de versão na biblioteca automaticamente. Eu preciso adicionar uma opção via CFLAGS e / ou LDFLAGS?
RJVB
5

Fwiw, tive esse problema ao executar check_nrpe em um sistema que tinha o sistema de monitoramento zenoss instalado. Para aumentar a confusão, funcionou bem como usuário root, mas não como usuário zenoss.

Eu descobri que o usuário zenoss tinha um LD_LIBRARY_PATH que o fazia usar bibliotecas zenoss, que emitem esses avisos. Ie:

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

Enfim, o que estou tentando dizer: verifique suas variáveis ​​como LD_LIBRARY_PATH, LD_PRELOAD etc também.

Dieter_be
fonte
3

Como você está compilando seu aplicativo? Quais sinalizadores de compilador?

Na minha experiência, ao direcionar o vasto domínio de sistemas Linux lá fora, construa seus pacotes na versão mais antiga que você deseja oferecer suporte e, como mais sistemas tendem a ser compatíveis com versões anteriores, seu aplicativo continuará a funcionar. Na verdade, essa é a razão para o controle de versão da biblioteca - garantindo a compatibilidade com versões anteriores.

Ted Percival
fonte
1

Você já viu isso ? A causa parece ser uma libpam muito antiga em um dos lados, provavelmente naquele cliente.

Ou os links para a versão podem estar faltando: http://www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html

Vinko Vrsalovic
fonte
Eu encontrei esse, mas realmente não ajudou a entender a causa. Eu não acho que seja uma biblioteca pam antiga, porque eles atualizaram para os últimos testes do debian.
Então, talvez você esteja compilando em uma máquina antiga? :) Você já tentou compilá-lo na máquina do cliente? nondot.org/sabre/Mirrored/libtool-2.1a/libtool_toc.html#TOC36
Vinko Vrsalovic