Dlaczego systemy Unix / Linux nie przeglądają katalogów, dopóki nie znajdą wymaganej wersji połączonej biblioteki?

17

Mam binarny plik wykonywalny o nazwie „alpha”, który wymaga połączonej biblioteki (libz.so.1.2.7), która jest umieszczona w /home/username/myproduct/lib/libz.so.1.2.7

Eksportuję to samo do mojej instancji terminala przed spawnem mojego binarnego pliku wykonywalnego, wykonując następujące polecenie.

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

Teraz, gdy odradzam inną aplikację „brawo”, która wymaga tej samej biblioteki, ale innej wersji, tj. (Libz.so.1.2.8), która jest dostępna w /lib/x86_64-linux-gnu/libz.so.1.2.8systemie, system generuje następujący błąd.

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

Jeśli wyłączę LD_LIBRARY_PATH, „brawo” zacznie się dobrze. Rozumiem, że powyższe zachowanie jest LD_LIBRARY_PATHnadrzędne, ponieważ ma pierwszeństwo przed ścieżkami katalogu zdefiniowanymi /etc/ld.so.confpodczas wyszukiwania bibliotek połączonych, w wyniku czego wystąpił powyższy błąd. Jestem tylko ciekawy, dlaczego programiści UNIX / LINUX nie zaprojektowali systemu operacyjnego do wyszukiwania bibliotek połączonych w innych katalogach zgodnie z hierarchią, jeśli pierwsza instancja biblioteki ma inną wersję.

Mówiąc najprościej, systemy UNIX / LINUX przechodzą przez zestaw katalogów, aż znajdzie wymaganą bibliotekę. Ale dlaczego nie robi tego samego, dopóki nie znajdzie oczekiwanej wersji, zamiast zaakceptować pierwszą instancję biblioteki niezależnie od jej wersji?

daedalus_hamlet
źródło
Nie jestem do końca pewien, ale zgaduję dla bezpieczeństwa. Osobiście wolałbym nie martwić się o sym-link gdziekolwiek na moich komputerach
Joe
@Joe Wiele bibliotek ma same linki dowiązania do nich. libz.so.1jest dowiązaniem symbolicznym dolibz.so.1.2.8
Nasir Riley z

Odpowiedzi:

28

Ale dlaczego nie robi tego samego, dopóki nie znajdzie oczekiwanej wersji, zamiast zaakceptować pierwszą instancję biblioteki niezależnie od jej wersji?

Tak, o ile jest to świadome. zlib.so.1.2.7i zlib.so.1.2.8oba mają soname zlib.so.1, więc twoja alphai bravobinaria mówią, że potrzebują zlib.so.1. Dynamiczny moduł ładujący ładuje pierwszą znalezioną bibliotekę; nie wie, że wersja 1.2.8 zapewnia dodatkowe symbole, które bravopotrzebują. (Właśnie dlatego dystrybucje starają się określić dodatkowe informacje o zależnościach, takie jak zlib1g (>= 1.2.8)dla bravo.)

Można by pomyśleć, że powinno to być łatwe do naprawienia, ale tak nie jest, między innymi dlatego, że binaria i biblioteki zawierają listę potrzebnych symboli oddzielnie od bibliotek, których potrzebują, więc moduł ładujący nie może sprawdzić, czy dana biblioteka zawiera wszystkie symbole, które są z tego potrzebne. Symbole mogą być udostępniane na różne sposoby, a wprowadzenie połączenia między symbolami a bibliotekami, które je udostępnią, może zniszczyć istniejące pliki binarne. Dodatkową zabawą jest wstawianie symboli, aby komplikować rzeczy (i sprawić, by programiści wrażliwi na bezpieczeństwo odrywali włosy).

Niektóre biblioteki zawierają informacje o wersji, które ostatecznie są przechowywane .gnu.version_r, wraz z linkiem do dostarczającej biblioteki, co by tu pomogło, ale libznie jest jedną z nich.

(Biorąc pod uwagę sonames, oczekiwałbym, że twój alphaplik binarny będzie działał dobrze zlib.so.1.2.8).

Stephen Kitt
źródło
Należy również zauważyć, że wersja biblioteki w stylu GNU różni się od wersji semantycznej (-ish), z którą jesteśmy najbardziej przyzwyczajeni. Ponieważ mają one ten sam „bieżący” numer, 1, zlib.so.1.2.8 nie powinien zapewniać żadnych funkcji, których nie ma zlib.so.1.2.7, dlatego nie powinno mieć znaczenia (z perspektywy ABI), który z nich jest znaleziony. To, że ma znaczenie, należy uznać za wadę.
John Bollinger
4
@John nie, jedyną gwarancją jest to, że biblioteki z tą samą soname są kompatybilne wstecz; nowsze biblioteki mogą dodawać funkcje, nie mogą ich usuwać ani zmieniać w sposób niezgodny wstecz. Oznacza to, że plik binarny zbudowany na Zlib 1.2.7 będzie działał z tym lub dowolnym nowszym Zlib 1; ale plik binarny zbudowany na Zlib 1.2.8 niekoniecznie działa ze starszym Zlib 1. (I pozwala na to wersja semantyczna; ale obsługa soname nie jest wersją semantyczną.)
Stephen Kitt
1
Mówię konkretnie o konwencjach GNU, tak jak powiedziałem, i chyba o libtool w szczególności. Nie każdy projekt jest zgodny z tą konwencją, więc być może jest zbyt mocny, aby nazwać zlib wadliwym, ale z drugiej strony nawet interpretacja numerów wersji bibliotek w wersji semantycznej doszłaby do tego samego wniosku. Zgodność przekazywania (binarna) w takich przypadkach nie jest obietnicą związaną z soname, ale jest uzasadnionym oczekiwaniem w tym przypadku.
John Bollinger
1
Tak, dobrze rozumiem związek między numerami CRA a SOVERSION, który powraca do mojego pierwotnego punktu: sytuacja opisana przez OP wydaje się być niespójna z prawidłowym użyciem schematu CRA . Unikanie problemów, takich jak PO, jest jednym z kluczowych celów tego programu. Jeśli zlib doda nowy (binarny) interfejs binarny, wówczas jego liczbę C należy zwiększyć. To, że taki guz może również prowadzić do wstrząsu soversion, ma drugorzędne znaczenie.
John Bollinger
2
@John racja, podejrzewam, że jesteśmy w brutalnej umowie i że źle zrozumiałem twoją uwagę. zlibi tak nie używa libtool, z wyjątkiem Darwina, gdzie to jest ar;-).
Stephen Kitt