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

90

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

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

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

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

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

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


источник

Ответы:

64

«Информация о версии недоступна» означает, что номер версии библиотеки для общего объекта ниже. Например, если ваш номер 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.nnn поможет (очень - может помочь, если ваша система была разрушена).

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

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

Крис
источник
21

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

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

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

Дополнительную информацию можно найти в Ульрихе Дрепперсе "Управление версиями символов ELF" .

Роман Химов
источник
5
Я рекомендую запустить readelf -V <exePath>, чтобы просмотреть раздел управления версиями. заглавная
Rayee Roded
Я пришел к выводу, что это было причиной предупреждения для (более новых! Версий системы) библиотек, которые я создаю сам и устанавливаю с параллельным префиксом. Я всегда думал, что это потому, что я использую набор инструментов LLVM, но я просто заметил, что сборка с использованием системы gcc не помещает эти теги версий в библиотеку автоматически. Нужно ли мне добавлять опцию через CFLAGS и / или LDFLAGS?
RJVB
5

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

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

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

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

Dieter_be
источник
3

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

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

Тед Персиваль
источник
1

Вы это уже видели ? Причина, по-видимому, в очень старом libpam на одной из сторон, вероятно, на этом клиенте.

Или ссылки на версию могут отсутствовать: http://www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html

Винко Врсалович
источник
Я нашел его, но это не помогло понять причину. Я не думаю, что это старая библиотека pam, потому что они обновились до последней версии тестирования debian.
Тогда может быть компилируете на старой машине? :) Вы пробовали компилировать на машине клиента? nondot.org/sabre/Mirrored/libtool-2.1a/libtool_toc.html#TOC36
Винко Врсалович,