Lỗi “không có thông tin phiên bản” từ trình liên kết động linux nghĩa là gì?


89

Trong sản phẩm của chúng tôi, chúng tôi gửi một số tệp nhị phân linux liên kết động với các thư viện hệ thống như "libpam". Trên một số hệ thống của khách hàng, chúng tôi gặp lỗi sau trên stderr khi chương trình chạy:

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

Ứng dụng chạy tốt và thực thi mã từ thư viện động. Vì vậy, đây không phải là một lỗi nghiêm trọng, nó thực sự chỉ là một cảnh báo.

Tôi cho rằng đây là lỗi đến từ trình liên kết động khi thư viện được cài đặt hệ thống bị thiếu thứ gì đó mà tệp thực thi của chúng tôi mong đợi. Tôi không biết nhiều về nội dung của quá trình liên kết động ... và việc truy cập chủ đề này không giúp được gì nhiều. :(

Bất cứ ai biết những gì gây ra lỗi này? ... làm thế nào tôi có thể chẩn đoán nguyên nhân? ... và làm thế nào chúng ta có thể thay đổi các tệp thực thi của mình để tránh vấn đề này?

Cập nhật: Khách hàng đã nâng cấp lên phiên bản mới nhất của debian "testing" và xảy ra lỗi tương tự. Vì vậy, nó không phải là một thư viện libpam lỗi thời. Tôi đoán tôi muốn hiểu trình liên kết đang phàn nàn về điều gì? Làm cách nào để điều tra nguyên nhân cơ bản, v.v.?

Câu trả lời:


64

"Không có thông tin phiên bản có sẵn" có nghĩa là số phiên bản thư viện thấp hơn trên đối tượng được chia sẻ. Ví dụ: nếu số major.minor.patch của bạn là 7.15.5 trên máy mà bạn tạo nhị phân và số major.minor.patch là 7.12.1 trên máy cài đặt, ld sẽ in cảnh báo.

Bạn có thể khắc phục điều này bằng cách biên dịch với thư viện (tiêu đề và đối tượng được chia sẻ) khớp với phiên bản đối tượng chia sẻ được vận chuyển với hệ điều hành mục tiêu của bạn. Ví dụ: nếu bạn định cài đặt RedHat 3.4.6-9, bạn không muốn biên dịch trên Debian 4.1.1-21. Đây là một trong những lý do mà hầu hết các bản phân phối vận chuyển cho các số phân phối linux cụ thể.

Nếu không, bạn có thể liên kết tĩnh. Tuy nhiên, bạn không muốn làm điều này với thứ gì đó như PAM, vì vậy bạn muốn thực sự cài đặt một môi trường phát triển phù hợp với môi trường sản xuất của khách hàng của bạn (hoặc ít nhất là cài đặt và liên kết với các phiên bản thư viện chính xác.)

Lời khuyên bạn nên đổi tên các tệp .so (đệm chúng bằng số phiên bản,) bắt nguồn từ thời điểm khi các thư viện đối tượng được chia sẻ không sử dụng các ký hiệu được phiên bản. Vì vậy, đừng mong đợi rằng việc chơi với lược đồ đặt tên .so.nnn sẽ giúp ích (nhiều - nó có thể hữu ích nếu hệ thống của bạn đã bị chuyển vào thùng rác.)

Tùy chọn cuối cùng của bạn sẽ được biên dịch với một thư viện có số phiên bản nhỏ khác, sử dụng tập lệnh liên kết tùy chỉnh: http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/scripts. html

Để làm điều này, bạn sẽ cần viết một tập lệnh tùy chỉnh và bạn sẽ cần một trình cài đặt tùy chỉnh chạy ld dựa trên các đối tượng được chia sẻ của khách hàng của bạn, sử dụng tập lệnh tùy chỉnh. Điều này yêu cầu khách hàng của bạn phải có gcc hoặc ld trên hệ thống sản xuất của họ.


21

Thông báo này từ trình liên kết động glibc thực sự có nghĩa là thư viện được đề cập ( /lib/libpam.so.0trong trường hợp của bạn) không có phần VERDEFELF trong khi tệp nhị phân ( authpamtrong trường hợp của bạn) có một số định nghĩa phiên bản trong VERNEEDphần cho thư viện này (có lẽ, libpam.so.0). Bạn có thể dễ dàng nhìn thấy nó readelf, chỉ cần nhìn vào .gnu.version_d.gnu.version_rcác phần (hoặc thiếu chúng).

Vì vậy, nó không phải là phiên bản ký hiệu không khớp, bởi vì nếu hệ nhị phân muốn lấy một số phiên bản cụ thể thông qua VERNEEDvà thư viện không cung cấp nó trong thực tế của nó VERDEF, đó sẽ là lỗi trình liên kết cứng và tệp nhị phân sẽ không chạy (như thế này so với cái này hay cái kia ). Đó là hệ nhị phân muốn một số phiên bản, nhưng thư viện không cung cấp bất kỳ thông tin nào về các phiên bản của nó.

Nó có ý nghĩa gì trong thực tế? Thông thường, chính xác những gì được thấy trong ví dụ này - không có gì, mọi thứ chỉ hoạt động khi bỏ qua việc lập phiên bản. Mọi thứ có thể bị vỡ? Tất nhiên, có, vì vậy các câu trả lời khác đúng trong thực tế là người ta nên sử dụng cùng một thư viện trong thời gian chạy như những thư viện mà hệ nhị phân được liên kết tại thời điểm xây dựng.

Thông tin thêm có thể được tìm thấy trong Ulrich Dreppers "Phiên bản biểu tượng ELF" .


5
Tôi khuyên bạn nên chạy 'readelf -V <exePath>' để xem phần lập phiên bản. thông báo vốn V
Rayee Roded

Tôi đã suy luận rằng đây là lý do của cảnh báo cho các thư viện (phiên bản hệ thống mới hơn) mà tôi tự xây dựng và cài đặt trong một tiền tố song song. Tôi luôn nghĩ đó là do tôi sử dụng chuỗi công cụ LLVM, nhưng tôi chỉ nhận thấy rằng việc xây dựng với gcc hệ thống không tự động đưa các thẻ phiên bản đó vào thư viện. Tôi có cần thêm tùy chọn qua CFLAGS và / hoặc LDFLAGS không?
RJVB

5

Fwiw, tôi đã gặp sự cố này khi chạy check_nrpe trên hệ thống đã cài đặt hệ thống giám sát zenoss. Để thêm vào sự nhầm lẫn, nó hoạt động tốt với tư cách là người dùng root nhưng không hoạt động tốt như người dùng zenoss.

Tôi phát hiện ra rằng người dùng zenoss có LD_LIBRARY_PATH khiến nó sử dụng các thư viện zenoss, điều này đưa ra các cảnh báo này. I E:

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

Vì vậy, dù sao, điều tôi đang cố gắng nói: hãy kiểm tra các biến của bạn như LD_LIBRARY_PATH, LD_PRELOAD, v.v.


3

Bạn đang biên dịch ứng dụng của mình như thế nào? Cờ trình biên dịch nào?

Theo kinh nghiệm của tôi, khi nhắm mục tiêu vào phạm vi rộng lớn của các hệ thống Linux ngoài kia, hãy xây dựng các gói của bạn trên phiên bản cũ nhất mà bạn sẵn sàng hỗ trợ và vì nhiều hệ thống có xu hướng tương thích ngược nên ứng dụng của bạn sẽ tiếp tục hoạt động. Trên thực tế, đây là toàn bộ lý do cho việc tạo phiên bản thư viện - đảm bảo tính tương thích ngược.


1

Bạn đã thấy điều này chưa? Nguyên nhân dường như là do libpam rất cũ ở một trong những bên, có thể là do khách hàng đó.

Hoặc các liên kết cho phiên bản có thể bị thiếu: http://www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html


Tôi đã tìm thấy điều đó, nhưng nó không thực sự giúp hiểu được nguyên nhân. Tôi không nghĩ đó là một thư viện pam cũ, vì họ đã cập nhật lên thử nghiệm debian mới nhất.

Sau đó, có thể bạn đang biên dịch trên một máy cũ? :) Bạn đã thử biên dịch nó trên máy của khách hàng chưa? nondot.org/sabre/Mirrored/libtool-2.1a/libtool_toc.html#TOC36
Vinko Vrsalovic
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.