Cosa significa l'errore "nessuna informazione sulla versione disponibile" dal linker dinamico di Linux?


91

Nel nostro prodotto forniamo alcuni binari di Linux che si collegano dinamicamente a librerie di sistema come "libpam". Su alcuni sistemi del cliente otteniamo il seguente errore su stderr quando il programma viene eseguito:

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

L'applicazione funziona correttamente ed esegue il codice dalla libreria dinamica. Quindi questo non è un errore fatale, è solo un avvertimento.

Immagino che questo sia un errore proviene dal linker dinamico quando nella libreria installata dal sistema manca qualcosa che il nostro eseguibile si aspetta. Non so molto degli interni del processo di collegamento dinamico ... e cercare su Google l'argomento non aiuta molto. :(

Qualcuno sa cosa causa questo errore? ... come posso diagnosticare la causa? ... e come potremmo cambiare i nostri eseguibili per evitare questo problema?

Aggiornamento: il cliente è passato all'ultima versione di debian "testing" e si è verificato lo stesso errore. Quindi non è una libreria libpam obsoleta. Immagino che mi piacerebbe capire di cosa si lamenta il linker? Come posso indagare sulla causa sottostante, ecc.?

Risposte:


65

"Nessuna informazione sulla versione disponibile" significa che il numero di versione della libreria è inferiore sull'oggetto condiviso. Ad esempio, se il numero major.minor.patch è 7.15.5 sulla macchina in cui si crea il binario e il numero major.minor.patch è 7.12.1 sulla macchina di installazione, ld stamperà l'avviso.

È possibile risolvere questo problema compilando con una libreria (intestazioni e oggetti condivisi) che corrisponde alla versione dell'oggetto condiviso fornita con il sistema operativo di destinazione. Ad esempio, se stai per installare su RedHat 3.4.6-9 non vuoi compilare su Debian 4.1.1-21. Questo è uno dei motivi per cui la maggior parte delle distribuzioni fornisce numeri di distribuzione Linux specifici.

Altrimenti, puoi collegare staticamente. Tuttavia, non vuoi farlo con qualcosa come PAM, quindi vuoi installare effettivamente un ambiente di sviluppo che corrisponda all'ambiente di produzione del tuo cliente (o almeno installare e collegare le versioni della libreria corrette).

Il consiglio che si ottiene di rinominare i file .so (riempirli con i numeri di versione) deriva da un'epoca in cui le librerie di oggetti condivise non utilizzavano simboli con versione. Quindi non aspettarti che giocare con lo schema di denominazione .so.nnn possa aiutare (molto - potrebbe aiutare se il tuo sistema è stato eliminato).

L'ultima opzione sarà la compilazione con una libreria con un numero di versione minore diverso, utilizzando uno script di collegamento personalizzato: http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/scripts. html

Per fare ciò, dovrai scrivere uno script personalizzato e avrai bisogno di un programma di installazione personalizzato che esegua ld sugli oggetti condivisi del tuo client, utilizzando lo script personalizzato. Ciò richiede che il tuo client abbia gcc o ld sul proprio sistema di produzione.


22

Ciò che questo messaggio dal linker dinamico glibc significa in realtà è che la libreria menzionata ( /lib/libpam.so.0nel tuo caso) non ha la VERDEFsezione ELF mentre il binario ( authpamnel tuo caso) ha alcune definizioni di versione nella VERNEEDsezione per questa libreria (presumibilmente libpam.so.0). Puoi vederlo facilmente con readelf, guarda .gnu.version_de.gnu.version_r sezioni (o la loro mancanza).

Quindi non è una mancata corrispondenza della versione del simbolo, perché se il binario volesse ottenere una versione specifica tramite VERNEEDe la libreria non lo fornisse nel suo effettivo VERDEF, sarebbe un errore del linker reale e il binario non funzionerebbe affatto (come questo rispetto a questo o quello ). È che il binario vuole alcune versioni, ma la libreria non fornisce alcuna informazione sulle sue versioni.

Cosa significa in pratica? Di solito, esattamente ciò che si vede in questo esempio: niente, le cose funzionano ignorando il controllo delle versioni. Le cose potrebbero rompersi? Certo, sì, quindi le altre risposte sono corrette nel fatto che si dovrebbero usare le stesse librerie in fase di esecuzione di quelle a cui il binario era collegato in fase di compilazione.

Maggiori informazioni possono essere trovate in Ulrich Dreppers "ELF Symbol Versioning" .


5
Consiglio di eseguire "readelf -V <exePath>" per vedere la sezione relativa al controllo delle versioni. avviso V maiuscola
Rayee Roded

Avevo dedotto che questo fosse il motivo dell'avvertimento per le librerie (più recenti! Del sistema) che costruisco da solo e installo in un prefisso parallelo. Ho sempre pensato che fosse perché utilizzo la toolchain LLVM, ma ho appena notato che compilare con il sistema gcc non inserisce automaticamente quei tag di versione nella libreria. Devo aggiungere un'opzione tramite CFLAGS e / o LDFLAGS?
RJVB

5

Fwiw, ho avuto questo problema durante l'esecuzione di check_nrpe su un sistema su cui era installato il sistema di monitoraggio zenoss. Per aumentare la confusione, ha funzionato bene come utente root ma non come utente zenoss.

Ho scoperto che l'utente zenoss aveva un LD_LIBRARY_PATH che gli faceva utilizzare le librerie zenoss, che emettono questi avvisi. Cioè:

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

Comunque, quello che sto cercando di dire: controlla anche le tue variabili come LD_LIBRARY_PATH, LD_PRELOAD ecc.


3

Come stai compilando la tua app? Quali flag del compilatore?

Nella mia esperienza, quando prendi di mira il vasto regno dei sistemi Linux là fuori, crea i tuoi pacchetti sulla versione più vecchia che sei disposto a supportare, e poiché più sistemi tendono ad essere compatibili con le versioni precedenti, la tua app continuerà a funzionare. In realtà questa è l'intera ragione per il controllo delle versioni delle librerie: garantire la compatibilità con le versioni precedenti.


1

Hai visto questo già? La causa sembra essere una vecchia libpam su uno dei lati, probabilmente su quel cliente.

Oppure potrebbero mancare i collegamenti per la versione: http://www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html


L'ho trovato, ma non ha aiutato a capire la causa. Non penso che sia una vecchia libreria pam, perché è stata aggiornata all'ultimo debian testing.

Allora forse stai compilando su una vecchia macchina? :) Hai provato a compilarlo sulla macchina del client? nondot.org/sabre/Mirrored/libtool-2.1a/libtool_toc.html#TOC36
Vinko Vrsalovic,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.