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.