Атрибут GCC __attribute__ ((конструктор)) из основного исполняемого файла запускается после конструкторов связанных библиотек
Я заметил, что конструкторы из общих объектов, связанных с моими приложениями, всегда будут запускаться перед моими конструкторами приложений, даже если мои приложения имеют более низкий приоритет (т.е. более высокий приоритет); например, скажем, эта программа:
#include <stdio.h>
static void __attribute__ ((constructor (101))) test() {
printf("test\n");
}
int main(int argc, char *argv[]) {
return 0;
}
связывает следующий общий объект:
#include <stdio.h>
static void __attribute__ ((constructor (102))) test_so() {
printf("test so\n");
}
Я ожидал, что вывод будет:
тест
тест так
Вместо этого вывод противоположный.
Есть ли причина, почему? Я не смог найти никакой документации.
1 ответ
Есть ли причина, почему?
Факты:
-
__attribute__((__constructor__))
в основном добавляет указатель на функцию в какой-то раздел ELF - Каждый файл ELF имеет отдельные секции DT_INIT или DT_INIT_ARRAY.
- Каждый файл ELF загружается по порядку, а зависимости загружаются перед исполняемым файлом.
- Таким образом, конструкторы разделяемых библиотек будут запускаться перед исполняемым файлом.
- Заказ
__attribute__((__constructor__(this_number)))
ограничен одним файлом ELF, так как компилятор может переупорядочить их там.
никакой документации найти не удалось.
Это задокументировано в https://refspecs.linuxfoundation.org/elf/elf.pdf :
Функции инициализации и завершения
После того, как динамический компоновщик создаст образ процесса и выполнит перемещение, каждый общий объект получает возможность выполнить некоторый код инициализации. Все инициализации общих объектов происходят до того, как исполняемый файл получает управление.