В каком порядке разделяемые библиотеки инициализируются и завершаются? - PullRequest
0 голосов
/ 26 октября 2018

Динамические объекты в процессе поступают из нескольких источников:

  1. Сам исполняемый файл
  2. Любые необходимые ему библиотеки (DT_NEEDED для ELF)
  3. Библиотекизагружен явно (dlopen или аналогичный)
  4. Любые библиотеки, необходимые для таких явных загрузок

Они могут быть выгружены явно (dlclose) или неявно когда процесс exit s, запустив их финализацию (atexit функции, деструкторы статической длительности в C ++ и __attribute__((destructor)) функции) в любом случае.

Что определяет порядок вкакие динамические объекты инициализируются и завершаются в этих различных случаях?Очевидно, что последний dlclose для библиотеки немедленно выгружает ее, но как насчет ее дерева зависимостей (некоторые из которых также могут быть зависимостями других загруженных библиотек)?Что если библиотека dlopen редактируется, но затем выгружается exit?

Я склонен ожидать обычный обратный порядок инициализации, но, возможно, есть разница между DT_NEEDED иdlopen, поскольку "плагины" загружаются последними, и можно ожидать, что они будут зависеть от данных исполняемого файла, а не наоборот.

1 Ответ

0 голосов
/ 26 октября 2018

Алгоритм одинаков во всех случаях.После сопоставления основного исполняемого файла (или библиотеки dlopen ed) динамический компоновщик будет выполнять функции инициализации в топологическом порядке, чтобы зависимости инициализировались перед зависимостями.Обратите внимание, что в некоторых случаях это может оставить порядок неопределенным, и компоновщик делает там произвольный выбор.

Деструкторы библиотеки регистрируются в одном из ее конструкторов (через вызов __cxa_atexit).Регистрация выполняется путем добавления функции dtor кумулятивной библиотеки в специальный список внутри Glibc.На exit список перемещается в прямом направлении, поэтому зависимые деструкторы будут вызываться перед их зависимостями.

...