Неопределенный символ при попытке загрузить библиотеку с помощью dlopen - PullRequest
8 голосов
/ 03 декабря 2011

Я пытаюсь загрузить разделяемую библиотеку (плагин), которую мне предоставили (с закрытым исходным кодом) dlopen под платформу Linux ARM.Я пытаюсь загрузить таким образом:

void* handle = dlopen(<library_path>/<library_name>, RTLD_NOW);

В результате возникает ошибка с этим сообщением:

Failed to load <library_path>/<library_name>: undefined symbol: <symbol_name>.

Я попытался заглянуть внутрь библиотеки с помощью nm, но, похоже,lib была удалена, символ не найден.Я также попытался использовать readelf -s, и, фактически, я получил такой результат:

12663: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND <symbol_name>

Читая, я получаю, что readelf -s возвращает все символы, включая символы, определенные в библиотеках, на которые ссылаетсяit.

Ответы на этот вопрос мне не совсем понятны: это символ, который должен быть в библиотеке, а его нет, потому что он был скомпилирован неправильноили это символ, который я должен найти где-то еще?Вывод readelf -d, кажется, предполагает, что я предоставляю все необходимые разделяемые библиотеки.Может ли эта ошибка быть связана с ошибкой в ​​процессе компиляции моего исполняемого файла или это не связано с загрузчиком?

Кроме того, я прочитал о значении каждого столбца, но эти значения довольно странные,Как вы интерпретируете это описание символа?Почему адрес 0?Почему тип NOTYPE?

1 Ответ

5 голосов
/ 03 декабря 2011

неопределенный символ: X всегда означает, что X следует экспортировать из одной из загруженных библиотек, но это не так. Вы должны узнать, в какой библиотеке запрашивается символ, и ссылку на него.

Вы должны знать, что это сообщение всегда является результатом проблемы с библиотекой, это не ошибка. Библиотека должна знать, как получить все свои символы. Если это не так, вы можете связать свой исполняемый файл с необходимой библиотекой, поэтому при загрузке плагина запрашиваемый символ уже известен.

Эта ошибка может иметь более сложную причину. В случае, когда плагин и основное приложение ссылаются на библиотеку, тогда попытки связать ее могут в любом случае закончиться неопределенными символами. Это может произойти, если основное приложение и плагин используют разные версии библиотеки (а именно плагин использует более новую версию). Затем в момент загрузки плагина более старая версия уже загружена, поэтому загрузчик предполагает, что все в порядке, но более новая версия может содержать новые символы. Если плагин использует их, вы получите неопределенные ошибки символов.

...