Was bedeutet der Fehler "Keine Versionsinformationen verfügbar" von Linux Dynamic Linker?

85

In unserem Produkt liefern wir einige Linux-Binärdateien, die dynamisch mit Systembibliotheken wie "libpam" verknüpft sind. Auf einigen Kundensystemen wird auf stderr der folgende Fehler angezeigt, wenn das Programm ausgeführt wird:

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

Die Anwendung läuft einwandfrei und führt Code aus der dynamischen Bibliothek aus. Dies ist also kein schwerwiegender Fehler, sondern nur eine Warnung.

Ich denke, dass dies ein Fehler ist, der vom dynamischen Linker herrührt, wenn in der vom System installierten Bibliothek etwas fehlt, was unsere ausführbare Datei erwartet. Ich weiß nicht viel über die Interna des dynamischen Verknüpfungsprozesses ... und das Googeln des Themas hilft nicht viel. :(

Weiß jemand, was diesen Fehler verursacht? ... wie kann ich die Ursache diagnostizieren? ... und wie könnten wir unsere ausführbaren Dateien ändern, um dieses Problem zu vermeiden?

Update: Der Kunde hat auf die neueste Version von debian "testing" aktualisiert und der gleiche Fehler ist aufgetreten. Es ist also keine veraltete libpam-Bibliothek. Ich würde gerne verstehen, worüber sich der Linker beschwert. Wie kann ich die zugrunde liegende Ursache usw. untersuchen?


quelle

Antworten:

61

Die Option "Keine Versionsinformationen verfügbar" bedeutet, dass die Versionsnummer der Bibliothek für das freigegebene Objekt niedriger ist. Wenn Ihre major.minor.patch-Nummer beispielsweise auf dem Computer, auf dem Sie die Binärdatei erstellen, 7.15.5 lautet und die major.minor.patch-Nummer auf dem Installationscomputer 7.12.1 lautet, druckt ld die Warnung.

Sie können dies beheben, indem Sie mit einer Bibliothek (Header und gemeinsam genutzte Objekte) kompilieren, die der mit Ihrem Zielbetriebssystem gelieferten Version für gemeinsam genutzte Objekte entspricht. Wenn Sie beispielsweise RedHat 3.4.6-9 installieren möchten, möchten Sie nicht unter Debian 4.1.1-21 kompilieren. Dies ist einer der Gründe, warum die meisten Distributionen für bestimmte Linux-Distributionsnummern ausgeliefert werden.

Andernfalls können Sie statisch verknüpfen. Sie möchten dies jedoch nicht mit so etwas wie PAM tun, sondern eine Entwicklungsumgebung installieren, die der Produktionsumgebung Ihres Kunden entspricht (oder zumindest die richtigen Bibliotheksversionen installieren und mit diesen verknüpfen).

Der Ratschlag zum Umbenennen der .so-Dateien (Auffüllen mit Versionsnummern) stammt aus einer Zeit, in der gemeinsam genutzte Objektbibliotheken keine versionierten Symbole verwendeten. Erwarten Sie also nicht, dass das Spielen mit dem Namensschema .so.nnn hilfreich sein wird (viel - es könnte hilfreich sein, wenn Ihr System zerstört wurde.)

Ihre letzte Option ist das Kompilieren mit einer Bibliothek mit einer anderen Nebenversionsnummer unter Verwendung eines benutzerdefinierten Verknüpfungsskripts: http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/scripts. html

Dazu müssen Sie ein benutzerdefiniertes Skript schreiben und ein benutzerdefiniertes Installationsprogramm, das ld mithilfe des benutzerdefinierten Skripts für die freigegebenen Objekte Ihres Clients ausführt. Dies setzt voraus, dass Ihr Kunde gcc oder ld in seinem Produktionssystem hat.

Chris
quelle
19

Was diese Nachricht vom dynamischen Glibc-Linker tatsächlich bedeutet, ist, dass die erwähnte Bibliothek ( /lib/libpam.so.0in Ihrem Fall) nicht über den VERDEFELF-Abschnitt verfügt, während die Binärdatei ( authpamin Ihrem Fall) einige Versionsdefinitionen im VERNEEDAbschnitt für diese Bibliothek enthält (vermutlich libpam.so.0). Sie können es leicht sehen mit readelf, schauen Sie sich nur .gnu.version_dund .gnu.version_rAbschnitte (oder deren Fehlen) an.

Es handelt sich also nicht um eine Nichtübereinstimmung der Symbolversion, denn wenn die Binärdatei eine bestimmte Version über erhalten wollte VERNEEDund die Bibliothek diese nicht in ihrer tatsächlichen VERDEFForm bereitstellte , wäre dies ein harter Linkerfehler und die Binärdatei würde überhaupt nicht ausgeführt ( so) im Vergleich zu diesem oder jenem ). Es ist so, dass die Binärdatei einige Versionen möchte, aber die Bibliothek keine Informationen zu ihren Versionen bereitstellt.

Was bedeutet das in der Praxis? Normalerweise genau das, was in diesem Beispiel zu sehen ist - nichts, die Dinge funktionieren einfach, wenn die Versionierung ignoriert wird. Könnten die Dinge kaputt gehen? Natürlich, ja, die anderen Antworten sind insofern richtig, als man zur Laufzeit dieselben Bibliotheken verwenden sollte, mit denen die Binärdatei zur Erstellungszeit verknüpft war.

Weitere Informationen finden Sie in Ulrich Dreppers "ELF Symbol Versioning" .

Roman Khimov
quelle
4
Ich empfehle 'readelf -V <exePath>' auszuführen, um den Versionsabschnitt zu sehen.
Beachten Sie
Ich hatte festgestellt, dass dies der Grund für die Warnung für (neuere! Systemversionen) Bibliotheken war, die ich selbst erstellt und in einem parallelen Präfix installiert habe. Ich habe immer gedacht, dass dies daran liegt, dass ich die LLVM-Toolchain verwende, aber ich habe gerade bemerkt, dass das Erstellen mit dem System gcc diese Versions-Tags nicht automatisch in die Bibliothek einfügt. Muss ich eine Option über CFLAGS und / oder LDFLAGS hinzufügen?
RJVB
4

Fwiw, ich hatte dieses Problem beim Ausführen von check_nrpe auf einem System, auf dem das Zenoss-Überwachungssystem installiert war. Um die Verwirrung zu vergrößern, funktionierte es gut als Root-Benutzer, aber nicht als Zenoss-Benutzer.

Ich fand heraus, dass der Zenoss-Benutzer einen LD_LIBRARY_PATH hatte, der dazu führte, dass er Zenoss-Bibliotheken verwendete, die diese Warnungen ausgeben. Dh:

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

Also, was ich damit sagen will: Überprüfen Sie auch Ihre Variablen wie LD_LIBRARY_PATH, LD_PRELOAD usw.

Dieter_be
quelle
3

Wie kompilierst du deine App? Welche Compiler-Flags?

Nach meiner Erfahrung sollten Sie Ihre Pakete auf der ältesten Version aufbauen, die Sie unterstützen möchten, wenn Sie auf den weiten Bereich der Linux-Systeme abzielen. Da mehr Systeme in der Regel abwärtskompatibel sind, funktioniert Ihre App weiterhin. Tatsächlich ist dies der ganze Grund für die Versionierung der Bibliothek - Gewährleistung der Abwärtskompatibilität.

Ted Percival
quelle
1

Hast du das gesehen ? schon gesehen? Die Ursache scheint eine sehr alte libpam auf einer der Seiten zu sein, wahrscheinlich auf diesem Kunden.

Oder die Links für die Version fehlen möglicherweise: http://www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html

Vinko Vrsalovic
quelle
Ich habe das gefunden, aber es hat nicht wirklich geholfen, die Ursache zu verstehen. Ich glaube nicht, dass es sich um eine alte Pam-Bibliothek handelt, da sie auf die neuesten Debian-Tests aktualisiert wurden.
Dann kompilieren Sie vielleicht auf einer alten Maschine? :) Haben Sie versucht, es auf dem Computer des Clients zu kompilieren? nondot.org/sabre/Mirrored/libtool-2.1a/libtool_toc.html#TOC36
Vinko Vrsalovic