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

70

В настоящее время у меня странная проблема с 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 без получения ошибок
  • У меня те же проблемы для других двоичных файлов, которые пришли с проектом
  • Когда я пытаюсь выполнить двоичный файл из основного root ( /chr_path/some_path/perl), он работает.
  • Я попытался поставить один из двоичных файлов с копией моей ls. Я проверил, что права доступа были одинаковыми, но это ничего не изменило (одно работало, а другое нет)
Elenaher
источник
1
Это та же проблема, что и «Нет таких файлов или каталогов», лежащих в двоичных файлах, установленных Optware . Обратите внимание, что ваш Perl является 32-битным исполняемым файлом. Вам не хватает 32-битной системы времени исполнения ( libc6-i386пакета или ia32-libsесли вам нужно много библиотек).
Жиль "ТАК - перестань быть злым"
@ Жиль: Большое спасибо! Способность установить ia32-libs решила проблему !! Я видел, что Perl был 32-битным, но так как он работал в основной системе (тот же дистрибутив), я просто предположил, что он не связан. На самом деле, я должен был установить 32-битную систему времени выполнения в основной системе в какой-то момент.
Elenaher
1
@ Жиль: Думаю, я бы добавил это в качестве краткого ответа вместо того, чтобы отмечать его как дублирующий вопрос. Среда достаточно различна, поэтому, несмотря на то, что проблема одна и та же, поиски людей с большей вероятностью попадут в одну или другую.
Калеб
1
@Caleb Мы не удаляем дубликаты именно по этой причине; искатели, которые найдут этот, просто перейдут по дублирующей ссылке на другой пост. Если это та же самая проблема, ее, вероятно, следует просто закрыть
Майкл Мрозек
@MichaelMrozek Я изменил свое мнение по этому вопросу: хотя основная проблема та же, конкретное средство немного отличается (не смешивая ARM ABI в одном случае, включая 32-битную поддержку в дистрибутиве amd64 Linux в другом) , Так что я думаю, что этот вопрос все-таки остается открытым.
Жиль "ТАК - перестань быть злым"

Ответы:

72

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

  • Загрузчик динамически связанного собственного исполняемого файла является частью системы, которая отвечает за загрузку динамических библиотек. Это что-то вроде /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 wheezy и далее, если вам нужна поддержка i386 и x86_64, начните с установки amd64 и активируйте поддержку multiarch : запустите dpkg --add-architecture i386then 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.

Жиль "ТАК - перестань быть злым"
источник
Это единственное, что может вызвать сообщение об ошибке? У меня установлены 32-битные библиотеки, и вот вывод,ldd но я все еще получаю ту же ошибку.
Натан Осман
1
@NathanOsman Вероятно, unix.stackexchange.com/questions/76490/…
Жиль "ТАК, перестань быть злым"
Я пытался установить, lsb-coreно это не помогло. Я думаю, мне лучше открыть новый вопрос для этого.
Натан Осман
Спасибо вам за это, вы только что закончили два дня чесать голову. Я думал, что все статически компилируется, но это не так!
Финн О'Лери,
5

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

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

CAMH
источник
На самом деле я получаю: perl is not a dynamic executableкогда я в chroot, и я получаю правильный список зависимостей извне. В настоящее время я проверяю, есть ли что-то странное, но я использовал debootstrap, чтобы избежать такого недостатка, и у меня уже есть много библиотек (есть исполняемый файл perl в системе chroot, который работает хорошо, но это другая версия; возможно, я просто сделаю несколько символическая ссылка?)
Elenaher
Честно говоря, я ожидал, что debootstrap создаст полный chroot, поэтому я не ожидаю, что мой ответ будет правильным в этом отношении. Но я столкнулся с отсутствующей библиотекой в ​​проблеме с chroot, поэтому подумал, увижу ли мой ответ.
Camh
ср комментарий Жилю к основному сообщению: Вы были правы. Там не хватает некоторых библиотек. Основным преимуществом debootstrap является то, что я могу решить проблему с базовой установкой aptitude :)
Elenaher