En nedladdningssida säger 32-bit, filen landar på en Raspberry Pi och installatören misslyckas med ett meddelande som inte namnger någon användbar del av problemet. Två helt olika körbara filer räknas båda som 32-bit i ELF-bemärkelse, och bara en av dem kan köras på det kortet. Klassfältet är ett faktum, maskinfältet ett annat, och ett filnamn berättar pålitligt inget av dem. Läs huvudet innan du byter ett bibliotek eller provar en annan spegel.

Klassen säger ordstorlek, maskinen säger instruktionsuppsättning

Linux ELF-referensen definierar ett klassfält och ett maskinfält i filhuvudet, och de två svarar på olika frågor. Klassen säger om filen använder 32-bit- eller 64-bit-formen; maskinen säger vilken instruktionsuppsättning den byggdes för. En 32-bit x86-build och en 32-bit ARM-build är ense om det första och oense om det andra. Så levererar en etikett som lovar rätt ordstorlek ändå kod som processorn inte kan avkoda. Det tredje värdet som är värt att läsa är den begärda tolken, som programhuvudena namnger när den binära filen deklarerar en.

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

Det första kommandot skriver ut huvudet, det andra skriver ut programhuvuden när filen har några, och det tredje listar de delade objekten som laddaren kommer att behöva. Anteckna klass, maskin och tolk tillsammans, eftersom dessa tre värden är hela kompatibilitetsfrågan på den här nivån. Ingen av de tre står på en nedladdningsknapp, därför måste filen undersökas i stället för beskrivas.

Vilken tolk den ber kärnan om

En körbar fil som deklarerar en tolk ber kärnan om en specifik laddarsökväg. När den laddaren saknas misslyckas starten även om filen du nämnde ligger precis där. Det är punkten där folk drar slutsatsen att nedladdningen är skadad, medan det faktiska svaret är en laddare som distributionen inte levererar.

Anpassa laddaren till systemet du faktiskt kör: OS-versionen, användarrymdens arkitektur och paketet som tillhandahåller laddaren. En 64-bitars kärna kan bara köra en 32-bitars användarrymd när den rymden och dess laddare är installerade, så processorns förmågor är inte den avgörande faktorn. En kort kontroll namnger tolken på en enda rad, och den tar mindre tid än ett supportärende. Ett skalskript misslyckas igen på ett annat sätt, eftersom dess tolk namnges på första raden och inte i ett ELF-huvud, och att läsa den raden kostar ingenting.

file --brief ./vendor-vpn

Anpassa nedladdningen till paketarkitekturen

Distributionernas paketarkitekturer kodar samma åtskillnad i sin egen vokabulär, och det är den vokabulären som en leverantörs supportuttalande hänvisar till. Jämför värdet som din pakethanterare rapporterar med värdet som leverantören dokumenterar, i stället för att jämföra en marknadsföringsetikett med ett filnamn. Paren som ställer till problem är amd64 mot arm64 och armhf mot armel, eftersom varje par ser utbytbart ut i en nedladdningslista. Ett filnamn som slutar på x64 eller ia32 beskriver ett byggmål, inte maskinen som håller 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

Varje rad är ett fall där ordstorleken ser rätt ut och koden ändå beter sig fel, eller där den startar och sedan misslyckas ett lager längre ned. Läs tolkkolumnen som ett hårt krav och inte som en antydan, eftersom kärnan löser den sökvägen innan någon del av din kod körs. Emulering är ett driftsättningsbeslut med egna konsekvenser för prestanda och support, och det antyds aldrig av en processor som annonserar en bredare ordstorlek.

dpkg --print-architecture

ENOEXEC och ENOENT är olika fel

Startfasen rapporterar ett av två fel, och de pekar på olika problem. Att läsa felvärdet klassificerar misslyckandet innan du kör något annat.

ENOEXEC betyder att formatet inte kändes igen: fel arkitektur, fel klass eller något som inte alls är en körbar fil. ENOENT på en ELF-fil betyder vanligtvis att tolken saknas, trots att filen du bad om finns. Samma ENOENT kan också betyda att ett skripts tolk saknas, och därför spelar ett skripts första rad roll. Hur det än är namnger meddelandet lagret, och att behandla varje »hittades inte« som en saknad konfiguration skickar undersökningen i fel riktning. Citera felvärdet i ärendet, eftersom det överlever återberättande bättre än meningen runt det.

Vad du inte bör göra när den binära filen inte startar

Att tvinga en oförklarad binär fil genom ett skalomslag får den inte att köras. Kör inte en beroendekontroll lättvindigt på en fil du inte litar på, eftersom körningen i vissa fall kan utföra kod från den binära filen. Lägg inte till laddarsymlinkar, byt inte ut värdbibliotek och hämta inte ett gammalt arkiv från en tredjepartsspegel för att komma förbi meddelandet. Var och en av dessa utökar ändringsytan utan att röra den bristande överensstämmelse som huvudet redan har namngett.

När du vänder dig till leverantören, skicka värden och inte en historia: OS-versionen, paketarkitekturen, klass- och maskinsträngarna, den begärda tolken och den första felraden. Den uppsättningen löser supportfrågor snabbare än en skärmbild av en installatör som misslyckas. Gamla artefakter och ihågkomna forumutdata är inte en aktuell supportmatris, och när en inbyggd binärfil har laddats förblir profil, autentisering och routing separat arbete.

Relaterade artiklar