Путаница в порядке вызова __attribute__((конструктор))

Ответ здесьдемонстрирует, что __attribute__((конструктор)) не вызывается послестатической инициализации, он вызывается в порядке объявления.

Тогда какова его цель, если не гарантируется, что он будет вызван при инициализации всех данных? Мы могли бы также иметь наш ((конструктор)) код в конструкторе Foo.

Я ищу способ иметь в разделяемой библиотеке код, который будет выполняться после инициализации всех статических данных и вызова статических конструкторов. Я видел, как люди рекомендовали __attribute__((constructor)) в качестве замены DllMain; как мы видим, это неправильно, потому что некоторые статические данные могут быть еще не инициализированы.

Конечно, в одном файле (единице компиляции) можно было бы организовать статику. Но в типичной программе много файлов.Есть ли способ гарантировать, что ((конструктор)) в одном файле будет определенно вызываться после того, как все остальные статические элементы в общей библиотеке будут инициализированы?

Если я помещу файл со статической инициализацией (конструктор, объект и т.д.) в конец командной строки gcc:

g++ -shared -fPIC source1.o source2.o MyLastInitChance.o

гарантированно ли, что статические конструкторы этого файла будут вызываться последними? Я экспериментировал, и когда я меняю порядок исходных файлов, порядок printfs меняется; но указан ли он где-нибудь и гарантированно ли он будет одинаковым для систем/компьютеров компиляции?

Например, цитата:

Во время компоновки драйвер gcc помещает crtbegin.o непосредственно перед всеми перемещаемые файлы и crtend.o сразу после перемещаемые файлы. ©

Насколько я понимаю, приведенная выше цитата подразумевает, что порядок файлов .o, передаваемых компоновщику, определяет порядок статической инициализации. Я прав?

Другое интересное возможное решение, возможно, заключается в написании подключаемого модуля GCC, который корректирует статическую инициализацию (например, добавляет код в раздел .ctors и т. д.). Но это всего лишь идея, которую, возможно, кто-то сможет расширить.

Еще одно возможное решение представленоздесь. Короче говоря, внешний инструмент пост-сборки можно использовать для изменения порядка записей .ctors в исполняемом файле (библиотеке). Но я не эксперт в формате ELF; Интересно, возможно ли это и достаточно ли легко настроить файлы .so таким образом.

Меня интересует решение конкретной проблемы или доказательство того, что ее решить невозможно (по крайней мере, почему приведенные выше решения не будут работать).

9
задан Community 23 May 2017 в 12:24
поделиться