Egy letöltési oldal 32 bitet mond, a fájl egy Raspberry Pi-re kerül, és a telepítő olyan üzenettel vall kudarcot, amely a probléma semmilyen hasznos részét nem nevezi meg. Két teljesen különböző végrehajtható fájl az ELF értelmében egyaránt 32 bitesnek számít, és közülük csak az egyik tud azon a lapon futni. Az osztálymező egy tény, a gépmező egy másik, és egy fájlnév megbízhatóan egyiket sem mondja meg. Olvassa el a fejlécet, mielőtt könyvtárat cserél vagy másik tükröt próbál.

Az osztály a szóméretet mondja, a gép az utasításkészletet

A Linux ELF-referencia osztálymezőt és gépmezőt definiál a fájlfejlécben, és a kettő különböző kérdésekre válaszol. Az osztály azt mondja, hogy a fájl 32 bites vagy 64 bites formát használ; a gép azt, hogy melyik utasításkészletre épült. Egy 32 bites x86 build és egy 32 bites ARM build egyetért az elsőben és különbözik a másodikban. Így egy etikett, amely a helyes szóméretet ígéri, mégis olyan kódot szállít, amelyet a processzor nem tud dekódolni. A harmadik olvasásra érdemes érték a kért értelmező, amelyet a programfejlécek megneveznek, amikor a bináris fájl deklarál egyet.

readelf -h -- ./vendor-vpn
readelf -l -- ./vendor-vpn
readelf -d -- ./vendor-vpn | grep NEEDED

Az első parancs kiírja a fejlécet, a második a programfejléceket, ha a fájlnak vannak ilyenek, a harmadik pedig felsorolja a megosztott objektumokat, amelyekre a betöltőnek szüksége lesz. Jegyezze fel az osztályt, a gépet és az értelmezőt együtt, mert ez a három érték az egész kompatibilitási kérdés ezen a szinten. Egyik sem jelenik meg egy letöltési gombon, ezért a fájlt meg kell vizsgálni, nem leírni.

Melyik értelmezőt kéri a kerneltől

Egy végrehajtható fájl, amely értelmezőt deklarál, egy konkrét betöltőútvonalat kér a kerneltől. Ha ez a betöltő hiányzik, az indítás meghiúsul, pedig a megnevezett fájl éppen ott van. Ez az a pont, ahol az emberek úgy döntenek, hogy a letöltés sérült, holott a valódi válasz egy betöltő, amelyet a disztribúció nem szállít.

Illessze a betöltőt ahhoz a rendszerhez, amelyet valóban futtat: az OS kiadása, a felhasználói tér architektúrája és a betöltőt biztosító csomag. Egy 64 bites kernel csak akkor tud 32 bites felhasználói teret futtatni, ha az a tér és a betöltője telepítve van, tehát a processzor képességei nem döntő tényezők. Egy rövid ellenőrzés egyetlen sorban megnevezi az értelmezőt, és kevesebb időt vesz igénybe, mint egy támogatási jegy. A shell-szkript megint másképp vall kudarcot, mert az értelmezője az első sorban van megnevezve, nem ELF-fejlécben, és annak a sornak az elolvasása semmibe sem kerül.

file --brief ./vendor-vpn

Illessze a letöltést a csomag architektúrájához

A disztribúciók csomagarchitektúrái ugyanezt a megkülönböztetést kódolják a saját szókincsükben, és erre a szókincsre hivatkozik egy szállító támogatási nyilatkozata. Hasonlítsa össze a csomagkezelője által jelentett értéket a szállító által dokumentált értékkel, ahelyett hogy egy marketingcímkét hasonlítana össze egy fájlnévvel. A bajt okozó párok az amd64 az arm64-gyel szemben, és az armhf az armel-lel szemben, mert mindegyik pár felcserélhetőnek látszik egy letöltési listán. Az x64-re vagy ia32-re végződő fájlnév buildcélot ír le, nem a gépet, amely tárolja.

Label on the downloadELF classe_machineInterpreter the kernel wantsHow it fails on the wrong host
amd64ELF64x86-64/lib64/ld-linux-x86-64.so.2Immediate exec failure on an ARM board
armhfELF32ARM/lib/ld-linux-armhf.so.3Loads on a soft-float system, then fails on a float ABI call
i386ELF32Intel 80386/lib/ld-linux.so.2Exec format error where no 32-bit loader package exists

Minden sor olyan eset, amikor a szóméret helyesnek látszik és a kód mégis rosszul viselkedik, vagy amikor elindul, majd egy szinttel lejjebb meghiúsul. Az értelmező oszlopát kemény követelményként olvassa, nem utalásként, mert a kernel ezt az útvonalat a kódja bármely részének futása előtt feloldja. Az emuláció saját teljesítmény- és támogatási következményekkel járó telepítési döntés, és szélesebb szóméretet hirdető processzor soha nem sugallja.

dpkg --print-architecture

Az ENOEXEC és az ENOENT különböző hibák

Az indítási szakasz két hiba egyikét jelenti, és ezek különböző problémákra mutatnak. A hibaérték elolvasása még bármi más futtatása előtt osztályozza a kudarcot.

Az ENOEXEC azt jelenti, hogy a formátumot nem ismerték fel: rossz architektúra, rossz osztály vagy valami, ami egyáltalán nem végrehajtható fájl. Az ENOENT egy ELF-fájlon általában azt jelenti, hogy hiányzik az értelmező, pedig a kért fájl létezik. Ugyanez az ENOENT azt is jelentheti, hogy egy szkript értelmezője hiányzik, ezért számít egy szkript első sora. Akárhogy is, az üzenet megnevezi a szintet, és minden „nem található” hiányzó konfigurációként kezelése rossz irányba küldi a vizsgálatot. Idézze a hibaértéket a jegyben, mert jobban túléli az újramondást, mint a körülötte lévő mondat.

Mit ne tegyen, ha a bináris fájl nem indul el

Egy megmagyarázatlan bináris fájl shell-burkolaton át erőltetése nem indítja el. Ne futtasson függőségellenőrzőt könnyelműen olyan fájlon, amelyben nem bízik, mert futtatása bizonyos körülmények között kódot hajthat végre a bináris fájlból. Ne adjon hozzá betöltő-szimlinkeket, ne cseréljen host-könyvtárakat, és ne töltsön le régi archívumot harmadik féltől származó tükörről, hogy megkerülje az üzenetet. Mindegyik szélesíti a változtatás felületét anélkül, hogy hozzáérne ahhoz az eltéréshez, amelyet a fejléc már megnevezett.

Amikor a szállítóhoz fordul, értékeket küldjön, ne történetet: az OS kiadását, a csomag architektúráját, az osztály- és gépkarakterláncokat, a kért értelmezőt és az első hiba sort. Ez a készlet gyorsabban oldja meg a támogatási kérdéseket, mint egy meghiúsuló telepítő képernyőképe. A régi artefaktumok és a felidézett fórumkimenetek nem aktuális támogatási mátrix, és miután egy natív bináris fájl betöltődik, a profil, a hitelesítés és az útválasztás továbbra is külön munka.

Kapcsolódó cikkek