it-swarm-ru.tech

Получение сообщения «Не найдено» при запуске 32-разрядного двоичного файла в 64-разрядной системе

В настоящее время у меня странная проблема с Debian (wheezy/AMD64).

Я создал chroot для установки сервера (я не могу дать более подробную информацию об этом, извините). Давайте назовем его путь /chr_path/. Чтобы упростить задачу, я инициализировал этот chroot с помощью debootstrap (также wheezy/AMD64).

Казалось, что все хорошо работает внутри chroot, но когда я запустил установочный скрипт моего сервера, я получил: zsh: Not found /some_path/Perl (установщик включает в себя бинарный файл Perl по некоторым причинам)

Естественно, я проверил /some_path/ местоположение, и я нашел двоичный файл "Perl". file в среде chroot возвращает:

/some_path/Perl ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped

Файл существует, кажется, в порядке, имеет правильные права. Я могу использовать file, ls, vim, но как только я попытаюсь его выполнить - ./Perl например - я получаю: zsh: Not found ./Perl.

Эта ситуация для меня вполне понятна. Более того :

  • Я могу выполнить другие основные двоичные файлы (/ bin/ls, ...) в chroot без получения ошибок
  • У меня те же проблемы для других двоичных файлов, которые пришли с проектом
  • Когда я пытаюсь выполнить двоичный файл из основного корня (/chr_path/some_path/Perl), оно работает.
  • Я попытался поставить один из двоичных файлов с копией моего ls. Я проверил, что права доступа были одинаковыми, но это ничего не изменило (одно работало, а другое нет)
72
Elenaher

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

  • Загрузчик динамически связанного собственного исполняемого файла является частью системы, которая отвечает за загрузку динамических библиотек. Это что-то вроде /lib/ld.so или /lib/ld-linux.so.2 и ​​должен быть исполняемым файлом.
  • Загрузчик сценария - это программа, упомянутая в строке Shebang, например, /bin/sh для сценария, который начинается с #!/bin/sh. (Bash и zsh в этом случае выдают сообщение "плохой интерпретатор" вместо "команда не найдена".)

Сообщение об ошибке вводит в заблуждение, так как не указывает на проблему с загрузчиком. К сожалению, исправить это было бы сложно, потому что в интерфейсе ядра есть место только для сообщения о числовом коде ошибки, но не для указания того, что ошибка на самом деле касается другого файла. Некоторые оболочки сами работают для скриптов (читая #! строка в сценарии и переработка условия ошибки), но ни одна из тех, что я видел, не пытается сделать то же самое для собственных двоичных файлов.

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

Такая ситуация часто возникает, когда вы пытаетесь запустить двоичный файл для правильной системы (или семейства систем) и суперархитектуры, но не той субархитектуры. Здесь у вас есть двоичные файлы ELF в системе, которая ожидает двоичные файлы ELF, поэтому ядро ​​загружает их просто отлично. Это двоичные файлы i386, работающие на процессоре x86_64, поэтому инструкции имеют смысл и доводят программу до такой степени, что она может искать свой загрузчик. Но это 32-битная программа (как показывает вывод file), ищущая 32-битный загрузчик /lib/ld-linux.so.2, и вы предположительно установили только 64-разрядный загрузчик /lib64/ld-linux-x86-64.so.2 в chroot.

Вам нужно установить 32-битную систему времени выполнения в chroot: загрузчик и все библиотеки, которые нужны программам. Начиная с Debian, если вам нужна поддержка i386 и x86_64, начните с установки AMD64 и активируйте multiarch support: run dpkg --add-architecture i386 тогда apt-get update а также apt-get install libc6:i386 zlib1g:i386 … (если вы хотите сгенерировать список зависимостей пакета Perl Debian, чтобы увидеть, какие библиотеки могут понадобиться, вы можете использовать aptitude search -F %p '~Rdepends:^Perl$ ~ri386'). Вы можете получить коллекцию общих библиотек, установив ia32-libs пакет (сначала нужно включить поддержку multiarch). На Debian AMD64 вплоть до wheezy 32-разрядный загрузчик находится в libc6-i386 пакет. Вы можете установить больший набор 32-битных библиотек, установив ia32-libs .

75

Запустите ldd(1) на вашем Perl бинарном файле. Часто, казалось бы, сбивает с толку Not found ошибка в файле, которая явно существует, потому что одна из общих библиотек, используемых программой, не найдена.

Таким образом, возможно, что ваш chroot неполон в отношении разделяемых библиотек, необходимых вашим двоичным файлам.

5
camh