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

<p>в настоящее время у меня странная проблема с debian (wheezy/amd64).</p><p>я создал chroot для установки сервера (я не могу дать более подробную информацию об этом, извините). давайте назовем его путь <code>/chr\_path/</code>. чтобы упростить задачу, я инициализировал этот chroot с помощью debootstrap (также wheezy/amd64).</p><p>казалось, что все хорошо работает внутри chroot, но когда я запустил установочный скрипт моего сервера, я получил: <code>zsh: not found /some\_path/perl</code> (установщик включает в себя бинарный файл perl по некоторым причинам)</p><p>естественно, я проверил <code>/some\_path/</code> местоположение, и я нашел двоичный файл "perl". <code>file</code> в среде chroot возвращает:</p><pre><code>/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 </code></pre><p>файл существует, кажется, в порядке, имеет правильные права. я могу использовать <code>file</code>, <code>ls</code>, <code>vim</code>, но как только я попытаюсь его выполнить - <code>./perl</code> например - я получаю: <code>zsh: not found ./perl</code>.</p><p>эта ситуация для меня вполне понятна. более того :</p><ul> <li>я могу выполнить другие основные двоичные файлы (/ bin/ls, ...) в chroot без получения ошибок</li> <li>у меня те же проблемы для других двоичных файлов, которые пришли с проектом</li> <li>когда я пытаюсь выполнить двоичный файл из основного корня (<code>/chr\_path/some\_path/perl</code>), оно работает.</li> <li>я попытался поставить один из двоичных файлов с копией моего <code>ls</code>. я проверил, что права доступа были одинаковыми, но это ничего не изменило (одно работало, а другое нет)</li> </ul>

<p>если вам не удается выполнить файл, который зависит от "загрузчика", полученная ошибка может относиться к загрузчику, а не к исполняемому файлу.</p><ul> <li>загрузчик динамически связанного собственного исполняемого файла является частью системы, которая отвечает за загрузку динамических библиотек. это что-то вроде <code>/lib/ld.so</code> или <code>/lib/ld-linux.so.2</code> и должен быть исполняемым файлом.</li> <li>загрузчик сценария - это программа, упомянутая в строке shebang, например, <code>/bin/sh</code> для сценария, который начинается с <code>#!/bin/sh</code>. (bash и zsh в этом случае выдают сообщение "плохой интерпретатор" вместо "команда не найдена".)</li> </ul><p>сообщение об ошибке вводит в заблуждение, так как не указывает на проблему с загрузчиком. к сожалению, исправить это было бы сложно, потому что в интерфейсе ядра есть место только для сообщения о числовом коде ошибки, но не для указания того, что ошибка на самом деле касается другого файла. некоторые оболочки сами работают для скриптов (читая <code>#!</code> строка в сценарии и переработка условия ошибки), но ни одна из тех, что я видел, не пытается сделать то же самое для собственных двоичных файлов.</p><p><code>ldd</code> также не будет работать с двоичными файлами, потому что он работает, устанавливая некоторые специальные переменные окружения, а затем запускает программу, позволяя загрузчику делать всю работу. <code>strace</code> также не предоставит никакой значимой информации, поскольку она не будет сообщать больше, чем то, что сообщает ядро, и, как мы видели, ядро не может сообщить все, что оно знает.</p><p>такая ситуация часто возникает, когда вы пытаетесь запустить двоичный файл для правильной системы (или семейства систем) и суперархитектуры, но не той субархитектуры. здесь у вас есть двоичные файлы elf в системе, которая ожидает двоичные файлы elf, поэтому ядро загружает их просто отлично. это двоичные файлы i386, работающие на процессоре x86\_64, поэтому инструкции имеют смысл и доводят программу до такой степени, что она может искать свой загрузчик. но это 32-битная программа (как показывает вывод <code>file</code>), ищущая 32-битный загрузчик <code>/lib/ld-linux.so.2</code>, и вы предположительно установили только 64-разрядный загрузчик <code>/lib64/ld-linux-x86-64.so.2</code> в chroot.</p><p>вам нужно установить 32-битную систему времени выполнения в chroot: загрузчик и все библиотеки, которые нужны программам. начиная с debian, если вам нужна поддержка i386 и x86\_64, начните с установки amd64 и активируйте <a href="https://wiki.debian.org/multiarch/howto">multiarch</a> support: run <code>dpkg --add-architecture i386</code> тогда <code>apt-get update</code> а также <code>apt-get install libc6:i386 zlib1g:i386 …</code> (если вы хотите сгенерировать список зависимостей пакета perl debian, чтобы увидеть, какие библиотеки могут понадобиться, вы можете использовать <code>aptitude search -f %p '~rdepends:^perl$ ~ri386'</code>). вы можете получить коллекцию общих библиотек, установив <a href="http://packages.debian.org/wheezy/ia32-libs"><code>ia32-libs</code></a> пакет (сначала нужно включить поддержку multiarch). на debian amd64 вплоть до wheezy 32-разрядный загрузчик находится в <a href="http://packages.debian.org/libc6-i386"><code>libc6-i386</code></a> пакет. вы можете установить больший набор 32-битных библиотек, установив <a href="http://packages.debian.org/squeeze/ia32-libs"><code>ia32-libs</code></a> .</p>

<p>запустите <code>ldd(1)</code> на вашем <code>perl</code> бинарном файле. часто, казалось бы, сбивает с толку <code>not found</code> ошибка в файле, которая явно существует, потому что одна из общих библиотек, используемых программой, не найдена.</p><p>таким образом, возможно, что ваш chroot неполон в отношении разделяемых библиотек, необходимых вашим двоичным файлам.</p>