Некорректный порядок вызова деструкторов при выгрузке динамической библиотеки?
Здравствуйте,
Я столкнулся с очень странной проблемой.
У меня есть динамическая библиотека на Linux, которая динамически подгружается и выгружается процессом два раза подряд (причем я не могу повлиять на логику процесса).
Первая пара вызовов dlopen/dlclose отрабатывают корректно — деструкторы статических переменных вызываются в порядке, обратном их созданию.
Второй вызов dlopen отрабатывает нормально. А вот второй (и все последующие) вызов dlclose приводит к тому, что деструкторы вызываются в порядке создания! В лучшем случае это проходит незаметно, но в худшем, если одна переменная пытается использовать другую, процесс валится по SEGFAULT.
Я попытался воспроизвести проблему с маленькой динамической библиотекой-пустышкой, но там все ок — никаких нарушений в порядке освобождения статических переменных. Проход с LD_DEBUG ничего полезного не выявил — dlclose/_fini вызыватся штатно (вроде).
Затем я попробовал добавить несколько вызовов atexit() и проследить, влияет-ли второй dlclose() на них. Оказалость, что да — их порядок тоже нарушается (сначала я думал, что это только касается финализации С++).
Я не обнаружил зависимости от версии gcc (пробовал 3.2/3.4/4.1.2) или дистры Linux (RHEL 4/5, SuSE 10). Поиск в Web не принес никаких похожих ссылок.
В реальной библиотеке (а она очень большая) я отчасти локализовал часть, включение которой начинает вызывать проблему, и буду еще копать в этом направлении.
Буду признателен за любые идеи — что еще можно попробовать, что почитать, где поискать…
Я повозился с отладкой кода atexit() в GLIBC, и обнаружил, что это баг в GLIBC — достаточно прозаичный баг, который происходит при достаточно ограниченных условиях.
Я оказался достаточно неудачлив, чтобы попасть как раз на версию GLIBC 2.3.4, в которой баг присутствует. В следующей версии GLIBC 2.4 его уже починили.
Было нечто подобное. У тебя случайно эта динамическая библиотека при сборке не линкуется статически с какой-нибудь библиотекой, которая так же статически линкуется и с бинарников из которого происходит загрузка динамической библиотеки?
У меня похожая проблема была, но она проявлялась только на определенном дистрибутиве.
Я воспроизвожу проблему с этой библиотекой из простого консольного приложения, которое несколько раз разгружает и выгружает библиотеку. Так что у меня имена и статические переменные не пересекаются с головной программой. Более того, я скрываю все символы в библиотеке, кроме пары нужных.
Так как я не могу свой коммент заапрувить как решение, то я отмечу коммент товарища rtorsten — вопрос разрешен, лучше если он будет отмечен как решенный.