Zasadniczo są to dwa pytania w jedno - ponieważ jeśli mogę wymienić wszystkie symbole wyeksportowane w systemie wraz z ich ścieżką do biblioteki współdzielonej, to mógłbym po prostu uzyskać grep
ten wynik.
W przypadku symboli jądra wydaje mi się, że jest to nieco łatwiejsze - ponieważ zawsze możemy cat /proc/kallsyms
uzyskać listę wszystkich symboli modułów załadowanych do pamięci; następnie sudo cat /proc/modules
poda listę załadowanych modułów wraz z ich adresami, ale nie ścieżek, z których moduły zostały załadowane (jeśli są zbudowane jako osobne, niepasujące obiekty .ko)
Na przykład próbuję śledzić program kst
przy użyciu 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
...
... i chciałbym wiedzieć, gdzie to się _ZNK13QGraphicsItem10parentItemEv
znajduje.
Co więc zrobić z symbolami biblioteki współdzielonej? Czytanie za pomocą [gcc-help] Re: znalezienie biblioteki, w której zdefiniowano symbol. ; Próbowałem czegoś takiego:
$ 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
...
... ale to daje mi dodatkowe problemy: tak naprawdę nie znam wszystkich ścieżek skanowanych w poszukiwaniu bibliotek współdzielonych w moim systemie, więc kiedy po raz pierwszy spróbowałem find /lib ...
, nic nie znalazło; Zgadywanie katalogów jest dla mnie irytujące, podobnie jak alternatywa: skanowanie całego głównego systemu plików za pomocą find
... I wydaje mi się, że trafiłem na * .so, które nie mogą zostać otwarte nm
(może dlatego, że są dowiązaniami symbolicznymi?), Które wypisuje sporo komunikatów o błędach (których mi się nie podoba).
Chodzi o to, że - ldd
(lub ld
?) Prawdopodobnie wykonuje niektóre z tych odnośników symboli, ale wypróbowałem odpowiednie strony podręcznika i nie widzę sposobu, aby „znaleźć” dowolny symbol z wiersza poleceń, bez podania jakiegoś pliku wykonywalnego jako pliku argument. Pytanie poboczne - czy istnieje sposób na wykorzystanie tych narzędzi?
Tak więc szukam narzędzia wiersza polecenia, które zachowałoby się jak (pseudokod):
$ ./findsymbol '_Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE'
symbol found in:
/usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
...
... gdzie nie określam żadnych katalogów do przeszukania - ale które również mogłyby obsługiwać, np. LD_PRELOAD
lub LD_LIBRARY_PATH
; powiedz jeśli zrobię:
$ LD_PRELOAD="/path/to/mylib.so" ./findsymbol '*mylib_print*'
... wtedy ustaliłbym, /path/to/mylib.so
gdzie zdefiniowano dany symbol (biorąc pod uwagę, że taki symbol nie istniałby w standardowych bibliotekach) - w przeciwnym razie wyświetliłby „nie znaleziono”. W przeciwnym razie ./findsymbol --dumpall
może wygenerować listę wszystkich dostępnych symboli i ich lokalizacji widzianych z danego środowiska (np. Konkretnej bash
powłoki).
Czy takie narzędzie istnieje w systemie Linux?
źródło
scanelf
pozwala określić określone katalogi do przeszukiwania i wspierać wyszukiwanie rekurencyjne,-r
dzięki czemu można dostosować jego ścieżki wyszukiwania lub przeszukać cały system bez większych problemów. Na przykładscanelf -r -s SYMBOL /lib/* /usr/* /opt/*
znajdzie większość miejsc, w których ukrywają się biblioteki.W systemach GNU (podczas korzystania z dynamicznego linkera GNU libc) możesz uruchomić swój program jako:
Aby dowiedzieć się, gdzie symbole się kończą.
źródło
Natknąłem się na to wiele razy, próbując przenieść kod z jednego systemu Linux na inny. Zwykle po prostu szukam wszystkich standardowych katalogów. Nie mogłem znaleźć niczego googlującego. Oto krótki skrypt:
edt11x / findinsharedlibs
źródło