Я хочу перехватить все обращения к файловой системе, происходящие внутри dlopen(). Сначала казалось, что LD_PRELOAD
или -Wl,-wrap,
были бы жизнеспособными решениями, но у меня возникли проблемы с их работой по некоторым техническим причинам:
ld.so уже сопоставил свои собственные символы к моменту обработки LD_PRELOAD. Для меня не критично перехватывать первоначальную загрузку, но
_dl_*
worker функции в это время разрешаются, поэтому будущие вызовы идут через них. Я думаю, чтоLD_PRELOAD
слишком поздно.Каким-то образом
malloc
обходит описанную выше проблему, потому чтоmalloc()
внутри ld.so не имеет функциональногоfree()
, он просто вызываетmemset()
.Рабочие функции файловой системы, например.
__libc_read()
, содержащиеся вld.so
, являются статическими, поэтому я не могу их перехватить с помощью-Wl,-wrap,__libc_read
.
Все это может означать, что мне нужно создать свой собственный ld.so
непосредственно из исходного кода, а не связывать его с оболочкой. Проблема в том, что и libc
, и rtld-libc
созданы из одного и того же источника. Я знаю, что макрос IS_IN_rtld
определяется при построении rtld-libc
, но как я могу гарантировать наличие только одной копии статических структур данных при экспорте функции открытого интерфейса? (Это вопрос системы сборки glibc, но я не нашел документации по этим деталям.)
Есть ли лучший способ попасть внутрь dlopen()
?
Примечание. Я не могу использовать специфичное для Linux решение, такое как FUSE
, потому что оно предназначено для ядер с минимальным «вычислительным узлом», которые не поддерживают такие вещи.
ptrace
для перехвата самих системных вызовов. Я сделал это с большим успехом, и он полностью избегает всей ерунды с общей библиотекой. Но это требует, чтобы вы полностью перепроектировали свою логику, чтобы иметь главный процесс, который выполняет функции ptrace, и подчиненный процесс, который выполняет функции динамической библиотеки. - person David Given   schedule 09.10.2011dlopen
/dlsym
функционировали должным образом, но чтобы обращаться к файловой системе по-другому. В частности, в средах HPC, таких как Blue Gene, все операции, связанные с файловым дескриптором ядра, отправляются с узлов ввода-вывода вычислительных узлов. Это вызывает серьезную проблему конкуренции при высокой параллелизации узлов. Например, загрузка приложения Python, которое ссылается на несколько скомпилированных общих библиотек, занимает около 4 часов на 65 000 ядер. Излишне говорить, что люди не в восторге от того, что тратят четверть миллиона часов ядра на загрузку своей программы. - person Jed   schedule 09.10.2011open
,read
,mmap
и т. д.), используя коллективы MPI. Это нормально для загрузки байт-кода Python, но общие библиотеки должны пройти черезdlopen
, и у меня возникли проблемы с вызовом моей реализации внутриdlopen
. - person Jed   schedule 09.10.2011ptrace
недоступен в Blue Gene, так что это не вариант. Я вернусь к созданию собственного ld.so с подключеннымdlopen
для вызова моей реализации. - person Jed   schedule 09.10.2011