Страница за изтегляне казва 32-бит, файлът се озовава на Raspberry Pi и инсталаторът се проваля със съобщение, което не назовава нито една полезна част от проблема. Два напълно различни изпълними файла и двата се броят за 32-битови в смисъла на ELF и само един от тях може да работи на тази платка. Полето за клас е един факт, полето за машина е друг, а името на файла надеждно не ви казва нито едното. Прочетете заглавката, преди да смените библиотека или да опитате друго огледало.

Класът казва размера на думата, машината казва набора инструкции

Справочникът за ELF в Linux дефинира поле за клас и поле за машина в заглавката на файла и двете отговарят на различни въпроси. Класът казва дали файлът използва 32-битова или 64-битова форма; машината казва за кой набор инструкции е построен. 32-битова сборка за x86 и 32-битова сборка за ARM съвпадат по първото и се разминават по второто. Ето как етикет, който обещава правилния размер на думата, все пак доставя код, който процесорът не може да декодира. Третата стойност, която си струва да се прочете, е исканият интерпретатор, който заглавките на програмата назовават, когато двоичният файл обяви такъв.

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

Първата команда отпечатва заглавката, втората отпечатва заглавките на програмата, когато файлът има такива, а третата изброява споделените обекти, от които зареждащият ще се нуждае. Записвайте класа, машината и интерпретатора заедно, защото тези три стойности са целият въпрос за съвместимост на това ниво. Нито една от трите не се появява на бутон за изтегляне и затова файлът трябва да се инспектира, а не да се описва.

Какъв интерпретатор иска от ядрото

Изпълним файл, който обявява интерпретатор, иска от ядрото един конкретен път за зареждащ. Когато този зареждащ липсва, стартирането се проваля, въпреки че файлът, който сте посочили, стои точно там. Това е моментът, в който хората решават, че изтеглянето е повредено, докато действителният отговор е зареждащ, който дистрибуцията не доставя.

Съпоставете зареждащия със системата, която наистина използвате: изданието на ОС, архитектурата на потребителското пространство и пакета, който предоставя зареждащия. 64-битово ядро може да изпълнява 32-битово потребителско пространство само когато то и неговият зареждащ са инсталирани, така че възможностите на процесора не са решаващият фактор. Една кратка проверка назовава интерпретатора на един ред и отнема по-малко време от билет за поддръжка. Shell скриптът се проваля по още друг начин, защото неговият интерпретатор е назован на първия ред, а не в заглавка на ELF и прочитането на този ред не струва нищо.

file --brief ./vendor-vpn

Съпоставете изтеглянето с архитектурата на пакета

Архитектурите на пакетите на дистрибуциите кодират същото разграничение в своя речник и именно този речник има предвид изявлението за поддръжка на доставчика. Сравнете стойността, която вашият мениджър на пакети съобщава, със стойността, която доставчикът документира, вместо да сравнявате маркетингов етикет с име на файл. Двойките, които създават проблеми, са amd64 срещу arm64 и armhf срещу armel, защото всяка двойка изглежда взаимозаменяема в списък за изтегляне. Име на файл, завършващо на x64 или ia32, описва цел на сборката, а не машината, която го държи.

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

Всеки ред е случай, в който размерът на думата изглежда правилен, а кодът пак се държи зле, или който стартира и после се проваля едно ниво по-надолу. Четете колоната за интерпретатор като твърдо изискване, а не като подсказка, защото ядрото разрешава този път, преди да се изпълни какъвто и да е ваш код. Емулацията е решение за внедряване със свои последствия за производителността и поддръжката и никога не се подразбира от процесор, който рекламира по-широк размер на думата.

dpkg --print-architecture

ENOEXEC и ENOENT са различни откази

Етапът на стартиране съобщава една от две грешки и те сочат към различни проблеми. Прочитането на стойността на грешката класифицира отказа, преди да стартирате нещо друго.

ENOEXEC означава, че форматът не е разпознат: грешна архитектура, грешен клас или нещо, което изобщо не е изпълним файл. ENOENT за файл ELF обикновено означава, че интерпретаторът липсва, въпреки че файлът, който сте поискали, съществува. Същият ENOENT може да означава и че интерпретаторът на скрипт липсва и затова първият ред на скрипта има значение. Във всеки случай съобщението назовава нивото и третирането на всяко „не е намерено“ като липсваща конфигурация насочва разследването в грешна посока. Цитирайте стойността на грешката в билета, защото тя издържа на преразказ по-добре от изречението около нея.

Какво да не правите, когато двоичният файл не стартира

Принуждаването на необяснен двоичен файл през обвивка на shell не го кара да работи. Не стартирайте проверка на зависимости небрежно върху файл, на който не се доверявате, защото стартирането ѝ може при някои обстоятелства да изпълни код от двоичния файл. Не добавяйте символни връзки за зареждащия, не подменяйте библиотеки на хоста и не изтегляйте стар архив от огледало на трета страна, за да прескочите съобщението. Всяко от тези разширява обхвата на промяната, без да докосва несъответствието, което заглавката вече е назовала.

Когато се обръщате към доставчика, изпращайте стойности, а не разказ: изданието на ОС, архитектурата на пакета, низовете за клас и машина, искания интерпретатор и първия ред с грешка. Този набор решава въпросите за поддръжка по-бързо от екранна снимка на провалящ се инсталатор. Старите артефакти и запомнените изходи от форуми не са актуална матрица за поддръжка, а след като нативен двоичен файл се зареди, профилът, удостоверяването и маршрутизацията остават отделна работа.

Подобни статии