Otrzymywanie komunikatu „Nie znaleziono” podczas uruchamiania 32-bitowego pliku binarnego w 64-bitowym systemie


70

Mam obecnie dziwny problem z Debianem (wheezy / amd64).

Utworzyłem chroota, aby zainstalować serwer (przepraszam, nie mogę podać więcej szczegółów). Nazwijmy jego ścieżkę /chr_path/. Aby to ułatwić, zainicjowałem tego chroota za pomocą paska debootstrap (także wheezy / amd64).

Wyglądało na to, że wszystko działa dobrze w chroot, ale kiedy uruchomiłem skrypt instalacyjny mojego serwera, otrzymałem: zsh: Not found /some_path/perl(z pewnych powodów instalator zawiera plik binarny perla)

Oczywiście sprawdziłem /some_path/lokalizację i znalazłem plik binarny „perl”. filew środowisku chroot zwraca:

/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

Plik istnieje, wydaje się być w porządku, ma poprawne prawa. Mogę użyć file, ls, vimna nim, ale jak tylko próbuję go uruchomić - ./perlna przykład - uzyskać: zsh: Not found ./perl.

Ta sytuacja jest dla mnie całkiem zrozumiała. Ponadto :

  • Mogę wykonywać inne podstawowe pliki binarne (/ bin / ls, ...) w chroot bez otrzymywania błędów
  • Mam takie same problemy z innymi plikami binarnymi dostarczonymi z projektem
  • Kiedy próbuję uruchomić plik binarny z głównego katalogu głównego ( /chr_path/some_path/perl), działa.
  • Próbowałem umieścić jeden z plików binarnych z kopią mojego ls. Sprawdziłem, czy prawa dostępu były takie same, ale to niczego nie zmieniło (jedno działało, a drugie nie)

1
Jest to ten sam problem, co „Brak takiego pliku lub katalogu” dotyczy plików binarnych zainstalowanych przez Optware . Zauważ, że twój Perl jest 32-bitowym plikiem wykonywalnym. Brakuje 32-bitowego systemu wykonawczego ( libc6-i386pakietu lub ia32-libsjeśli chcesz mieć wiele bibliotek).
— Gilles

@Gilles: Wielkie dzięki! Instalacja apta ia32-libs rozwiązała problem !! Widziałem, że perl ma 32 bity, ale ponieważ działał na głównym systemie (ta sama dystrybucja), po prostu założyłem, że nie jest połączony. Właściwie w pewnym momencie musiałem zainstalować 32-bitowy system wykonawczy w systemie głównym.
— Elenaher

1
@Gilles: Myślę, że dodałbym to jako zwięzłą odpowiedź zamiast oznaczać to jako duplikat pytania. Środowisko jest na tyle różne, że nawet jeśli problem jest taki sam, osoby szukające częściej trafiają w jedno lub drugie.
— Caleb

1
@Caleb Nie usuwamy duplikatów z tego właśnie powodu; szukający, którzy go znajdą, będą po prostu podążać za duplikatem linku do drugiego postu. Jeśli jest to ten sam problem, prawdopodobnie należy go po prostu zamknąć
— Michał Mrożek

@MichaelMrozek Zmieniłem zdanie na temat tego pytania: chociaż podstawowy problem jest taki sam, konkretne rozwiązanie jest nieco inne (brak mieszania ARI ABI w jednym przypadku, umożliwianie 32-bitowej obsługi dystrybucji Linuksa amd64 w drugiej) . Sądzę więc, że to pytanie należy w końcu otworzyć.
— Gilles,

Odpowiedzi:


72

Jeśli nie uda się uruchomić pliku zależnego od „modułu ładującego”, wyświetlony błąd może dotyczyć modułu ładującego, a nie wykonywanego pliku.

  • Moduł ładujący dynamicznie połączonego natywnego pliku wykonywalnego jest częścią systemu odpowiedzialną za ładowanie bibliotek dynamicznych. Jest to coś w rodzaju /lib/ld.solub /lib/ld-linux.so.2i powinno być plikiem wykonywalnym.
  • Program ładujący skrypt to program wymieniony w wierszu shebang, np. /bin/shDla skryptu, który zaczyna się od #!/bin/sh. (Bash i zsh podają komunikat „zły tłumacz” zamiast „polecenia nie znaleziono” w tym przypadku.)

Komunikat o błędzie jest raczej mylący, ponieważ nie oznacza, że ​​problem stanowi moduł ładujący. Niestety, naprawienie tego byłoby trudne, ponieważ interfejs jądra ma miejsce tylko na zgłoszenie liczbowego kodu błędu, a nie na wskazanie, że błąd w rzeczywistości dotyczy innego pliku. Niektóre powłoki wykonują same prace dla skryptów (odczytując #!wiersz skryptu i ponownie sprawdzając warunek błędu), ale żadna z tych, które widziałem, nie próbuje zrobić tego samego dla natywnych plików binarnych.

lddnie będzie działać na plikach binarnych, ponieważ działa poprzez ustawienie specjalnych zmiennych środowiskowych, a następnie uruchomienie programu, umożliwiając programowi ładującemu wykonanie pracy. stracenie dostarczyłby również żadnych istotnych informacji, ponieważ nie zgłosiłby więcej niż to, co zgłasza jądro, a jak widzieliśmy, jądro nie może zgłaszać wszystkiego, co wie.

Taka sytuacja często pojawia się, gdy próbujesz uruchomić plik binarny dla odpowiedniego systemu (lub rodziny systemów) i superarchitektury, ale niewłaściwej podarchitektury. Tutaj masz pliki binarne ELF w systemie, który oczekuje plików binarnych ELF, więc jądro ładuje je dobrze. Są to pliki binarne i386 działające na procesorze x86_64, więc instrukcje mają sens i doprowadzają program do punktu, w którym może szukać swojego modułu ładującego. Ale program jest programem 32-bitowym (jak filewskazuje dane wyjściowe), szuka 32-bitowego programu ładującego /lib/ld-linux.so.2i prawdopodobnie zainstalowałeś tylko 64-bitowy moduł ładujący /lib64/ld-linux-x86-64.so.2w chroot.

Musisz zainstalować 32-bitowy system wykonawczy w chroot: moduł ładujący i wszystkie biblioteki, których potrzebują programy. Począwszy od wersji Debian wheezy, jeśli chcesz obsługiwać zarówno i386, jak i x86_64, zacznij od instalacji amd64 i aktywuj obsługę wielu ścieżek : uruchom dpkg --add-architecture i386wtedy apt-get updatei apt-get install libc6:i386 zlib1g:i386 …(jeśli chcesz wygenerować listę zależności pakietu perla Debiana, aby zobaczyć, jakie biblioteki prawdopodobnie będą być potrzebne, możesz użyć aptitude search -F %p '~Rdepends:^perl$ ~ri386'). Możesz pobrać kolekcję popularnych bibliotek, instalując ia32-libspakiet (najpierw musisz włączyć obsługę wielu kanałów). W systemie Debian amd64 aż do wheezy, 32-bitowy moduł ładujący znajduje się w libc6-i386pakiecie. Instalując, możesz zainstalować większy zestaw bibliotek 32-bitowych ia32-libs.


Czy to jedyna rzecz, która może wywołać komunikat o błędzie? Mam zainstalowane biblioteki 32-bitowe i oto dane wyjściowe,ldd ale nadal pojawia się ten sam błąd.
— Nathan Osman

1
@NathanOsman Prawdopodobnie unix.stackexchange.com/questions/76490/...
— Gilles

Próbowałem zainstalować, lsb-coreale to nie pomogło. Myślę, że lepiej otworzyć na to nowe pytanie.
— Nathan Osman

Dziękuję za to, właśnie skończyłeś dwa dni drapania głowy. Myślałem, że wszystko jest kompilowane statycznie, ale tak nie było!
— Finn O'leary,

5

Uruchom ldd(1)na swoim perlpliku binarnym. Często pozornie mylący Not foundbłąd w pliku, który najwyraźniej istnieje, ponieważ nie znaleziono jednej z bibliotek współdzielonych używanych przez program.

Możliwe więc, że twój chroot jest niekompletny w odniesieniu do bibliotek współdzielonych wymaganych przez twoje pliki binarne.


Właściwie to dostaję: perl is not a dynamic executablekiedy jestem w chroot i otrzymuję prawidłową listę zależności z zewnątrz. Obecnie sprawdzam, czy jest coś dziwnego, ale użyłem paska deboot, aby uniknąć tego rodzaju braku i mam już wiele bibliotek lib (w systemie chroot jest wykonywalny perl, który działa dobrze, ale jest to inna wersja; być może zrobię trochę link symboliczny?)
— Elenaher

Szczerze mówiąc, spodziewałbym się, że debootstrap stworzy kompletny chroot, więc nie spodziewałbym się, że moja odpowiedź będzie poprawna w tym zakresie. Ale już wcześniej natknąłem się na brakującą bibliotekę z problemem chroot, więc pomyślałem, że zobaczę, czy moja odpowiedź się sprawdzi.
— camh

por. komentarz do Gillesa w głównym poście: Miałeś rację. Brakowało niektórych bibliotek. Główną zaletą debootstrap jest to, że mogłem rozwiązać problem za pomocą podstawowej instalacji aptitude :)
— Elenaher
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.