Знайдіть, де визначений символ спільної бібліотеки, визначений у живій системі, / перелічіть усі символи, експортовані в систему


21

В основному, це два питання в одне - адже, якщо я можу перерахувати всі символи, експортовані в системі, разом із їх спільним бібліотечним шляхом, то я міг би просто grepвивести це.

Щодо символів ядра, я думаю, це дещо простіше - адже ми завжди можемо cat /proc/kallsymsотримати список усіх символів тих модулів, завантажених у пам'ять; то sudo cat /proc/modulesдасть список завантажених модулів з їх адресами, але не шляхи, з яких завантажуються модулі (якщо вони побудовані як окремі, поза деревами .ko об'єкти)

Наприклад, я намагаюся простежити програму, kstвикористовуючи 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
...

... і я хотів би знати, де це місце проживання _ZNK13QGraphicsItem10parentItemEv.

Отже, що робити зі спільними символами бібліотеки? Читання через [gcc-help] Re: пошук бібліотеки, в якій визначено символ. ; Я спробував щось подібне:

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

... але це створює мені додаткові проблеми: я насправді не знаю всіх шляхів, які скануються на спільні бібліотеки в моїй системі, тому коли я вперше спробував, find /lib ...нічого не знайшов; Мені здається, що це вгадування каталогів є неприйнятним, так само як і альтернатива: сканування всієї кореневої файлової системи за допомогою find... І також, я здається, потрапив * .so, який неможливо відкрити nm(можливо, тому що вони є посиланнями?), Які вивести досить багато повідомлень про помилки (що мені теж не подобається).

Річ у тому, що ldd(або ld?), Ймовірно, виконує частину цього пошуку символів, але я спробував відповідні вказівки, і я не можу побачити спосіб "знайти" будь-який символ з командного рядка, не надаючи якийсь виконуваний файл як аргумент. Побічне запитання - чи існує спосіб використовувати ці інструменти для цього?

Отже, я шукаю інструмент командного рядка, який би поводився щось на зразок (псевдокод):

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

... де я не вказую жодних каталогів для пошуку - але які б також обробляли, наприклад, LD_PRELOADабо LD_LIBRARY_PATH; скажіть, якщо я:

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

... тоді я отримав би те, /path/to/mylib.soде визначено даний символ (враховуючи, що такого символу не буде в стандартних бібліотеках) - і виводиться "не знайдено" в іншому випадку. Інакше, ./findsymbol --dumpallможна скласти список усіх доступних символів та їх розташування, що відображаються із заданого середовища (наприклад, конкретної bashоболонки).

Чи існує такий інструмент для Linux?

Відповіді:


16

Шляхи пошуку бібліотек будуть перераховані у файлі /etc/ld.so.conf, змінній середовища LD_LIBRARY_PATHта будь-яких RPATH, закодованих у бінарний файл ELF. Програма lddрозповість, які бібліотеки завантажуватиме конкретна програма.

Коли у вас є цікавий вам символ, ви можете використовувати програму nmдля скидання символів .oта .aфайлів та readelfскидання символів із .soбудь-якого виконуваного ельфа.

Приклади:

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

І нарешті, з огляду на цей фон, ось ваш святий грааль:

Дано символ _ZN6Kopete6Global10PropertiesC2Ev, де це?

scanelf -l -s _ZN6Kopete6Global10PropertiesC2Ev | grep _ZN6Kopete6Global10PropertiesC2Ev

який дає:

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

-lПрапор каже шукати каталоги в /etc/ld.so.confі -sвизначає , символ для пошуку.


Це неповно: деякі програми завантажують бібліотеки з каталогів, що стосуються додатків.
Жил "ТАК - перестань бути злим"

2
@Gilles scanelfдозволяє вказати конкретні каталоги для пошуку та підтримки рекурсивного пошуку, -rщоб ви могли налаштувати його пошукові шляхи або шукати всю вашу систему без особливих проблем. Наприклад scanelf -r -s SYMBOL /lib/* /usr/* /opt/*, знайдете більшість місць, де ховаються бібліотеки.
Кейсі

7

У системах GNU (при використанні динамічного лінкера GNU libc) ви можете запустити свою програму так:

LD_DEBUG=bindings kst2

Щоб знайти, де символи вирішуються.


0

Я не раз стикався з цим, намагаючись перенести код з однієї системи Linux в іншу. Зазвичай я просто закінчую програвання всіх стандартних каталогів. Я нічого не міг знайти гуглінг. Ось ось швидкий сценарій:

edt11x / findinsharedlibs

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.