Warum durchlaufen Unix / Linux-Systeme keine Verzeichnisse, bis sie die erforderliche Version einer verknüpften Bibliothek gefunden haben?

17

Ich habe eine ausführbare Binärdatei mit dem Namen "alpha", für die eine verknüpfte Bibliothek (libz.so.1.2.7) erforderlich ist, die unter abgelegt wird /home/username/myproduct/lib/libz.so.1.2.7

Ich exportiere dasselbe in meine Terminal-Instanz, bevor ich meine ausführbare Binärdatei durch Ausführen des folgenden Befehls spawne.

export LD_LIBRARY_PATH=/home/username/myproduct/lib/:$LD_LIBRARY_PATH

Wenn ich nun eine andere Anwendung "bravo" spawne, die dieselbe Bibliothek, aber eine andere Version benötigt, dh (libz.so.1.2.8), die in verfügbar ist /lib/x86_64-linux-gnu/libz.so.1.2.8, gibt das System den folgenden Fehler aus.

version `ZLIB_1.2.3.3' not found (required by /usr/lib/x86_64-linux-gnu/libxml2.so.2)

Wenn ich das deaktiviere LD_LIBRARY_PATH, läuft "bravo" gut an. Ich verstehe, dass das obige Verhalten darauf zurückzuführen ist, dass es LD_LIBRARY_PATHVorrang vor den in definierten Verzeichnispfaden hat, /etc/ld.so.confwährend nach verknüpften Bibliotheken gesucht wird. Infolgedessen ist der obige Fehler aufgetreten. Ich bin nur neugierig, warum die Entwickler von UNIX / LINUX das Betriebssystem nicht für die Suche nach verknüpften Bibliotheken in anderen Verzeichnissen gemäß der Hierarchie entworfen haben, wenn die erste Instanz der Bibliothek eine andere Version hat.

Vereinfacht gesagt durchlaufen UNIX / LINUX-Systeme eine Reihe von Verzeichnissen, bis die erforderliche Bibliothek gefunden wurde. Aber warum macht es nicht dasselbe, bis es die erwartete Version findet, anstatt die erste Instanz der Bibliothek unabhängig von ihrer Version zu akzeptieren?

daedalus_hamlet
quelle
Ich bin nicht ganz sicher, aber ich würde aus Sicherheitsgründen raten. Ich persönlich würde mir lieber keine Sorgen um einen Sym-Link irgendwo auf meinen Maschinen machen müssen
Joe,
@ Joe Viele der Bibliotheken selbst haben Symlinks, die auf sie verweisen. libz.so.1ist ein Symlink zulibz.so.1.2.8
Nasir Riley

Antworten:

28

Aber warum macht es nicht dasselbe, bis es die erwartete Version findet, anstatt die erste Instanz der Bibliothek unabhängig von ihrer Version zu akzeptieren?

Soweit bekannt. zlib.so.1.2.7und zlib.so.1.2.8beide haben einen Sonamen von zlib.so.1, also sagen deine alphaund die bravoBinärdateien, dass sie brauchen zlib.so.1. Der Dynamic Loader lädt die erste gefundene passende Bibliothek. Es ist nicht bekannt, dass Version 1.2.8 zusätzliche Symbole bereitstellt, die bravobenötigt werden. (Aus diesem Grund bemühen sich Verteilungen, zusätzliche Abhängigkeitsinformationen anzugeben, z. B. zlib1g (>= 1.2.8)für bravo.)

Möglicherweise sollte dies leicht zu beheben sein, aber nicht zuletzt, weil Binärdateien und Bibliotheken die benötigten Symbole getrennt von den benötigten Bibliotheken auflisten, sodass der Loader nicht überprüfen kann, ob eine bestimmte Bibliothek alle diese Symbole enthält werden davon benötigt. Symbole können auf verschiedene Arten bereitgestellt werden, und das Einfügen einer Verknüpfung zwischen Symbolen und den Bibliotheken, die diese bereitstellen, kann vorhandene Binärdateien beschädigen. Es gibt auch den zusätzlichen Spaß, Symbole einzufügen, um die Dinge zu komplizieren (und sicherheitsrelevante Entwickler dazu zu bringen, sich die Haare auszureißen).

Einige Bibliotheken stellen Versionsinformationen bereit, die letztendlich in gespeichert werden .gnu.version_r, mit einem Link zur bereitstellenden Bibliothek, der hier hilfreich wäre, aber libzkeiner von ihnen ist.

(Angesichts der Sonamen würde ich erwarten, dass Ihre alphaBinärdatei gut funktioniert zlib.so.1.2.8.)

Stephen Kitt
quelle
Und man sollte auch beachten, dass sich die Versionierung von GNU-Bibliotheken von der semantischen (-ish) Versionierung unterscheidet, mit der wir uns am meisten auskennen. Da sie die gleiche "aktuelle" Nummer 1 haben, sollte zlib.so.1.2.8 keine Funktionen bieten, die zlib.so.1.2.7 nicht bietet, daher sollte es (aus ABI-Sicht) keine Rolle spielen, um welche es sich handelt gefunden. Dass es wichtig ist, sollte als Fehler angesehen werden.
John Bollinger
4
@ John nein, die einzige Garantie ist, dass Bibliotheken mit demselben Sonamen abwärtskompatibel sind. Neuere Bibliotheken können Features hinzufügen, keine entfernen oder in einer abwärtskompatiblen Weise ändern. Das heißt, eine Binärdatei, die gegen zlib 1.2.7 erstellt wurde, funktioniert mit dieser oder einer neueren zlib 1; Eine Binärdatei, die gegen zlib 1.2.8 erstellt wurde, funktioniert jedoch nicht unbedingt mit einer älteren zlib 1. (Und die semantische Versionierung ermöglicht dies; die Behandlung von Sonamen ist jedoch keine semantische Versionierung.)
Stephen Kitt
1
Ich spreche, wie gesagt, speziell über GNU-Konventionen und insbesondere über libtool . Nicht jedes Projekt folgt dieser Konvention. Vielleicht ist es zu stark, um zlib als fehlerhaft zu bezeichnen, aber auf der anderen Seite würde auch eine semantische Interpretation der Versionsnummern der Bibliothek zu demselben Ergebnis führen. Vorwärts (binär) Kompatibilität in solchen Fällen ist kein Versprechen , die sich aus der soname, aber es ist eine vernünftige Erwartung in diesem Fall.
John Bollinger
1
Ja, ich verstehe die Beziehung zwischen CRA-Nummern und SOVERSION sehr gut, was wieder zu meinem ursprünglichen Punkt zurückkehrt: Die vom OP beschriebene Situation scheint mit der korrekten Anwendung des CRA-Schemas unvereinbar zu sein . Die Vermeidung von Problemen wie den OP ist eines der Hauptziele dieser Regelung. Wenn zlib eine neue (Version von a) Binärschnittstelle hinzufügt, sollte deren C-Nummer erhöht werden. Dass eine solche Beule auch zu einer Soversions-Beule führen kann, ist zweitrangig.
John Bollinger
2
@ John richtig, ich vermute, wir sind uns gewaltsam einig und dass ich den Punkt falsch verstanden habe, den Sie gemacht haben. zlibwird libtoolsowieso nicht verwendet , außer auf Darwin, wo es ist ar;-).
Stephen Kitt