По сути, это два вопроса в одном - потому что, если я смогу перечислить все символы, экспортируемые в систему, вместе с их общим путем к библиотеке, я мог бы просто получить 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
?), Вероятно, выполняет некоторые из этих поисков символов, но я попробовал соответствующие страницы man, и я не могу найти способ «найти» какой-либо символ из командной строки, не предоставив некоторый исполняемый файл в виде аргумент. Дополнительный вопрос - есть ли способ использовать эти инструменты для этого?
Итак, что я ищу инструмент командной строки, который будет вести себя примерно так (псевдокод):
$ ./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?
источник
scanelf
позволяет вам указывать конкретные каталоги для поиска и поддерживать рекурсивное кэширование,-r
чтобы вы могли без проблем настраивать его пути поиска или выполнять поиск по всей вашей системе. Напримерscanelf -r -s SYMBOL /lib/* /usr/* /opt/*
, найдет большинство мест, которые скрывают библиотеки.В системах GNU (при использовании динамического компоновщика GNU libc) вы можете запустить вашу программу как:
Чтобы найти, где символы разрешают.
источник
Я сталкивался с этим несколько раз, пытаясь перенести код из одной системы Linux в другую. Обычно я просто в конечном итоге grep'ing все стандартные каталоги. Я не мог найти что-нибудь гуглить. Итак, вот быстрый скрипт:
edt11x / findinsharedlibs
источник