Что именно означает предупреждение о том, что DSO ссылается на скрытый символ?
У меня проблема со связыванием какой-то разделяемой библиотеки с g++. Это дает мне предупреждение, как:
hidden symbol XXX in YYY is referenced by DSO /usr/lib/...
Я прочитал некоторые связанные вопросы об определенных проблемах, но я хочу понять это в целом - что означает это предупреждение и что является причиной:
- Что такое DSO?
- Что такое скрытый символ?
- Как на него можно сослаться, если он скрыт?
2 ответа
Что такое DSO?
DSO - это динамический совместно используемый объект, или менее формально разделяемая библиотека.
Что такое скрытый символ?
Скрытый символ - это символ (т. Е. Имя функции или объекта данных), который был скомпилирован со скрытой связью, например, согласно (специфическому для GCC) объявлению:
int x __attribute__ ((visibility ("hidden")));
Если x
определяется в одном DSO, тогда динамическое связывание не может ссылаться на него из другого DSO. Компоновщик может видеть x
(это не static
), но он не доступен для динамического связывания. Документация здесь
Как на него можно сослаться, если он скрыт?
Этого не может быть, о чем вас предупреждают. Например, предупреждение о времени ссылки:
DSO ссылается на скрытый символ "stat" в /usr/lib/libc_nonshared.a(stat.oS)
говорит вам, что DSO в связи ссылается на символ stat
и компоновщик может найти определение stat
в /usr/lib/libc_nonshared.a
, но (очевидно), что это определение отсутствует в DSO, который ссылается на него, и на него нельзя ссылаться из этого DSO, поскольку оно скрыто.
Эта проблема возникает, если проблемный DSO не был правильно построен для использования в качестве DSO. Посмотрите этот пример и следуйте инструкциям по решению.
Продолжение для продолжения OP
Если какой-то DSO уже ссылается на скрытый символ, то почему проблема в DSO?
Линкер говорит:
DSO X
содержит ссылку на символ S
, Я могу найти определение символа S
это еще один связанный модуль Y
, но это определение не будет доступно для удовлетворения ссылки в X
динамически (т.е. во время выполнения), потому что S
имеет скрытую связь в Y
,
Я могу подтвердить, что проблема связана с не-общим объектом [...][но], я не скрываю эти символы явно в моем не-совместно используемом объекте.
Возможно, вы не пометили явно какие-либо символы, скрытые в необщем объекте. В зависимости от того, как он был построен, символы могут быть скрыты по умолчанию, если явно не указано иное.
Скажем, не-общий объект libnonshared.a
и предположительно скрытый символ foo
, Бежать:
objdump -t libnonshared.a
чтобы получить информацию о символах в libnonshared.a
, В выходных данных ищите запись для foo
, Содержит ли он тег .hidden
? - например
0000000000000000 g F .text 000000000000000b .hidden foo
Эта запись говорит, что foo
является глобальным символом (отмечен g
- именно поэтому компоновщик может видеть это), но он скрыт для динамической компоновки.
Если это так, то вам нужно пойти и исправить сборку libnonshared.a
так что не прячется foo
, Если нет, то я в тупике.
Это почти десять лет спустя после отличного ответа Майка, и я хотел дать более короткий ответ, который может помочь другим в будущем:
Что происходит, когда возникает эта ошибка:
- Вы связываетесь с динамической библиотекой, которая содержит символ, который разрешается другой библиотекой.
- Эта ошибка возникает, если библиотека, разрешающая символ, является статической (.a).
- Попробуйте воссоздать разрешающую библиотеку как динамическую библиотеку (.so)
Конкретный пример, где я столкнулся с этой проблемой:
- Я создал динамическую библиотеку, которая использует некоторые функции OpenCV и поэтому имеет некоторые символы OpenCV.
- Я связывал библиотеки OpenCV для разрешения символов в динамической библиотеке, за исключением того, что мои библиотеки OpenCV были статическими, что вызвало ошибку, описанную в исходном сообщении.
- Я перекомпилировал OpenCV, на этот раз создав библиотеки как динамические.
- Я попытался перекомпилировать свою программу с моей динамической библиотекой и недавно созданными динамическими библиотеками OpenCV.
- Бум, ошибка больше не появлялась.
Удачи!