Tìm vị trí ký hiệu thư viện dùng chung được xác định trên hệ thống trực tiếp / liệt kê tất cả các ký hiệu được xuất trên hệ thống


21

Về cơ bản, đây là hai câu hỏi thành một - bởi vì nếu tôi có thể liệt kê tất cả các biểu tượng được xuất trong một hệ thống, cùng với đường dẫn thư viện dùng chung của chúng, thì tôi có thể chỉ đơn giản greplà đầu ra đó.

Đối với các ký hiệu kernel, tôi đoán nó có phần dễ dàng hơn - bởi vì chúng ta luôn có thể cat /proc/kallsymsvà nhận được một danh sách tất cả các ký hiệu của các mô-đun được tải trong bộ nhớ; sau đó sudo cat /proc/modulessẽ đưa ra một danh sách các mô-đun được tải với địa chỉ của chúng, nhưng không phải là các đường dẫn mà các mô-đun đã được tải từ đó (nếu chúng được xây dựng dưới dạng các đối tượng .ko ngoài cây riêng biệt)

Chẳng hạn, tôi cố gắng theo dõi chương trình kstbằng cách sử dụng ltrace:

$ ltrace kst2
...
_ZNK13QGraphicsItem10parentItemEv(0xa1ccdb4, 0, 0xbfe631a8, 0x823652b, 0xbfe63298) = 0xa1ce854
__dynamic_cast(0xa1ce854, 0x839ff00, 0x8306b80, 84, 0xbfe63298)     = 0xa1ce800
_ZNK13QGraphicsItem10parentItemEv(0xa1ccdb4, 0x839ff00, 0x8306b80, 84, 0xbfe63298) = 0xa1ce854
__dynamic_cast(0xa1ce854, 0x839ff00, 0x8306b80, 84, 0xbfe63298)     = 0xa1ce800
...

... Và tôi muốn biết nơi này _ZNK13QGraphicsItem10parentItemEvnằm ở đâu.

Vì vậy, những gì để làm về các biểu tượng thư viện chia sẻ? Đọc qua [gcc-help] Re: tìm thư viện trong đó ký hiệu được xác định. ; Tôi đã thử một cái gì đó như thế này:

$ find /usr/lib -name '*.so*' -exec nm --print-file-name --defined-only --dynamic {} \; | grep "QGraphicsItem"
...
/usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
/usr/lib/libQtGui.so.4.7.2:00766aa0 T _Zls6QDebugN13QGraphicsItem18GraphicsItemChangeE
/usr/lib/libQtGui.so.4.7.2:00767e80 T _Zls6QDebugP13QGraphicsItem
...

... nhưng điều đó mang đến cho tôi những vấn đề khác: Tôi thực sự không biết tất cả các đường dẫn được quét cho các thư viện dùng chung trên hệ thống của mình, vì vậy khi tôi thử lần đầu tiên, find /lib ...nó không tìm thấy gì; Tôi thấy việc đoán các thư mục này rất hay, cũng như cách khác: quét toàn bộ hệ thống tập tin gốc bằng find... Và ngoài ra, tôi dường như đánh lên * .so không thể mở được nm(có thể vì chúng là liên kết tượng trưng?), Mà xuất ra khá nhiều thông báo lỗi (mà tôi cũng không thích).

Vấn đề là - ldd(hoặc ld?) Có thể thực hiện một số tra cứu biểu tượng này, nhưng tôi đã thử các trang tương ứng và tôi không thể thấy cách "tìm" bất kỳ biểu tượng nào từ dòng lệnh, mà không cung cấp một loại tệp thực thi nào đó dưới dạng tranh luận. Câu hỏi phụ - có cách nào để sử dụng các công cụ này cho việc đó không?

Vì vậy, những gì tôi đang tìm kiếm một công cụ dòng lệnh, sẽ hoạt động giống như (mã giả):

$ ./findsymbol '_Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE'
symbol found in:
    /usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
...

... nơi tôi không chỉ định bất kỳ thư mục nào để tìm kiếm - nhưng cũng sẽ xử lý, ví dụ LD_PRELOADhoặc LD_LIBRARY_PATH; nói nếu tôi làm:

$ LD_PRELOAD="/path/to/mylib.so" ./findsymbol '*mylib_print*'

... sau đó tôi sẽ nhận được vị /path/to/mylib.sotrí của biểu tượng đã cho (được xác định rằng biểu tượng đó sẽ không tồn tại trong các thư viện chuẩn) - và sẽ xuất ra "không tìm thấy" nếu không. Và mặt khác, ./findsymbol --dumpallcó thể tạo ra một danh sách tất cả các biểu tượng có sẵn và vị trí của chúng nhìn thấy từ một môi trường nhất định (ví dụ: một bashvỏ cụ thể ).

Có một công cụ như thế này tồn tại cho Linux?

Câu trả lời:


16

Các đường dẫn để tìm kiếm các thư viện trong sẽ được liệt kê trong tệp /etc/ld.so.conf, biến môi trường LD_LIBRARY_PATHvà bất kỳ RPATH nào được mã hóa thành nhị phân ELF. Chương trình lddsẽ cho bạn biết những thư viện mà một ứng dụng cụ thể sẽ tải.

Khi bạn có một biểu tượng mà bạn tò mò, bạn có thể sử dụng chương trình nmđể kết xuất các biểu tượng .o.atệp và readelfđể kết xuất các biểu tượng từ một .sohoặc bất kỳ yêu tinh nào có thể thực thi được.

Ví dụ:

nm -g /usr/lib/blah.a
readelf -Ws /usr/lib/blah.so

Và cuối cùng, với nền tảng đó sang một bên, đây là chén thánh của bạn:

Đưa ra một biểu tượng _ZN6Kopete6Global10PropertiesC2Ev, đây là đâu?

scanelf -l -s _ZN6Kopete6Global10PropertiesC2Ev | grep _ZN6Kopete6Global10PropertiesC2Ev

mang lại:

ET_DYN _ZN6Kopete6Global10PropertiesC2Ev /usr/lib64/libkopete.so.4.11.4

Các -llá cờ nói với dirs trong tìm kiếm /etc/ld.so.confvà các -squy định cụ thể các biểu tượng để tìm.


Điều này là không đầy đủ: một số chương trình tải thư viện từ các thư mục dành riêng cho ứng dụng.
Gilles 'SO- ngừng trở nên xấu xa'

2
@Gilles scanelfcho phép bạn chỉ định các thư mục cụ thể để tìm kiếm và hỗ trợ tìm kiếm đệ quy -rđể bạn có thể điều chỉnh đường dẫn tìm kiếm của nó hoặc tìm kiếm toàn bộ hệ thống của bạn mà không gặp quá nhiều khó khăn. Ví dụ scanelf -r -s SYMBOL /lib/* /usr/* /opt/*sẽ tìm thấy hầu hết các thư viện địa điểm đang ẩn.
casey

7

Trên các hệ thống GNU (khi sử dụng trình liên kết động GNU libc), bạn có thể chạy chương trình của mình dưới dạng:

LD_DEBUG=bindings kst2

Để tìm nơi các biểu tượng giải quyết.


0

Tôi đã gặp phải điều này nhiều lần, cố gắng chuyển mã từ hệ thống Linux này sang hệ thống Linux khác. Thông thường tôi chỉ kết thúc tất cả các thư mục tiêu chuẩn. Tôi không thể tìm thấy bất cứ điều gì googling. Vì vậy, đây là một kịch bản nhanh chóng:

edt11x / findin Sharedlibs

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.