Отримання повідомлення "Не знайдено" під час запуску 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, не отримуючи помилок
  • У мене такі ж проблеми і для інших бінарних файлів, які поставились із проектом
  • Коли я намагаюся виконати двійковий файл з головного кореня ( /chr_path/some_path/perl), він працює.
  • Я спробував покласти один із бінарних файлів із копією моєї ls. Я перевірив, що права доступу однакові, але це нічого не змінило (один працював, а другий не був)

1
Це те саме питання, що "Немає такого файлу чи каталогу" лежить на встановлених Optware бінарних файлах . Зауважте, що ваш Perl - це 32-бітний виконуваний файл. Вам не вистачає 32-бітної системи виконання ( libc6-i386пакет або ia32-libsякщо ви хочете багато бібліотек).
Жиль

@Gilles: Велике спасибі! Здатність встановити ia32-libs вирішила проблему !! Я бачив, що Perl має 32 біти, але оскільки він працював на основній системі (той же дистрибутив), я тільки припустив, що він не пов'язаний. Насправді я повинен був встановити 32-бітну систему виконання в основній системі в якийсь момент.
Оленагер

1
@Gilles: Я думаю, я би додав це як стислу відповідь, а не маркувати це як повторне запитання. Навколишнє середовище досить різне, що, хоча проблема однакова, люди, які шукають, швидше вдаряться про те чи інше.
Калеб

1
@Caleb Ми не видаляємо дублікати саме з цієї причини; шукачі, які знайдуть цю, просто перейдуть на повторне посилання на іншу публікацію. Якщо це та сама проблема, її, мабуть, слід просто закрити
Майкл Мрозек

@MichaelMrozek Я змінив свою думку з цього питання: хоча основна проблема однакова, конкретний засіб дещо інший (не змішуючи ARI ABI в одному випадку, що дозволяє підтримувати 32-бітну підтримку дистрибутива amd64 в іншому) . Тож я думаю, це питання належить відкрито.
Жиль

Відповіді:


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 і активуйте підтримку мультиарха : запустіть 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пакет (спочатку потрібно включити підтримку багатоархів). На 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 є неповним щодо спільних бібліотек, необхідних вашим бінарним файлам.


Насправді я розумію: perl is not a dynamic executableколи я перебуваю в хроту і отримую правильний перелік залежностей ззовні. Я зараз перевіряю, чи є щось дивне, але я використав debootstrap, щоб уникнути подібних нестач і у мене вже багато ліфтів (у системі chroot працює добре виконаний Perl, але це інша версія; можливо, я просто зроблю кілька символічне посилання?)
Elenaher

Якщо чесно кажучи, я б очікував, що дебоотстрап дасть повний Chroot, тому я б не очікував, що моя відповідь буде правильною у цьому відношенні. Але раніше я перебігав через відсутність бібліотеки у проблемі chroot, тому думав, що побачу, чи відповість моя відповідь.
camh

пор. коментар до Жилла на головній публікації: Ви мали рацію. Не вистачало якихось губ. Основна перевага debootstrap полягає в тому, що я міг вирішити проблему з базовим встановленням придатності :)
Elenaher
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.