Canlı bir sistemde tanımlanmış paylaşılan bir kütüphane sembolünün nerede olduğunu bulun / sisteme verilen tüm sembolleri listeler


21

Temel olarak, bu iki soruya tek bir sorudur - çünkü bir sistem içerisinde dışa aktarılan tüm sembolleri, paylaşılan kütüphane yollarıyla birlikte listeleyebilirsem, o zaman basitçe grepbu çıktıyı alabilirdim.

Çekirdek sembolleri için sanırım biraz daha kolay - çünkü her zaman cat /proc/kallsymsbellekte yüklü olan modüllerin tüm sembollerinin bir listesini alabiliriz; daha sonra sudo cat /proc/modulesadresleriyle birlikte yüklü modüllerin bir listesini verecektir, ancak modüllerin yüklendiği yolları içermez (eğer ayrı, ağaç dışı .ko nesneleri olarak oluşturulmuşlarsa)

Örneğin, programı kstkullanarak izlemeyi denerim 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
...

... ve bunun nerede olduğunu bilmek istiyorum _ZNK13QGraphicsItem10parentItemEv.

Peki, paylaşılan kütüphane sembolleri hakkında ne yapmalı? [Gcc-help] Re ile okuma : Sembolün tanımlandığı kütüphaneyi bulma. ; Böyle bir şey denedim:

$ 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
...

... ama bu bana ek problemler veriyor: Sistemimdeki paylaşılan kütüphaneler için taranan tüm yolları gerçekten bilmiyorum, bu yüzden ilk denediğimde find /lib ...hiçbir şey bulamadı; Dizinlerin tahminini zahmetli buluyorum, bunun yanı sıra alternatif: tüm kök dosya sistemini taramakla find... Ve ayrıca, * .so'lar tarafından açılmayan nm(belki onlar sembolik olduklarından?) Çarptığım gibi görünüyor. Oldukça fazla hata mesajı çıktısı alın (ki bu da hoşuma gitmedi).

Mesele şu ki - ldd(veya ld?) Muhtemelen bu sembollerin aranmasını gösteriyor, ancak ilgili man sayfalarını denedim ve komut satırından herhangi bir sembolü "çalıştırılabilir", bir tür çalıştırılabilir dosya sağlamadan bir yol göremiyorum. argüman. Yan soru - bu araçları bunun için kullanmanın bir yolu var mı?

Öyleyse, aradığım komut satırı aracı, şöyle bir şey olurdu (sözde kodu):

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

... aranacak dizinleri belirtmediğim - ancak bunların da ele alınacağı, örneğin LD_PRELOADveya LD_LIBRARY_PATH; eğer yapsam:

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

... o zaman /path/to/mylib.soverilen sembolün nerede tanımlandığını (standart kütüphanelerde böyle bir sembolün bulunmaması nedeniyle) ve aksi takdirde "bulunmaz" çıktısını alırdım . Aksi halde, ./findsymbol --dumpallmevcut tüm sembollerin bir listesini ve belirli bir ortamdan görülen konumlarını (örn bash. Belirli bir kabuk) üretebilir .

Linux için böyle bir araç var mı?

Yanıtlar:


16

Kütüphaneleri aramanın yolları, dosyada /etc/ld.so.conf, ortam değişkeninde LD_LIBRARY_PATHve ELF ikili kodunda kodlanmış tüm RPATH'lerde listelenir . Program lddsize belirli bir uygulamanın hangi kütüphaneleri yükleyeceğini söyleyecektir.

Merak ettiğiniz bir sembole sahip olduğunuzda, programı nmsembolleri .ove .adosyaları readelfdökmek .sove herhangi bir elf uygulamasından semboller dökmek için kullanabilirsiniz .

Örnekler:

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

Ve nihayet, bu arka plan bir yana, işte kutsal kâsenin:

Bir sembol _ZN6Kopete6Global10PropertiesC2Evverildiğinde, bu nerede?

scanelf -l -s _ZN6Kopete6Global10PropertiesC2Ev | grep _ZN6Kopete6Global10PropertiesC2Ev

hangi verim:

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

-lBayrak içinde dizinleri arama diyor /etc/ld.so.confve -ssembol bulmak için belirtir.


Bu eksik: Bazı programlar, uygulamaya özel dizinlerden kütüphaneler yükler.
Gilles 'SO- kötülük' dur

2
@Gilles scanelf, arama yapmanıza ve özyinelemeli oturumu desteklemeye yönelik özel dizinler belirlemenizi sağlar; -rböylece arama yollarını düzenleyebilir veya tüm sisteminizi çok fazla sorun yaşamadan arayabilirsiniz. Örneğin scanelf -r -s SYMBOL /lib/* /usr/* /opt/*kütüphanelerin saklandığı yerlerin çoğunu bulacaksınız.
casey

7

GNU sistemlerinde (GNU libc dinamik bağlayıcısını kullanırken), programınızı aşağıdaki gibi çalıştırabilirsiniz:

LD_DEBUG=bindings kst2

Sembollerin nerede çözüldüğünü bulmak için.


0

Bunu bir kaç kez deneyimledim, bir Linux sisteminden diğerine kod yerleştirmeye çalışıyorum. Genelde sadece tüm standart dizinleri okutuyorum. Googling hiçbir şey bulamadım. Yani burada hızlı bir komut dosyası:

edt11x / findinsharedlibs

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.