Почему один и тот же исполняемый файл использует разные RUNPATH для поиска в разных библиотеках? - PullRequest
0 голосов
/ 25 октября 2018

У меня есть программа на Linux C ++, которая создает & ссылки (с -Wl,--no-undefined, не менее), но не может загрузить все свои библиотеки, когда я пытаюсь ее запустить.Я пытался проверить его зависимости с помощью ldd, но я не могу понять, почему он срабатывает из-за сбоя библиотеки:

$ ldd standalone_test
   ...  lots of libraries that are found ...
libPythia6.so => not found

Теперь эта библиотека равна в месте, где он должен быть найден в соответствии с RUNPATH, встроенным в исполняемый файл:

$ readelf -d ./standalone_test | grep "RUNPATH"
 0x000000000000001d (RUNPATH)            Library runpath: [/home/jeremy/code/NOvARwgt/cmake-build-debug/src:/home/jeremy/code/genie-2.12.2/lib:/opt/genie/GENIESupport/pythia6/v6_424/lib:/opt/root/lib:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug]
$ ls /opt/genie/GENIESupport/pythia6/v6_424/lib
liblund.a  libPythia6.so  pydata.o

(и исполняемый файл standalone_test, и библиотека libPythia6.so являются ELF64, поэтому я неНе думаю, что это несовпадение архитектуры процессора или что-то в этом роде.)

Я попытался углубиться в то, что происходит во время загрузки библиотеки, и заметил, что сообщается о различных RUNPATH для загрузкиразные библиотеки под одним и тем же исполняемым файлом (некоторые из них являются «цепочечными» загрузками, когда их запрашивает библиотека, запрошенная исполняемым файлом):

$ LD_DEBUG=libs,files ./standalone_test 2>&1 | ack RUNPATH
  # this one is the 'correct' RUNPATH (the one from the executable)
 19553:  search path=/opt/root/lib/tls/haswell/x86_64:/opt/root/lib/tls/haswell:/opt/root/lib/tls/x86_64:/opt/root/lib/tls:/opt/root/lib/haswell/x86_64:/opt/root/lib/haswell:/opt/root/lib/x86_64:/opt/root/lib        (RUNPATH from file ./standalone_test)
 # next one has been 'augmented' with processor architecture subdirs
 19553:  search path=/home/jeremy/code/NOvARwgt/cmake-build-debug/src/tls/haswell/x86_64:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/tls/haswell:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/tls/x86_64:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/tls:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/haswell/x86_64:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/haswell:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/x86_64:/home/jeremy/code/NOvARwgt/cmake-build-debug/src:/home/jeremy/code/genie-2.12.2/lib/tls/haswell/x86_64:/home/jeremy/code/genie-2.12.2/lib/tls/haswell:/home/jeremy/code/genie-2.12.2/lib/tls/x86_64:/home/jeremy/code/genie-2.12.2/lib/tls:/home/jeremy/code/genie-2.12.2/lib/haswell/x86_64:/home/jeremy/code/genie-2.12.2/lib/haswell:/home/jeremy/code/genie-2.12.2/lib/x86_64:/home/jeremy/code/genie-2.12.2/lib:/opt/genie/GENIESupport/pythia6/v6_424/lib/tls/haswell/x86_64:/opt/genie/GENIESupport/pythia6/v6_424/lib/tls/haswell:/opt/genie/GENIESupport/pythia6/v6_424/lib/tls/x86_64:/opt/genie/GENIESupport/pythia6/v6_424/lib/tls:/opt/genie/GENIESupport/pythia6/v6_424/lib/haswell/x86_64:/opt/genie/GENIESupport/pythia6/v6_424/lib/haswell:/opt/genie/GENIESupport/pythia6/v6_424/lib/x86_64:/opt/genie/GENIESupport/pythia6/v6_424/lib:/opt/root/lib:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/tls/haswell/x86_64:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/tls/haswell:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/tls/x86_64:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/tls:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/haswell/x86_64:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/haswell:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/x86_64:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug      (RUNPATH from file ./standalone_test)
    ... more variants of these two ...
 # this one contains only a single entry from the real runpath??
 19553:  search path=/opt/root/lib      (RUNPATH from file ./standalone_test)

В последнем случае - та, где библиотекане найден, и исполняемый файл завершается с ошибкой cannot open shared object file: No such file or directory, он переходит также к поиску в системном пути поиска.

Мой вопрос: как эти варианты на RUNPATH concocted? Я понял, что они изменены различными библиотеками, которые как-то их запрашивают, но я не могу найти каких-либо объяснений там на веб-сайтах Google.(Может быть, я ищу не ту вещь?) Кажется, что если бы я понял, что здесь происходит, я бы смог вернуться назад к пониманию того, почему библиотека не была найдена.

1 Ответ

0 голосов
/ 28 октября 2018

Мой вопрос: как эти варианты на RUNPATH придуманы?

В отличие от старых RPATH, RUNPATH применяется только при поиске прямые зависимости двоичного файла.

То есть, если a.out имеет RUNPATH из /foo и NEEDED из libfoo.so (находится в /foo), то libfoo.so будет найдено.Но если libfoo.so зависит от libbar.so (также находится в /foo), и если libfoo.so не имеет RUNPATH, то libbar.so будет не быть найденным.

Это поведение способствует "каждый двоичный файл ELF должен быть самодостаточным".В вышеприведенном случае libfoo.so не является самодостаточным (требуется libbar.so, но не говорит, где его найти).

Если вы используете RPATH, путь к нему будет применяться к каждый поиск и libbar.so будут найдены.Вы можете достичь этого с помощью -Wl,--disable-new-dtags при связывании a.out.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...