Что означает ошибка "отсутствие информации о версии" из динамического компоновщика linux?

В нашем продукте мы отправляем несколько linux файлов, которые динамически связывают с системными библиотеками типа libpam. В некоторых системах клиентов мы получаем следующую ошибку при запуске программы stderr:

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

Приложение отлично работает и выполняет код из динамической библиотеки. Таким образом, это не фатальная ошибка, это действительно просто предупреждение.

Я полагаю, что эта ошибка возникает из динамического компоновщика, когда система, установленная в библиотеке, пропускает то, что ожидает наш исполняемый файл. Я не очень разбираюсь в внутренних процессах динамического связывания... и googling тема не очень помогает.: (

Кто-нибудь знает, что вызывает эту ошибку?... как я могу диагностировать причину?... и как мы могли бы изменить наши исполняемые файлы, чтобы избежать этой проблемы?

Обновление: клиент обновился до последней версии debian "testing" и произошла ошибка. Так что это не устаревшая библиотека libpam. Думаю, я хотел бы понять, о чем жалуется компоновщик? Как я могу исследовать основную причину и т.д.

Ответ 1

"Отсутствие информации о версии" означает, что номер версии библиотеки ниже на общем объекте. Например, если ваш номер major.minor.patch равен 7.15.5 на машине, где вы создаете двоичный файл, а номер major.minor.patch равен 7.12.1 на установочной машине, ld выведет предупреждение.

Вы можете исправить это, скомпилировав библиотеку (заголовки и общие объекты), которая соответствует версии общего объекта, поставляемой с вашей целевой ОС. Например, если вы собираетесь установить RedHat 3.4.6-9, вы не хотите компилировать его на Debian 4.1.1-21. Это одна из причин, по которой большинство дистрибутивов отправляются для конкретных дистрибутивных номеров Linux.

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

Советуем вам переименовать файлы .so(заполняя их номерами версий), из-за того, что в библиотеках общих объектов не использовались версированные символы. Поэтому не ожидайте, что игра с использованием схемы именования .so.n.n.n поможет (много - это может помочь, если ваша система была повреждена.)

Последняя опция будет компилироваться в библиотеке с другим младшим номером версии, используя настраиваемую ссылку script: http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/scripts.html

Для этого вам нужно написать пользовательский script, и вам понадобится специальный установщик, который запускает ld против ваших общих объектов клиента, используя пользовательский script. Это требует, чтобы ваш клиент имел gcc или ld в своей производственной системе.

Ответ 2

На самом деле это сообщение от динамического компоновщика glibc означает, что упомянутая библиотека (/lib/libpam.so.0 в вашем случае) не имеет секции VERDEF ELF, тогда как двоичный файл (authpam в вашем случае) имеет некоторую версию определения в разделе VERNEED для этой библиотеки (предположительно, libpam.so.0). Вы можете легко увидеть его с помощью readelf, просто посмотрите разделы .gnu.version_d и .gnu.version_r (или их отсутствие).

Итак, это не ошибка отображения символов, потому что если бы двоичный код хотел получить определенную версию через VERNEED, и библиотека не предоставила ее в ее фактическом VERDEF, это была бы жесткая ошибка компоновщика и двоичная (например, this по сравнению с этим или что). Это то, что бинарные файлы хотят некоторых версий, но библиотека не предоставляет никакой информации о ее версиях.

Что это означает на практике? Обычно именно то, что видно в этом примере -— ничего, все просто работает, игнорируя управление версиями. Могут ли вещи сломаться? Конечно, да, поэтому другие ответы правильны в том, что во время выполнения нужно использовать те же библиотеки, что и те, с которыми был связан бинар во время сборки.

Более подробную информацию можно найти в Ulrich Dreppers Верстка символов ELF.

Ответ 3

Fwiw, эта проблема возникла при запуске check_nrpe в системе, на которой установлена ​​система мониторинга zenoss. Чтобы добавить к путанице, он отлично работал как пользователь root, но не как пользователь zenoss.

Я узнал, что у пользователя zenoss был LD_LIBRARY_PATH, который заставил его использовать библиотеки zenoss, которые выдают эти предупреждения. То есть:

[email protected]:$ echo $LD_LIBRARY_PATH

su - zenoss
[email protected]:/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::
[email protected]:/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)
(...)
[email protected]:/root$ LD_LIBRARY_PATH= /usr/lib/nagios/plugins/check_nrpe -H 192.168.61.61 -p 6969 -c check_mq
(...)

Так или иначе, что я пытаюсь сказать: проверьте свои переменные, например LD_LIBRARY_PATH, LD_PRELOAD и т.д.

Ответ 4

Как вы компилируете свое приложение? Какие флаги компилятора?

По моему опыту, когда вы ориентируетесь на обширную область Linux-систем, создайте свои пакеты на самой старой версии, которую вы хотите поддерживать, и потому что больше систем, как правило, совместимо с обратной связью, ваше приложение будет продолжать работать. Фактически, это и есть причина для управления версиями библиотеки - обеспечение обратной совместимости.

Ответ 6

Вам нужно указать операционную систему, если вы используете Mac OS: OSX, для других вам нужно искать конкретный и установить в вашей конфигурации (например, в ваших файлах .yml).