Символ отчетов NM определен, но символ отчетов LDD не определен - PullRequest
2 голосов
/ 03 июня 2009

У меня проблема со связыванием. Мне нужно связать с общей библиотекой libfoo.so, которая зависит от функции read, которую я хотел бы определить в файле read.c.

Я компилирую и связываю все вместе, но во время выполнения я получаю ошибку

/home/bar/src/libfoo.so: undefined symbol: sread.

нм сообщает, что символ определен

$nm baz | grep sread
  00000000000022f8 t sread

но ldd сообщает, что символ не определен

$ldd -r baz | grep sread 
undefined symbol: sread (/home/bar/src/libfoo.so)

Что дает? Есть ли некоторые проблемы с тем, что libfoo.so является общей библиотекой?

Ответы [ 3 ]

13 голосов
/ 03 июня 2009

Во-первых, определение функции с именем read - плохая идея (TM), потому что это стандартная функция libc во всех UNIXen. При этом поведение вашей программы не определено.

Во-вторых, функция read, которую вы определили в libbaz.so, помечена выводом 't' in nm. Это означает, что эта функция является локальной (не отображается снаружи libbaz.so). Глобальные функции отмечены 'T' nm.

Использовали ли вы 'static int read(...)', когда определили его в read.c? Если нет, то использовали ли вы скрипт компоновщика, или attribute((visibility(hidden))), или, возможно, -fvisibility=hidden в командной строке при компиляции и компоновке libbaz.so?

1 голос
/ 30 августа 2013

Вышеуказанная ошибка также может возникать, когда код C компилируется с G ++, а затем связывается. G ++ выполняет искажение имени, поэтому реальным символом может быть что-то вроде «_Zsds_ [имя_функции] _», в результате чего компоновщик задыхается при поиске необработанного имени.

Я столкнулся с тем же поведением сегодня, за исключением того, что моя проблема была решена после действий, описанных в Wikipedia . По сути, код C, скомпилированный с помощью компилятора C ++, будет иметь «искаженное» имя в таблице символов, что приведет к сбою разрешения символов в стиле C.

0 голосов
/ 03 июня 2009

Когда вы создаете общую библиотеку, вам нужно разрешить все неопределенные символы из одной и той же библиотеки или другой (общей) библиотеки. Компоновщик не разрешит неопределенный символ из библиотеки с символом из вашего приложения.

...