Halaman unduhan bilang 32-bit, berkas mendarat di Raspberry Pi, dan installer gagal dengan pesan yang tidak menyebut satu pun bagian masalah yang berguna. Dua berkas eksekutabel yang sama sekali berbeda sama-sama dihitung 32-bit dalam arti ELF, dan hanya satu di antaranya dapat berjalan di papan itu. Bidang kelas adalah satu fakta, bidang mesin fakta lain, dan nama berkas tidak memberi tahu Anda keduanya secara andal. Baca header sebelum mengganti pustaka atau mencoba cermin lain.

Kelas menyebut ukuran kata, mesin menyebut set instruksi

Referensi ELF Linux mendefinisikan bidang kelas dan bidang mesin pada header berkas, dan keduanya menjawab pertanyaan yang berbeda. Kelas menyebut apakah berkas memakai bentuk 32-bit atau 64-bit; mesin menyebut untuk set instruksi mana ia dibangun. Build x86 32-bit dan build ARM 32-bit sepakat pada yang pertama dan berbeda pada yang kedua. Begitulah label yang menjanjikan ukuran kata yang tepat tetap mengirim kode yang tidak dapat didekode prosesor. Nilai ketiga yang layak dibaca adalah interpreter yang diminta, yang disebut header program ketika biner menyatakan satu.

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

Perintah pertama mencetak header, yang kedua mencetak header program bila berkas memilikinya, dan yang ketiga mendaftar objek bersama yang akan dibutuhkan pemuat. Catat kelas, mesin, dan interpreter bersama-sama, karena ketiga nilai itu adalah seluruh pertanyaan kompatibilitas pada lapisan ini. Tidak satu pun dari ketiganya muncul di tombol unduh, karena itu berkas harus diperiksa, bukan dideskripsikan.

Interpreter mana yang dimintanya dari kernel

Berkas eksekutabel yang menyatakan interpreter meminta satu jalur pemuat tertentu kepada kernel. Ketika pemuat itu tidak ada, peluncuran gagal meskipun berkas yang Anda sebut berada tepat di sana. Di titik itulah orang memutuskan unduhan rusak, padahal jawaban sebenarnya adalah pemuat yang tidak disediakan distribusi.

Cocokkan pemuat dengan sistem yang benar-benar Anda jalankan: rilis OS, arsitektur ruang pengguna, dan paket yang menyediakan pemuat. Kernel 64-bit dapat menjalankan ruang pengguna 32-bit hanya bila ruang itu dan pemuatnya terpasang, jadi kemampuan prosesor bukan faktor penentu. Satu pemeriksaan singkat menyebut interpreter dalam satu baris, dan itu lebih cepat daripada tiket dukungan. Skrip shell gagal dengan cara lain lagi, karena interpreternya disebut di baris pertama dan bukan di header ELF, dan membaca baris itu tidak memakan biaya.

file --brief ./vendor-vpn

Cocokkan unduhan dengan arsitektur paket

Arsitektur paket distribusi mengodekan pembedaan yang sama dalam kosakata mereka sendiri, dan kosakata itulah yang dirujuk pernyataan dukungan vendor. Bandingkan nilai yang dilaporkan manajer paket Anda dengan nilai yang didokumentasikan vendor, alih-alih membandingkan label pemasaran dengan nama berkas. Pasangan yang menimbulkan masalah adalah amd64 versus arm64, dan armhf versus armel, karena setiap pasangan tampak dapat dipertukarkan dalam daftar unduhan. Nama berkas yang berakhiran x64 atau ia32 menggambarkan target build, bukan mesin yang menyimpannya.

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

Setiap baris adalah kasus ketika ukuran kata tampak benar dan kode tetap berperilaku salah, atau ketika ia mulai lalu gagal satu lapisan lebih rendah. Baca kolom interpreter sebagai persyaratan keras, bukan petunjuk, karena kernel menyelesaikan jalur itu sebelum bagian mana pun dari kode Anda berjalan. Emulasi adalah keputusan penerapan dengan konsekuensi kinerja dan dukungannya sendiri, dan tidak pernah tersirat oleh prosesor yang mengiklankan ukuran kata lebih lebar.

dpkg --print-architecture

ENOEXEC dan ENOENT adalah kegagalan yang berbeda

Tahap peluncuran melaporkan salah satu dari dua galat, dan keduanya menunjuk masalah yang berbeda. Membaca nilai galat mengklasifikasikan kegagalan sebelum Anda menjalankan apa pun yang lain.

ENOEXEC berarti formatnya tidak dikenali: arsitektur salah, kelas salah, atau sesuatu yang sama sekali bukan berkas eksekutabel. ENOENT pada berkas ELF biasanya berarti interpreter hilang, meskipun berkas yang Anda minta ada. ENOENT yang sama juga dapat berarti interpreter sebuah skrip tidak ada, karena itu baris pertama skrip penting. Bagaimanapun pesan menyebut lapisannya, dan memperlakukan setiap „tidak ditemukan“ sebagai konfigurasi yang hilang mengarahkan penyelidikan ke arah yang salah. Kutip nilai galat di tiket, karena ia bertahan lebih baik saat diceritakan ulang daripada kalimat di sekitarnya.

Apa yang tidak boleh dilakukan saat biner tidak mau jalan

Memaksa biner yang tidak dijelaskan lewat pembungkus shell tidak membuatnya berjalan. Jangan menjalankan pemeriksa dependensi dengan sembarangan pada berkas yang tidak Anda percayai, karena menjalankannya dapat mengeksekusi kode dari biner dalam keadaan tertentu. Jangan menambahkan symlink pemuat, menukar pustaka host, atau mengambil arsip lama dari cermin pihak ketiga untuk melewati pesan. Masing-masing memperluas permukaan perubahan tanpa menyentuh ketidakcocokan yang sudah disebut header.

Saat menghubungi vendor, kirim nilai, bukan cerita: rilis OS, arsitektur paket, string kelas dan mesin, interpreter yang diminta, dan baris galat pertama. Himpunan itu menyelesaikan pertanyaan dukungan lebih cepat daripada tangkapan layar installer yang gagal. Artefak lama dan keluaran forum yang diingat bukanlah matriks dukungan terkini, dan begitu biner native dimuat, profil, autentikasi, dan perutean tetap menjadi pekerjaan terpisah.

Artikel terkait