Стандарт C ++ требует, чтобы деструкторы вызывались для глобальных объектов при выходе из программы в обратном порядке построения. Большинство реализаций обрабатывает это, вызывая подпрограмму atexit библиотеки C для регистрации деструкторов. Это проблематично, поскольку стандарт C 1999 года требует только того, чтобы реализация поддерживала 32 зарегистрированных функции, хотя большинство реализаций поддерживают гораздо больше. Более важно то, что в большинстве реализаций вообще отсутствует возможность удалять DSO из образа работающей программы, вызывая dlclose перед завершением программы.
Эта проблема решается в более поздних версиях GCC, включая стандартную библиотеку C / C ++ и компоновщик. По сути, деструкторы C ++ должны быть зарегистрированы с использованием функции __cxa_atexit
вместо atexit
(3).
Для получения полной информации о __cxa_atexit
см. Спецификация Itanium C ++ ABI .
Из вашего вопроса не ясно, какую версию gcc, linker и стандартной библиотеки C вы используете. Кроме того, предоставленный вами код не соответствует стандарту POSIX , поскольку не определены макросы RTDL_NOW
или RTDL_LOCAL
. Это RTLD_NOW
и RTLD_LOCAL
(см. dlopen ).
Если ваша стандартная библиотека C не поддерживает __cxa_atexit
, вам может потребоваться отключить ее, указав -fno-use-cxa-atexit
gcc flag:
-fuse-CXA-atexit
Регистрация деструкторов для объектов со статическим хранилищем
продолжительность с __cxa_ atexit
функция, а не Atexit
функция. Эта опция необходима для
полностью совместимая со стандартами обработка
статические деструкторы, но будут работать только
если ваша библиотека C поддерживает
__cxa_atexit.
Но это может привести к проблеме, когда деструкторы вызываются в другом порядке или не вызываются вообще. Таким образом, лучшее решение в случае неработающей поддержки __cxa_atexit
или ее отсутствия вообще - не использовать статические объекты с деструкторами в общих библиотеках.