[devel] Коллизия символов разных динамических библиотек
Alexander Bokovoy
ab на altlinux.org
Вс Сен 12 19:47:37 UTC 2010
2010/9/12 Roman Savochenko <rom_as на diyaorg.dp.ua>:
> Думаю для программ, единоразово подключающих свои модули, это не проблема.
> Однако есть программы, которые могут отбрасывать модули во время работы и
> подключать новые, например для горячего их обновления. Так вот для них это
> может оказаться проблемой, правда только для модулей с собственными,
> достаточно тяжёлыми, зависимостями.
Глобальные статические объекты приносят с собой деструкторы, которые
вызываются при выгрузке модулей. Изменение порядка загрузки/выгрузки
модулей с дополнительными зависимостями приводит к тому, что запись в
таблице символов для деструктора обнуляется, а потом этот деструктор
вызывается при выгрузке модуля (по уже обнуленному значению).
Например, QStringList имеет базовым классом QList<QString>, его
деструктор вызовет QList<QString>::~QList, который будет определен как
weak символ в каждом бинарнике, использующем QList<QString> (шаблонный
класс с не-inline использованием QString). Этот символ разрешается в
какую-то из целей-кандидатов в загруженных библиотеках. Если
библиотека выгружена, то символ в таблице будет обнулен, но вызван
позже деструктором глобального объекта.
Порядок вызова динамических конструкторов глобальных объектов в C++
определен только внутри одной единицы компиляции. Порядок выполнения
инициализации между единицами компиляции неопределен, он может быть
разным для разных запусков одной и той же программы. То же самое с
деструкторами.
--
/ Alexander Bokovoy
Подробная информация о списке рассылки Devel