Installer VPN bilang 32-bit: periksa header ELF saja
Ukuran kata tidak mengidentifikasi set instruksi. Prosedur membaca kelas, mesin, dan interpreter, lalu meminta build yang cocok dengan host.
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 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 |
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.