ldd показывает, что ELF-интерпретатор присутствует, но я все еще получаю «Нет такого файла или каталога» - PullRequest
2 голосов
/ 18 октября 2019

Недавно я пытался перенести существующее приложение C ++ в новую производственную среду (обновленное ядро, обновленный glibc и т. Д.). Несмотря на то, что вывод ldd показал, что все мои .so были найдены, включая интерпретатор ELF, выполнение всегда приводило к «Нет такого файла или каталога».

$ ldd my_app

    libpthread.so.0 => /lib/libpthread.so.0 (0x00007fd41afd6000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007fd41ae52000)
    libm.so.6 => /lib/libm.so.6 (0x00007fd41ad11000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007fd41acf7000)
    libc.so.6 => /lib/libc.so.6 (0x00007fd41ab3a000)
    /lib64/ld-linux-x86-64.so.2 => /lib/ld-linux-x86-64.so.2 (0x00007fd4258b5000) <= ELF Interpreter
    libconfig.so.9 => /usr/lib/libconfig.so.9 (0x00007fd41ab2c000)
    libsensors.so.4 => /usr/lib/libsensors.so.4 (0x00007fd41ab1b000)

$ file my_app

     ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=c8c7eeb2f6bdb96dab7b0cc9ad41aa6e3d610ec7, stripped

$ readelf -a my_app |grep "интерпретатор"

  [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

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

  ln -s /lib/ld-2.29.so /lib64/ld-linux-x86-64.so.2

Это наконец решило проблему. В конце концов, я был разочарован, так как я не искал настоящую проблему, и мне потребовалось слишком много времени, чтобы понять ее из-за вводящего в заблуждение вывода ldd.

Почему ldd говорит, что интерпретатор присутствует, хотяон не будет загружен при запуске двоичного файла? Моя интерпретация использования / вывода ldd ошибочна?

Ответы [ 2 ]

2 голосов
/ 19 октября 2019

В glibc динамический загрузчик ld.so. используется как интерпретатор программы и как загруженный общий объект. ldd отображает только последнее. Он может найти ld.so, потому что находится либо в пути поиска, либо в кэше ld.so. Напротив, когда ядро ​​пытается загрузить программный интерпретатор, оно использует только точный путь, указанный в программе, поэтому пути поиска и т.п. не применяются.

Правильный путь в соответствии с ABIруководство - это /lib64/ld-linux-x86-64.so.2. Если ваша система не имеет этого, она не следует ABI GNU / Linux x86-64, что довольно странно.

2 голосов
/ 19 октября 2019

в новой производственной среде

Ваша новая производственная среда установила ld-linux-x86-64.so.2 в /lib вместо /lib64. Это очень необычно и нестандартно. Многие бинарные файлы не смогут работать в такой системе. Тот, кто «создал» эту систему, вероятно, совершил серьезную ошибку.

Почему ldd говорит, что там есть переводчик

Способ работы ldd таков: он устанавливаетпеременная окружения LD_TRACE_OBJECTS=1 и вызывает интерпретатор real , с которым она была скомпилирована.

Поскольку ваша система (ошибочно) установлена ​​ld-linux в /lib, ldd должным образом вызвана /lib/ld-linux-x86-64.so.2, который существует существует, и фактически сказал вам об этом.

В общем, ldd не заслуживает доверия, особенно когда несколько версий GLIBC установлены наединая система.

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