Apa yang dimaksud dengan kesalahan "informasi versi tidak tersedia" dari linux dynamic linker?

91

Dalam produk kami, kami mengirimkan beberapa binari linux yang secara dinamis terhubung ke pustaka sistem seperti "libpam". Pada beberapa sistem pelanggan kami mendapatkan kesalahan berikut pada stderr saat program berjalan:

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

Aplikasi berjalan dengan baik dan menjalankan kode dari pustaka dinamis. Jadi ini bukan kesalahan fatal, ini hanya peringatan.

Saya pikir ini adalah kesalahan yang berasal dari linker dinamis ketika perpustakaan yang diinstal sistem kehilangan sesuatu yang diharapkan dapat dieksekusi. Saya tidak tahu banyak tentang internal dari proses penautan dinamis ... dan mencari topik di Google tidak banyak membantu. :(

Adakah yang tahu apa yang menyebabkan kesalahan ini? ... bagaimana saya bisa mendiagnosis penyebabnya? ... dan bagaimana kita dapat mengubah file yang dapat dieksekusi untuk menghindari masalah ini?

Pembaruan: Pelanggan meningkatkan ke versi terbaru dari "pengujian" debian dan kesalahan yang sama terjadi. Jadi ini bukan perpustakaan libpam yang ketinggalan zaman. Saya rasa saya ingin memahami apa yang dikeluhkan oleh linker? Bagaimana saya bisa menyelidiki penyebab yang mendasari, dll?


sumber

Jawaban:

65

"Tidak ada informasi versi yang tersedia" berarti nomor versi perpustakaan lebih rendah pada objek bersama. Misalnya, jika nomor major.minor.patch Anda adalah 7.15.5 pada mesin tempat Anda membuat biner, dan nomor major.minor.patch adalah 7.12.1 pada mesin instalasi, ld akan mencetak peringatan.

Anda dapat memperbaikinya dengan mengompilasi menggunakan pustaka (header dan objek bersama) yang cocok dengan versi objek bersama yang dikirimkan dengan OS target Anda. Misalnya, jika Anda akan menginstal ke RedHat 3.4.6-9, Anda tidak ingin mengkompilasi di Debian 4.1.1-21. Ini adalah salah satu alasan mengapa sebagian besar distribusi dikirimkan untuk nomor distro linux tertentu.

Jika tidak, Anda dapat menautkan secara statis. Namun, Anda tidak ingin melakukan ini dengan sesuatu seperti PAM, jadi Anda ingin menginstal lingkungan pengembangan yang cocok dengan lingkungan produksi klien Anda (atau setidaknya menginstal dan menautkan ke versi pustaka yang benar.)

Saran Anda untuk mengganti nama file .so (melapisinya dengan nomor versi,) berasal dari saat perpustakaan objek bersama tidak menggunakan simbol berversi. Jadi jangan berharap bahwa bermain dengan skema penamaan .so.nnn akan membantu (banyak - mungkin membantu jika sistem Anda telah dibuang.)

Opsi terakhir Anda akan mengompilasi dengan pustaka dengan nomor versi minor yang berbeda, menggunakan skrip tautan ubahsuaian: http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/scripts. html

Untuk melakukannya, Anda harus menulis skrip khusus, dan Anda memerlukan penginstal khusus yang menjalankan ld pada objek bersama klien Anda, menggunakan skrip khusus. Ini mengharuskan klien Anda memiliki gcc atau ld di sistem produksinya.

Chris
sumber
22

Maksud sebenarnya dari pesan dari glibc dynamic linker ini adalah bahwa pustaka yang disebutkan ( /lib/libpam.so.0dalam kasus Anda) tidak memiliki bagian VERDEFELF sementara biner ( authpamdalam kasus Anda) memiliki beberapa definisi versi di VERNEEDbagian untuk pustaka ini (mungkin, libpam.so.0). Anda dapat dengan mudah melihatnya dengan readelf, cukup lihat .gnu.version_ddan .gnu.version_rbagian (atau ketiadaan).

Jadi ini bukan ketidakcocokan versi simbol, karena jika biner ingin mendapatkan beberapa versi tertentu melalui VERNEEDdan pustaka tidak menyediakannya secara aktual VERDEF, itu akan menjadi kesalahan tautan keras dan biner tidak akan berjalan sama sekali (seperti ini dibandingkan dengan ini atau itu ). Biner menginginkan beberapa versi, tetapi pustaka tidak memberikan informasi apa pun tentang versinya.

Apa artinya dalam praktik? Biasanya, persis apa yang terlihat dalam contoh ini - tidak ada, hal-hal hanya berfungsi mengabaikan pembuatan versi. Bisakah hal-hal pecah? Tentu saja, ya, jadi jawaban lain benar dalam kenyataan bahwa seseorang harus menggunakan pustaka yang sama pada waktu proses seperti pustaka yang ditautkan ke biner pada waktu pembuatan.

Informasi lebih lanjut dapat ditemukan di Ulrich Dreppers "ELF Symbol Versioning" .

Roman Khimov
sumber
5
Saya sarankan menjalankan 'readelf -V <exePath>' untuk melihat bagian pembuatan versi. perhatikan modal V
Rayee Roded
Saya telah menyimpulkan bahwa ini adalah alasan peringatan untuk (versi sistem yang lebih baru!) Pustaka yang saya buat sendiri dan pasang dalam awalan paralel. Saya selalu berpikir itu karena saya menggunakan toolchain LLVM, tetapi saya baru menyadari bahwa membangun dengan sistem gcc tidak menempatkan tag versi tersebut ke dalam perpustakaan secara otomatis. Apakah saya perlu menambahkan opsi melalui CFLAGS dan / atau LDFLAGS?
RJVB
5

Fwiw, saya mengalami masalah ini saat menjalankan check_nrpe pada sistem yang menginstal sistem pemantauan zenoss. Untuk menambah kebingungan, ini berfungsi dengan baik sebagai pengguna root tetapi tidak sebagai pengguna zenoss.

Saya menemukan bahwa pengguna zenoss memiliki LD_LIBRARY_PATH yang menyebabkannya menggunakan pustaka zenoss, yang mengeluarkan peringatan ini. Yaitu:

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

Jadi, apa yang ingin saya katakan: periksa variabel Anda seperti LD_LIBRARY_PATH, LD_PRELOAD dll juga.

Dieter_be
sumber
3

Bagaimana Anda menyusun aplikasi Anda? Bendera kompiler apa?

Dalam pengalaman saya, ketika menargetkan ranah luas sistem Linux di luar sana, buat paket Anda pada versi terlama yang ingin Anda dukung, dan karena lebih banyak sistem cenderung kompatibel ke belakang, aplikasi Anda akan terus berfungsi. Sebenarnya ini adalah seluruh alasan untuk versi perpustakaan - memastikan kompatibilitas ke belakang.

Ted Percival
sumber
1

Sudahkah kau melihat ini ? Penyebabnya tampaknya libpam yang sangat tua di salah satu sisi, mungkin pada pelanggan itu.

Atau tautan untuk versi tersebut mungkin hilang: http://www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html

Vinko Vrsalovic
sumber
Aku memang menemukan yang satu itu, tapi itu tidak membantu memahami penyebabnya. Menurut saya ini bukan pustaka pam lama, karena mereka memperbarui ke pengujian debian terbaru.
Lalu mungkin Anda mengompilasi di mesin lama? :) Sudahkah Anda mencoba mengompilasinya di komputer klien? nondot.org/sabre/Mirrored/libtool-2.1a/libtool_toc.html#TOC36
Vinko Vrsalovic