Атрибут 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 :

Функции инициализации и завершения

После того, как динамический компоновщик создаст образ процесса и выполнит перемещение, каждый общий объект получает возможность выполнить некоторый код инициализации. Все инициализации общих объектов происходят до того, как исполняемый файл получает управление.

Другие вопросы по тегам