менее
$ readelf -Ws /usr/lib/libboost_program_options-mt.so | c++filt
Таблица символов «.dynsym» содержит 1163 элементов:
Чис: Знач Разм Тип Связ Vis Индекс имени
903: 0000000000054650 19 FUNC WEAK DEFAULT 11 boost::program_options::typed_value_base::~typed_value_base()
1022: 0000000000054510 15 FUNC WEAK DEFAULT 11 boost::program_options::typed_value_base::~typed_value_base()
1153: 0000000000054510 15 FUNC WEAK DEFAULT 11 boost::program_options::typed_value_base::~typed_value_base()
я бы понял почему так, если бы натравил readelf на статичекую либу - там было бы три объектника с реализацией одного инлайнового метода (например)
но почему так происходит для динамической либы? линкер же должен сводить дублирующиеся символы к одному уже при создании .so, не?
скорее всего, дело в связывании https://en.wikipedia.org/wiki/Weak_symbol
единственная гипотеза, да я просто не могу найти пока ни одного упоминания того, что weak могут дублироваться не только между разными объектами, но и в пределах одного 🤔
А так что выведет? objdump -T /usr/lib/libboost_program_options-mt.so | c++filt | grep "boost::program_options::typed_value_base::~typed_value_base()"
то же самое в другом обличьи 0000000000054650 w DF .text 0000000000000013 Base boost::program_options::typed_value_base::~typed_value_base() 0000000000054510 w DF .text 000000000000000f Base boost::program_options::typed_value_base::~typed_value_base() 0000000000054510 w DF .text 000000000000000f Base boost::program_options::typed_value_base::~typed_value_base()
это два разных деструктора, попробуй убрать c++filt и сравнить имена
Тогда это действительно из-за weak символов, объясняется почему и как тут: https://stackoverflow.com/questions/54750330/c-shared-libraries-have-duplicate-symbols
0000000000054650 w DF .text 0000000000000013 Base _ZN5boost15program_options16typed_value_baseD0Ev 0000000000054510 w DF .text 000000000000000f Base _ZN5boost15program_options16typed_value_baseD1Ev 0000000000054510 w DF .text 000000000000000f Base _ZN5boost15program_options16typed_value_baseD2Ev ...а это как? оО
::= D0 # deleting destructor ::= D1 # complete object destructor ::= D2 # base object destructor
The first destructor, called the complete object destructor, performs the destruction without calling delete() on the object. The second destructor, called the deleting destructor, calls delete() after destroying the object. Both destroy any virtual bases; a separate, non-virtual function, called the base object destructor, performs destruction of the object but not its virtual base subobjects, and does not call delete()
а откуда это, какие-то сырцы гцц ответственные за манглинг?
https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-special-ctor-dtor там же в разделе Definitions есть определения для всех видов деструкторов
слышал звон, да не помню где он спасибо, надо будет прочитать
и за это спасибо, двоение .dynsym / .syntab тоже где-то неподалёку вроде видел
Тут недавно было уже но в контексте конструкторов
Обсуждают сегодня