Неопределенная ссылка на mempcy@GLIBC_2.14 при компиляции в Linux

Я пытаюсь перенести приложение для управления устройством, использующим чип ftdi2332h, с Windows на Linux. Я установил библиотеку libftd2xx в системе Ubuntu 10.04 в соответствии с этими инструкциями. .

Когда я пытаюсь скомпилировать любой из примеров программ, я получаю следующую ошибку:

/usr/local/lib/libftd2xx.so: undefined reference to `memcpy@GLIBC_2.14'
collect2: ld returned 1 exit status

Любые рекомендации о том, как это исправить?


person user1487551    schedule 05.09.2012    source источник


Ответы (6)


mempcy@GLIBC_2.14 называется версионным символом. Glibc использует их, в то время как другие библиотеки времени выполнения, такие как musl, не используют.

Значение mempcy@GLIBC_2.14 при компиляции в Linux связано с тем, что Glibc изменил способ работы memcpy еще в 2012 году. memcpy использовалось для копирования байтов {начало → конец} (младший адрес памяти в старший адрес памяти). Glibc 2.13 предоставил оптимизированный memcpy, который копировал {end → begin} на некоторых платформах. Я считаю, что «некоторые платформы» включали машины Intel с SSE4.1. Затем Glibc 2.14 предоставил memcpy, который восстановил поведение {begin → end}.

Некоторые программы зависели от копии {begin → end}. Когда программы использовали перекрывающиеся буферы, memcpy приводило к неопределенному поведению. В этом случае программа должна была использовать memmove, но они справлялись из-за того, что произошло копирование {begin → end}. См. также странный звук на сайте mp3 flash (из-за Adobe Flash), Изменение Glibc, выявляющее ошибки (на LWN), Сага о memcpy и memmove и друзья.

Чтобы исправить это, вы можете добавить в исходный код следующее:

__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");

Может быть, что-то вроде следующего. Затем включите дополнительный исходный файл в свой проект.

$ cat version.c

__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
person jww    schedule 21.02.2019
comment
+1 большое спасибо, это исправило мой код, если я поместил эту строку в тот же файл C, в котором я назвал memcpy (я использую Eclipse), но после прочтения это, я думаю, что этот хак может привести к сбоям кода, который на самом деле вызывает старый memcpy. - person Accountant م; 20.04.2019
comment
@Accountantم - Может быть, вы можете создать общий объект и LD_PRELOAD обеспечить его привязку memcpy к Glibc 2.2.5. - person jww; 20.04.2019
comment
Для тех, кто собирается использовать это решение, вы можете проверить, действительно ли он изменил тег версии на objdump -T ./fooProgram - person Accountant م; 20.04.2019

В ридми упоминается Ubuntu 12.04, которая поставляется с glibc 2.15. Вы используете Ubuntu 10.04, которая поставляется с glibc 2.11.1. Сообщение об ошибке, которое вы видите, говорит вам, что какой-то двоичный файл (здесь это, скорее всего, libftd2xx.so), с которым вы связаны, опирается на более новый glibc, чем вы связываете, что логично, учитывая предыдущий факт.

Либо перекомпилируйте libftd2xx.so из исходного кода с версией glibc вашей системы (вероятно, это не вариант, так как это только двоичный файл), либо обновите свою ОС. Ubuntu 10.04 довольно старая.

В крайнем случае (и старайтесь делать это, только если хотите, хм, бить себя по пальцам кувалдой), вы можете скомпилировать новый glibc для своей системы и установить его куда-нибудь вроде /opt.

person rubenvb    schedule 17.02.2015

Это ошибка Oracle с «opatchauto». См. этот URL, https://dba010.com/2019/06/24/19cgi-12crdbms-opatchauto-re-link-fails-on-target-procob/. ВРЕМЕННОЕ РЕШЕНИЕ: Вручную используйте «opatch» вместо «opatchauto» для каждого из применимых исправлений БД.

person Gary Cates    schedule 20.10.2019

Вы можете скачать и скомпилировать libc и установить под /opt/lib/libcX/libc.so.6. Затем у вас может быть сценарий:

LD_LIBRARY_PATH=/opt/lib/libcX:/lib/:/usr/lib:/usr/share/lib
./your_program
person perreal    schedule 05.09.2012
comment
Создание glibc почти всегда является плохой идеей. - person rubenvb; 17.02.2015
comment
На самом деле, ответ, предоставленный @perreal, является действительно надежным и действительным ответом. Дополнительную информацию см. на странице unix.stackexchange.com/a/299665/241016. Комментарий, предоставленный rubenvb, неверен, поскольку он или она упустили из виду, что это сборка libc вместе с существующей системной. - person Roel Van de Paar; 19.02.2018
comment
Это необходимо во время выполнения, чтобы сообщить компоновщику/загрузчику, где найти новую библиотеку, это не имеет ничего общего с компиляцией, верно? - person Accountant م; 20.04.2019

Я не уверен, но если вы используете кросс-компилятор, у вас должны быть где-то установлены совместимые версии основных библиотек (не в /usr/include и /usr/lib), и вы должны убедиться, что их использует компилятор, а не те, что для родного компилятора. И вы должны убедиться, что вся цепочка инструментов совместима по версиям. (И я знаю, что это не очень полный ответ, но это все, что я знаю.)

person James Kanze    schedule 05.09.2012

Обновите до Ubuntu 12.04. У меня было то же самое с использованием Qt, оказалось, что библиотека glibc была слишком старой. Поиск в Google показал, что пытаться обновить glibc самостоятельно — очень опасное занятие.

person Matt Phillips    schedule 05.09.2012
comment
Мне кажется, что он использует кросс-компилятор, но он пытается скомпоновать системные библиотеки. В любом случае, если это кросс-компилятор, обновление системных библиотек ничего не изменит (и не должно). И если он не использует комплектный компилятор, он должен убедиться, что библиотеки совместимы с компилятором (и заголовками), который он использует. - person James Kanze; 05.09.2012
comment
Я не использую кросс-компилятор. Кажется, что по какой-то причине libftd2xx ищет конкретную версию 2.14 libc, где ubuntu 10.04 имеет версию 2.10. - person user1487551; 05.09.2012