Що означає помилка "інформація про версію недоступна" від динамічного компонувача Linux?


89

У нашому продукті ми поставляємо деякі двійкові файли Linux, які динамічно зв'язуються із системними бібліотеками, такими як "libpam". У деяких системах клієнтів ми отримуємо таку помилку на stderr під час запуску програми:

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

Додаток працює нормально і виконує код з динамічної бібліотеки. Отже, це не фатальна помилка, це насправді лише попередження.

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

Хтось знає, що спричиняє цю помилку? ... як я можу діагностувати причину? ... і як ми могли б змінити наші виконувані файли, щоб уникнути цієї проблеми?

Оновлення: Клієнт оновив до останньої версії «тестування» debian, і сталася та сама помилка. Тож це не застаріла бібліотека 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, що буде важко помилка линкера і виконавчі не працюватиме взагалі (як це порівняно з тим чи іншим ). Це те, що двійковий файл хоче деякі версії, але бібліотека не надає ніякої інформації про свої версії.

Що це означає на практиці? Зазвичай, саме те, що видно в цьому прикладі - нічого, все працює, ігноруючи встановлення версій. Чи можуть речі зламатися? Звичайно, так, тому інші відповіді є вірними в тому, що під час виконання слід використовувати ті самі бібліотеки, що і ті, з якими був пов’язаний двійковий файл під час побудови.

Більше інформації можна знайти в Ulrich Dreppers "ELF Symbol Versioning " .


5
Я рекомендую запустити 'readelf -V <exePath>', щоб побачити розділ версій. зверніть увагу на
велику

Я зрозумів, що це була причина попередження для (новіших версій системних) бібліотек, які я будую сам і встановлюю в паралельний префікс. Я завжди думав, що це тому, що я використовую ланцюжок інструментів 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 тощо.


3

Як ви складаєте програму? Які прапори компілятора?

З мого досвіду, будучи націленим на величезну сферу систем Linux, будуйте свої пакети на найстарішій версії, яку ви готові підтримувати, і оскільки більшість систем, як правило, мають зворотну сумісність, ваш додаток буде продовжувати працювати. Власне в цьому полягає вся причина бібліотечного керування версіями - забезпечення зворотної сумісності.


1

Ви вже це бачили ? Причиною є дуже стара лібпа з одного з боків, ймовірно, у цього клієнта.

Або посилання на версію можуть бути відсутніми: http://www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html


Я його знайшов, але це насправді не допомогло зрозуміти причину. Я не думаю, що це стара бібліотека пам, тому що вони оновили до останнього тестування debian.

Тоді, можливо, ви компілюєте на старій машині? :) Ви пробували складати його на машині клієнта? nondot.org/sabre/Mirrored/libtool-2.1a/libtool_toc.html#TOC36
Вінко Врсалович,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.