En nedlastingsside sier 32-bit, filen lander på en Raspberry Pi, og installatøren feiler med en melding som ikke navngir noen nyttig del av problemet. To helt forskjellige kjørbare filer telles begge som 32-bit i ELF-forstand, og bare én av dem kan kjøre på det kortet. Klassefeltet er ett faktum, maskinfeltet er et annet, og et filnavn forteller deg pålitelig ingen av dem. Les headeren før du bytter et bibliotek eller prøver en annen speiling.

Klassen sier ordstørrelse, maskinen sier instruksjonssett

Linux ELF-referansen definerer et klassefelt og et maskinfelt i filheaderen, og de to svarer på forskjellige spørsmål. Klassen sier om filen bruker 32-bit- eller 64-bit-formen; maskinen sier hvilket instruksjonssett den er bygget for. Et 32-bit x86-bygg og et 32-bit ARM-bygg er enige om det første og uenige om det andre. Slik leverer en etikett som lover riktig ordstørrelse likevel kode som prosessoren ikke kan dekode. Den tredje verdien som er verdt å lese, er tolken som bes om, og som programheaderne navngir når den binære filen erklærer en.

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

Den første kommandoen skriver ut headeren, den andre skriver ut programheadere når filen har noen, og den tredje lister opp de delte objektene som lasteren trenger. Noter klasse, maskin og tolk sammen, fordi disse tre verdiene er hele kompatibilitetsspørsmålet på dette nivået. Ingen av de tre står på en nedlastingsknapp, og derfor må filen undersøkes i stedet for beskrives.

Hvilken tolk den ber kjernen om

En kjørbar fil som erklærer en tolk, ber kjernen om én bestemt lastersti. Når den lasteren mangler, feiler oppstarten selv om filen du navnga ligger rett der. Det er her folk konkluderer med at nedlastingen er ødelagt, mens det faktiske svaret er en laster som distribusjonen ikke leverer.

Tilpass lasteren til systemet du faktisk kjører: OS-utgaven, arkitekturen i brukerrommet og pakken som leverer lasteren. En 64-bits kjerne kan bare kjøre et 32-bits brukerrom når det brukerrommet og lasteren er installert, så prosessorens evner er ikke den avgjørende faktoren. Én kort sjekk navngir tolken på én linje, og den tar mindre tid enn en støttebillett. Et shell-skript feiler på en annen måte igjen, fordi tolken er navngitt på første linje og ikke i en ELF-header, og å lese den linjen koster ingenting.

file --brief ./vendor-vpn

Tilpass nedlastingen til pakkearkitekturen

Distribusjonenes pakkearkitekturer koder den samme forskjellen i sitt eget vokabular, og det er dette vokabularet en leverandørs støtteerklæring viser til. Sammenlign verdien pakkebehandleren din rapporterer, med verdien leverandøren dokumenterer, i stedet for å sammenligne en markedsføringsetikett med et filnavn. Parene som skaper trøbbel, er amd64 mot arm64 og armhf mot armel, fordi hvert par ser utbyttbart ut i en nedlastingsliste. Et filnavn som slutter på x64 eller ia32 beskriver et byggemål, ikke maskinen som holder det.

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

Hver rad er et tilfelle der ordstørrelsen ser riktig ut og koden likevel oppfører seg feil, eller der den starter og deretter feiler ett lag lenger ned. Les tolkekolonnen som et hardt krav og ikke som et hint, fordi kjernen løser den stien før noe av koden din kjører. Emulering er en utrullingsbeslutning med sine egne konsekvenser for ytelse og støtte, og den antydes aldri av en prosessor som reklamerer med en bredere ordstørrelse.

dpkg --print-architecture

ENOEXEC og ENOENT er forskjellige feil

Oppstartsfasen rapporterer én av to feil, og de peker på forskjellige problemer. Å lese feilverdien klassifiserer feilen før du kjører noe annet.

ENOEXEC betyr at formatet ikke ble gjenkjent: feil arkitektur, feil klasse eller noe som ikke er en kjørbar fil i det hele tatt. ENOENT på en ELF-fil betyr vanligvis at tolken mangler, selv om filen du ba om, finnes. Den samme ENOENT kan også bety at tolken til et skript mangler, og derfor betyr første linje i et skript noe. Uansett navngir meldingen laget, og å behandle hver «ikke funnet» som en manglende konfigurasjon sender undersøkelsen i feil retning. Siter feilverdien i billetten, fordi den overlever gjenfortelling bedre enn setningen rundt.

Hva du ikke bør gjøre når den binære filen ikke starter

Å tvinge en uforklart binær fil gjennom en shell-innpakning får den ikke til å kjøre. Ikke kjør en avhengighetssjekk lettvint på en fil du ikke stoler på, fordi kjøringen i visse tilfeller kan utføre kode fra den binære filen. Ikke legg til laster-symlenker, bytt ikke vertsbiblioteker og hent ikke et gammelt arkiv fra en tredjepartsspeiling for å komme forbi meldingen. Hver av disse utvider endringsflaten uten å røre uoverensstemmelsen som headeren allerede har navngitt.

Når du henvender deg til leverandøren, send verdier og ikke en historie: OS-utgaven, pakkearkitekturen, klasse- og maskinstrengene, tolken som bes om, og den første feillinjen. Det settet løser støttespørsmål raskere enn et skjermbilde av en installatør som feiler. Gamle artefakter og husket forumutdata er ikke en gjeldende støttematrise, og når en innebygd binærfil er lastet, er profil, autentisering og ruting fortsatt separat arbeid.

Relaterte artikler