Почему системы Unix / Linux не перемещаются по каталогам, пока не найдут требуемую версию связанной библиотеки?

17

У меня есть двоичный исполняемый файл с именем "альфа", который требует связанной библиотеки (libz.so.1.2.7), который находится на /home/username/myproduct/lib/libz.so.1.2.7

Я экспортирую то же самое в свой экземпляр терминала, прежде чем порождать мой двоичный исполняемый файл, выполнив следующую команду.

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

Теперь, когда я порождаю другое приложение "bravo", которое требует ту же библиотеку, но другой версии, т.е. (libz.so.1.2.8), которая доступна в /lib/x86_64-linux-gnu/libz.so.1.2.8, система выдает следующую ошибку.

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

Если я сбросил LD_LIBRARY_PATH, "Браво" запускается нормально. Я понимаю, что вышеупомянутое поведение связано с тем, что LD_LIBRARY_PATHимеет приоритет над путями каталогов, определенными /etc/ld.so.confпри поиске связанных библиотек, и, следовательно, произошла вышеуказанная ошибка Мне просто любопытно, почему разработчики UNIX / LINUX не разработали ОС для поиска связанных библиотек в других каталогах в соответствии с иерархией, если первый экземпляр библиотеки имеет другую версию.

Проще говоря, системы UNIX / LINUX проходят через набор каталогов, пока не найдут нужную библиотеку. Но почему он не делает то же самое, пока не найдет ожидаемую версию, а не примет первый экземпляр библиотеки независимо от ее версии?

daedalus_hamlet
источник
Я не совсем уверен, но я думаю, для безопасности. Лично я бы предпочел не беспокоиться о символической ссылке где-либо на моих машинах
Джо,
@Joe Во многих библиотеках есть символические ссылки, указывающие на них. libz.so.1является символической libz.so.1.2.8
Насир Райли

Ответы:

28

Но почему он не делает то же самое, пока не найдет ожидаемую версию, а не примет первый экземпляр библиотеки независимо от ее версии?

Это так, насколько это известно. zlib.so.1.2.7и zlib.so.1.2.8оба имеют сонаму zlib.so.1, так что ваши alphaи bravoдвоичные файлы говорят, что им нужно zlib.so.1. Динамический загрузчик загружает первую соответствующую ему библиотеку; он не знает, что версия 1.2.8 предоставляет дополнительные символы, которые bravoнужны. (Вот почему дистрибутивы стараются указать дополнительную информацию о зависимостях, например, zlib1g (>= 1.2.8)для bravo.)

Вы можете подумать, что это легко исправить, но это не так, не в последнюю очередь потому, что двоичные файлы и библиотеки перечисляют необходимые символы отдельно от библиотек, в которых они нуждаются, поэтому загрузчик не может проверить, что данная библиотека предоставляет все символы, которые нужны от этого. Символы могут быть предоставлены различными способами, и введение связи между символами и библиотеками, предоставляющими их, может сломать существующие двоичные файлы. Также добавлена ​​забавная вставка символов, которая усложняет ситуацию (и заставляет разработчиков, чувствительных к безопасности, рвать на себе волосы).

Некоторые библиотеки предоставляют информацию о версии, которая в конечном итоге сохраняется .gnu.version_r, со ссылкой на библиотеку, которая может помочь, но libzне является одной из них.

(Учитывая сонмы, я ожидаю, что ваш alphaбинарный файл будет работать нормально zlib.so.1.2.8.)

Стивен Китт
источник
И следует также отметить, что управление версиями библиотеки в стиле GNU отличается от семантического (-ish) управления версиями, к которому мы больше всего привыкли. Так как они имеют одно и то же «текущее» число, 1, zlib.so.1.2.8 не должен предоставлять никаких функций, которых не имеет zlib.so.1.2.7, поэтому не должно иметь значения (с точки зрения ABI), какой из них нашел. То, что это имеет значение, следует считать недостатком.
Джон Боллингер,
4
@ Джон нет, единственная гарантия состоит в том, что библиотеки с одинаковым сонамом обратно совместимы; более новые библиотеки могут добавлять функции, они не могут удалять или изменять их обратно несовместимым способом. То есть бинарный файл, созданный для zlib 1.2.7, будет работать с этим или любым более новым zlib 1; но бинарный файл, созданный для zlib 1.2.8, не обязательно будет работать со старым zlib 1. (И семантическое версионирование позволяет это; но обработка сонама не семантическое версионирование.)
Стивен Китт
1
Как я уже говорил, я говорю конкретно о соглашениях GNU и, в частности, думаю о libtool . Не каждый проект следует этому соглашению, поэтому, возможно, он слишком силен для того, чтобы называть zlib ошибочным, но, с другой стороны, даже семантически версионная интерпретация используемых номеров версий библиотеки приведет к такому же выводу. Нападающие (двоичная) совместимость в таких случаях не обещание присуще игнорирована, но это разумно ожидать в этом случае.
Джон Боллинджер
1
Да, я хорошо понимаю взаимосвязь между числами CRA и SOVERSION, которая возвращается к моей первоначальной точке зрения: ситуация, описанная OP, кажется несовместимой с правильным использованием схемы CRA . Избежание таких проблем, как ФП, является одной из ключевых целей этой схемы. Если zlib добавляет новый (версия a) двоичного интерфейса, то его число C должно быть увеличено. То, что такой удар может также привести к такому повороту, является вторичным.
Джон Боллинджер
2
@ Джон, верно, я подозреваю, что мы находимся в насильственном согласии и что я неправильно понял то, о чем ты говорил. zlibне использует в libtoolлюбом случае, кроме как на Дарвине, где это ar;-).
Стивен Китт