VPN-installatør siger 32-bit: undersøg ELF-headeren i stedet
Ordstørrelse identificerer ikke instruktionssættet. Procedure for at læse klasse, maskine og interpreter og derefter bede om et build, der matcher værten.
En downloadside siger 32-bit, filen lander på en Raspberry Pi, og installatøren fejler med en besked, der ikke nævner nogen brugbar del af problemet. To helt forskellige eksekverbare filer tæller begge som 32-bit i ELF-forstand, og kun én af dem kan køre på det board. Klassefeltet er ét faktum, maskinfeltet er et andet, og et filnavn fortæller dig pålideligt ingen af dem. Læs headeren, før du skifter et bibliotek eller prøver et andet spejl.
Klassen siger ordstørrelse, maskinen siger instruktionssæt
Linux ELF-reference definerer et klassefelt og et maskinfelt i filheaderen, og de to besvarer forskellige spørgsmål. Klassen siger, om filen bruger 32-bit- eller 64-bit-form; maskinen siger, hvilket instruktionssæt den er bygget til. Et 32-bit x86-build og et 32-bit ARM-build er enige om det første og uenige om det andet. Det er sådan en etiket, der lover den rigtige ordstørrelse, stadig leverer kode, som processoren ikke kan afkode. Den tredje værdi, der er værd at læse, er den ønskede interpreter, som programheaderne nævner, når den binære fil erklærer en.
readelf -h -- ./vendor-vpn
readelf -l -- ./vendor-vpn
readelf -d -- ./vendor-vpn | grep NEEDED
Den første kommando udskriver headeren, den anden udskriver programheadere, når filen har nogen, og den tredje viser de delte objekter, som loaderen får brug for. Notér klasse, maskine og interpreter sammen, fordi de tre værdier er hele kompatibilitetsspørgsmålet på dette lag. Ingen af de tre står på en downloadknap, og derfor skal filen undersøges i stedet for beskrives.
Hvilken interpreter den beder kernen om
En eksekverbar fil, der erklærer en interpreter, beder kernen om én bestemt loader-sti. Når den loader mangler, fejler starten, selv om filen, du angav, ligger lige der. Det er her, folk konkluderer, at downloadet er beskadiget, mens det faktiske svar er en loader, som distributionen ikke leverer.
Match loaderen til det system, du faktisk kører: OS-versionen, brugerrummets arkitektur og den pakke, der leverer loaderen. En 64-bit kerne kan kun køre et 32-bit brugerrum, når dette brugerrum og dets loader er installeret, så processorens evner er ikke den afgørende faktor. Én kort kontrol nævner interpreten på en enkelt linje, og det tager mindre tid end en supportbillet. Et shell-script fejler igen på en anden måde, fordi dets interpreter er nævnt på første linje og ikke i en ELF-header, og at læse den linje koster intet.
file --brief ./vendor-vpn
Match downloadet til pakkens arkitektur
Distributionspakkernes arkitekturer koder den samme forskel i deres eget ordforråd, og det ordforråd er, hvad en leverandørs supportudtalelse henviser til. Sammenlign den værdi, din pakkehåndtering rapporterer, med den værdi, leverandøren dokumenterer, i stedet for at sammenligne en marketingetiket med et filnavn. De par, der volder problemer, er amd64 mod arm64 og armhf mod armel, fordi hvert par ser udskifteligt ud på en downloadliste. Et filnavn, der slutter på x64 eller ia32, beskriver et build-mål, ikke maskinen, der rummer det.
| Label on the download | ELF class | e_machine | Interpreter the kernel wants | How it fails on the wrong host |
|---|---|---|---|---|
| amd64 | ELF64 | x86-64 | /lib64/ld-linux-x86-64.so.2 | Immediate exec failure on an ARM board |
| armhf | ELF32 | ARM | /lib/ld-linux-armhf.so.3 | Loads on a soft-float system, then fails on a float ABI call |
| i386 | ELF32 | Intel 80386 | /lib/ld-linux.so.2 | Exec format error where no 32-bit loader package exists |
Hver række er et tilfælde, hvor ordstørrelsen ser rigtig ud, og koden alligevel opfører sig forkert, eller hvor den starter og derefter fejler et lag længere nede. Læs interpreter-kolonnen som et hårdt krav og ikke som et hint, fordi kernen opløser den sti, før nogen af din kode kører. Emulering er en udrulningsbeslutning med sine egne konsekvenser for ydeevne og support, og den antydes aldrig af en processor, der reklamerer med en bredere ordstørrelse.
dpkg --print-architecture
ENOEXEC og ENOENT er forskellige fejl
Startfasen rapporterer en af to fejl, og de peger på forskellige problemer. At læse fejlværdien klassificerer fejlen, før du kører noget andet.
ENOEXEC betyder, at formatet ikke blev genkendt: forkert arkitektur, forkert klasse eller noget, der slet ikke er en eksekverbar fil. ENOENT på en ELF-fil betyder normalt, at interpreten mangler, selv om filen, du bad om, findes. Den samme ENOENT kan også betyde, at et scripts interpreter mangler, og derfor betyder et scripts første linje noget. Under alle omstændigheder nævner beskeden laget, og at behandle hver »ikke fundet« som en manglende konfiguration sender undersøgelsen i den forkerte retning. Citér fejlværdien i billetten, fordi den overlever genfortælling bedre end sætningen omkring den.
Hvad man ikke skal gøre, når den binære fil ikke starter
At tvinge en uforklaret binær fil gennem en shell-indpakning får den ikke til at køre. Kør ikke en afhængighedskontrol letsindigt på en fil, du ikke stoler på, fordi det i visse tilfælde kan udføre kode fra den binære fil. Tilføj ikke loader-symlinks, udskift ikke værtsbiblioteker, og hent ikke et gammelt arkiv fra et tredjepartsspejl for at komme forbi beskeden. Hver af disse udvider ændringsfladen uden at røre den uoverensstemmelse, som headeren allerede har nævnt.
Når du henvender dig til leverandøren, send værdier i stedet for en historie: OS-versionen, pakkens arkitektur, klasse- og maskinstrengene, den ønskede interpreter og den første fejl-linje. Det sæt løser supportspørgsmål hurtigere end et skærmbillede af en fejlende installatør. Gamle artefakter og huskede forumoutput er ikke en aktuel supportmatrix, og når først en native binær fil indlæses, er profil, godkendelse og routing stadig separat arbejde.