Что именно означает предупреждение о том, что DSO ссылается на скрытый символ?

У меня проблема со связыванием какой-то разделяемой библиотеки с g++. Это дает мне предупреждение, как:

hidden symbol XXX in YYY is referenced by DSO /usr/lib/...

Я прочитал некоторые связанные вопросы об определенных проблемах, но я хочу понять это в целом - что означает это предупреждение и что является причиной:

  1. Что такое DSO?
  2. Что такое скрытый символ?
  3. Как на него можно сослаться, если он скрыт?

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, Если нет, то я в тупике.

Это почти десять лет спустя после отличного ответа Майка, и я хотел дать более короткий ответ, который может помочь другим в будущем:

Что происходит, когда возникает эта ошибка:

  1. Вы связываетесь с динамической библиотекой, которая содержит символ, который разрешается другой библиотекой.
  2. Эта ошибка возникает, если библиотека, разрешающая символ, является статической (.a).
  3. Попробуйте воссоздать разрешающую библиотеку как динамическую библиотеку (.so)

Конкретный пример, где я столкнулся с этой проблемой:

  1. Я создал динамическую библиотеку, которая использует некоторые функции OpenCV и поэтому имеет некоторые символы OpenCV.
  2. Я связывал библиотеки OpenCV для разрешения символов в динамической библиотеке, за исключением того, что мои библиотеки OpenCV были статическими, что вызвало ошибку, описанную в исходном сообщении.
  3. Я перекомпилировал OpenCV, на этот раз создав библиотеки как динамические.
  4. Я попытался перекомпилировать свою программу с моей динамической библиотекой и недавно созданными динамическими библиотеками OpenCV.
  5. Бум, ошибка больше не появлялась.

Удачи!

Другие вопросы по тегам