Поздравляем - вы вновь обнаружили, что не-nop dlclose
реализация принципиально небезопасна. Язык C не предусматривает код или данные псевдостатического хранилища, время жизни которых отличается от всего времени жизни программы, и в целом код библиотеки не может быть безопасно удален, так как ссылки на него могут быть разными слил и все еще быть доступным. Вы действительно нашли исключительно хороший пример; Обычные реализации пытаются перехватить и «исправить» утечки с помощью atexit
и т. д., запустив обработчики во время dlclose
, но, похоже, нет никакого способа перехватить и исправить оставленный поток.
В качестве обходного пути есть специальный флаг ELF, который вы можете установить, передавая -Wl,-z,nodelete
при связывании общей библиотеки libB.so
(или libA.so
, если это более удобно, например, если вы не контролируете, как libB.so
связан), что предотвратит его выгрузку dlclose
. К сожалению, этот дизайн задом наперед. Выгрузка принципиально небезопасна, если библиотека специально не написана для защиты от выгрузки, поэтому по умолчанию должен быть «nodelete» с явной опцией, необходимой для возможности выгрузки. К сожалению, мало шансов, что это когда-нибудь будет исправлено.
Еще один способ предотвратить выгрузку - вызвать на конструкторе вызов dlopen
для утечки ссылки, чтобы счетчик ссылок всегда был положительным и dlclose
ничего не делал.