Предположим, что существуют три разделяемые библиотеки A.so
, B.so
и C.so
, каждая из которых имеет функцию f()
. Я хочу переключаться между каждой функцией f()
при определенных обстоятельствах, определяемых во время выполнения. Используя трюк LD_PRELOAD
, я выполню программу p
(т.е. пользователя этих библиотек) следующим образом:
LD_PRELOAD=A.so:B.so:C.so ./p
f()
в A.so
будет значением по умолчанию. В этом экземпляре f()
я могу получить доступ к f()
из B.so
, используя dlsym()
, следующим образом:
void f() // in A.so
{
...
void *f_in_B = dlsym(RTLD_NEXT, "f");
...
}
Как я могу получить доступ к экземпляру f()
в C.so
?
ОБНОВЛЕНИЕ:
Хотя ответ yugr
работает в простом случае, у него есть проблемы в более общих условиях. Я пролью свет на проблему, предоставив больше подробностей о текущей ситуации:
Мне нужны два разных распределителя динамической памяти, и я не хочу иметь дело с внутренними деталями реализации glibc
malloc(),...
. Проще говоря, у меня есть две отдельные области памяти, каждая со своим собственным glibc
. Я использую LD_PRELOAD
для переключения между распределителями на основе некоторых условий времени выполнения. Я использовал ответ yugr
для загрузки и доступа к вторичной библиотеке.
Во-первых, я вызвал ptmalloc_init()
во вторичной библиотеке для инициализации malloc()
структур данных. Я также управлял вызовами brk()
на уровне системных вызовов ОС таким образом, чтобы каждая библиотека имела свой собственный большой диапазон brk()
и этот >избегает дальнейших конфликтов.
Проблема в том, что решение работает только на границе application/glibc
. Например, когда я использую malloc()
в дополнительной библиотеке, он вызывает такие функции, как __default_morecore()
в основной библиотеке, внутренне, и эти вызовы могут не быть захваченным трюком LD_PRELOAD
.
Почему это происходит? Я думал, что внутренние символы библиотеки устанавливаются внутри во время компиляции библиотеки, но здесь кажется, что они используйте символы из основной библиотеки LD_PRELOAD
. Если разрешение выполняется компоновщиком, почему эти кажущиеся внутренними символы не захватываются приемом LD_PRELOAD
?
Как я могу исправить проблему? Должен ли я переименовывать все экспортированные функции в дополнительной библиотеке? Или единственный возможный подход заключается в использовании одной библиотеки и вникании в реализацию?
glibc
и использовать их вместо оригинальных, при определенных условия. Вы можете предположить, чтоA.so
— это моя оболочка, которая проверяет условие и выбирает между исходной функцией вglibc
(например,B.so
) и индивидуальный (например,C.so
). - person TheAhmad   schedule 11.10.2020f()
в настроенномglibc
и использовать его как стандартный? Действительно, это решит проблему, но не будет работать более чем в двух случаях. - person TheAhmad   schedule 11.10.2020