Pada dasarnya, ini adalah dua pertanyaan menjadi satu - karena jika saya dapat membuat daftar semua simbol yang diekspor dalam suatu sistem, bersama dengan jalur pustaka bersama mereka, maka saya dapat dengan mudah grep
menampilkannya.
Untuk simbol kernel, saya kira ini agak lebih mudah - karena kita dapat selalu cat /proc/kallsyms
dan mendapatkan daftar semua simbol dari modul-modul yang dimuat dalam memori; kemudian sudo cat /proc/modules
akan memberikan daftar modul yang dimuat dengan alamatnya, tetapi bukan jalur darimana modul tersebut diambil (jika dibangun sebagai objek .ko yang terpisah dari pohon)
Misalnya, saya mencoba melacak program kst
menggunakan 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
...
... dan saya ingin tahu di mana ini _ZNK13QGraphicsItem10parentItemEv
berada.
Jadi, apa yang harus dilakukan tentang simbol perpustakaan bersama? Membaca [bantuan gcc] Re: menemukan perpustakaan di mana simbol didefinisikan. ; Saya mencoba sesuatu seperti ini:
$ 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
...
... tapi itu memberi saya masalah tambahan: Saya tidak benar-benar tahu semua jalur yang dipindai untuk perpustakaan bersama di sistem saya, jadi ketika saya pertama kali mencobanya find /lib ...
tidak menemukan apa-apa; Saya menemukan bahwa menebak direktori ini menjengkelkan, sama seperti alternatifnya: memindai seluruh sistem file root dengan find
... Dan juga, saya sepertinya menemukan * .so yang tidak dapat dibuka oleh nm
(mungkin karena mereka adalah symlink?), Yang menampilkan sedikit pesan kesalahan (yang saya juga tidak suka).
Masalahnya adalah - ldd
(atau ld
?) Mungkin melakukan beberapa pencarian simbol ini, tetapi saya mencoba halaman manual masing-masing, dan saya tidak dapat melihat cara untuk "menemukan" simbol dari baris perintah, tanpa menyediakan semacam file yang dapat dieksekusi sebagai argumen. Pertanyaan sampingan - apakah ada cara untuk menggunakan alat ini untuk itu?
Jadi, apa yang saya cari alat baris perintah, yang akan berperilaku seperti (pseudocode):
$ ./findsymbol '_Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE'
symbol found in:
/usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
...
... di mana saya tidak menentukan direktori yang akan dicari - tetapi yang juga akan menangani, misalnya LD_PRELOAD
atau LD_LIBRARY_PATH
; katakan jika saya lakukan:
$ LD_PRELOAD="/path/to/mylib.so" ./findsymbol '*mylib_print*'
... maka saya akan mendapatkan di /path/to/mylib.so
mana simbol yang diberikan didefinisikan (mengingat bahwa simbol seperti itu tidak akan ada di perpustakaan standar) - dan akan menampilkan "tidak ditemukan" sebaliknya. Dan jika tidak, ./findsymbol --dumpall
dapat menghasilkan daftar semua simbol yang tersedia dan lokasi mereka dilihat dari lingkungan tertentu (misalnya bash
shell tertentu ).
Apakah alat seperti ini ada untuk Linux?
sumber
scanelf
memungkinkan Anda menentukan direktori spesifik untuk dicari dan mendukung penelusuran rekursif-r
sehingga Anda dapat mengubah jalur pencariannya atau mencari seluruh sistem Anda tanpa terlalu banyak kesulitan. Misalnyascanelf -r -s SYMBOL /lib/* /usr/* /opt/*
akan menemukan sebagian besar tempat perpustakaan bersembunyi.Pada sistem GNU (saat menggunakan GNU libc dynamic linker), Anda dapat menjalankan program Anda sebagai:
Untuk menemukan di mana simbol menyelesaikan.
sumber
Saya telah mengalami ini beberapa kali, mencoba untuk mem-port code dari satu sistem Linux ke yang lain. Biasanya saya hanya mendapatkan semua direktori standar. Saya tidak dapat menemukan apa pun di Google. Jadi, inilah skrip cepat:
edt11x / findinsharedlibs
sumber