VPN-Installer meldet 32-Bit: Prüfen Sie stattdessen den ELF-Header
Die Wortbreite benennt nicht den Befehlssatz. Anleitung zum Lesen von Klasse, Maschine und Interpreter und dann zum Anfordern eines Builds, der zum Host passt.
Eine Downloadseite sagt 32-Bit, die Datei landet auf einem Raspberry Pi, und der Installer scheitert mit einer Meldung, die keinen brauchbaren Teil des Problems benennt. Zwei völlig verschiedene ausführbare Dateien zählen im ELF-Sinn beide als 32-Bit, und nur eine davon kann auf dieser Platine laufen. Das Klassenfeld ist ein Fakt, das Maschinenfeld ein anderer, und ein Dateiname sagt Ihnen verlässlich keines von beiden. Lesen Sie den Header, bevor Sie eine Bibliothek ändern oder einen anderen Spiegel ausprobieren.
Die Klasse nennt die Wortbreite, die Maschine den Befehlssatz
Die Linux-ELF-Referenz definiert ein Klassenfeld und ein Maschinenfeld im Dateiheader, und die beiden beantworten verschiedene Fragen. Die Klasse sagt, ob die Datei die 32-Bit- oder die 64-Bit-Form verwendet; die Maschine sagt, für welchen Befehlssatz sie gebaut wurde. Ein 32-Bit-x86-Build und ein 32-Bit-ARM-Build stimmen beim ersten überein und unterscheiden sich beim zweiten. So liefert ein Etikett, das die richtige Wortbreite verspricht, trotzdem Code, den der Prozessor nicht dekodieren kann. Der dritte lesenswerte Wert ist der angeforderte Interpreter, den die Programmheader nennen, wenn die Binärdatei einen deklariert.
readelf -h -- ./vendor-vpn
readelf -l -- ./vendor-vpn
readelf -d -- ./vendor-vpn | grep NEEDED
Der erste Befehl gibt den Header aus, der zweite die Programmheader, sofern die Datei welche hat, und der dritte listet die Shared Objects auf, die der Loader brauchen wird. Notieren Sie Klasse, Maschine und Interpreter zusammen, denn diese drei Werte sind die ganze Kompatibilitätsfrage auf dieser Ebene. Keiner der drei steht auf einer Download-Schaltfläche, deshalb muss die Datei untersucht statt beschrieben werden.
Welchen Interpreter sie vom Kernel verlangt
Eine ausführbare Datei, die einen Interpreter deklariert, verlangt vom Kernel einen bestimmten Loader-Pfad. Fehlt dieser Loader, scheitert der Start, obwohl die Datei, die Sie genannt haben, direkt dort liegt. Das ist der Punkt, an dem Leute den Download für beschädigt halten, während die eigentliche Antwort ein Loader ist, den die Distribution nicht mitliefert.
Passen Sie den Loader an das System an, das Sie tatsächlich betreiben: die OS-Version, die Architektur des Userspace und das Paket, das den Loader bereitstellt. Ein 64-Bit-Kernel kann einen 32-Bit-Userspace nur ausführen, wenn dieser Userspace und sein Loader installiert sind, also sind die Fähigkeiten des Prozessors nicht der entscheidende Faktor. Eine kurze Prüfung nennt den Interpreter in einer Zeile, und sie dauert weniger als ein Support-Ticket. Ein Shell-Skript scheitert wieder anders, weil sein Interpreter in der ersten Zeile genannt wird und nicht in einem ELF-Header, und diese Zeile zu lesen kostet nichts.
file --brief ./vendor-vpn
Passen Sie den Download an die Paketarchitektur an
Die Paketarchitekturen der Distributionen kodieren dieselbe Unterscheidung in ihrer eigenen Sprache, und auf diese Sprache bezieht sich die Support-Aussage eines Herstellers. Vergleichen Sie den Wert, den Ihr Paketmanager meldet, mit dem Wert, den der Hersteller dokumentiert, statt ein Marketing-Etikett mit einem Dateinamen zu vergleichen. Die Paare, die Ärger machen, sind amd64 gegen arm64 und armhf gegen armel, weil jedes Paar in einer Downloadliste austauschbar aussieht. Ein Dateiname, der auf x64 oder ia32 endet, beschreibt ein Build-Ziel, nicht die Maschine, die ihn hält.
| 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 |
Jede Zeile ist ein Fall, in dem die Wortbreite richtig aussieht und der Code sich trotzdem falsch verhält, oder in dem er startet und dann eine Ebene tiefer scheitert. Lesen Sie die Interpreter-Spalte als harte Anforderung und nicht als Hinweis, denn der Kernel löst diesen Pfad auf, bevor irgendein Code von Ihnen läuft. Emulation ist eine Bereitstellungsentscheidung mit eigenen Folgen für Leistung und Support, und sie wird nie von einem Prozessor impliziert, der mit einer breiteren Wortbreite wirbt.
dpkg --print-architecture
ENOEXEC und ENOENT sind verschiedene Fehler
Die Startphase meldet einen von zwei Fehlern, und sie deuten auf verschiedene Probleme hin. Den Fehlerwert zu lesen klassifiziert den Fehlschlag, bevor Sie irgendetwas anderes ausführen.
ENOEXEC bedeutet, dass das Format nicht erkannt wurde: falsche Architektur, falsche Klasse oder etwas, das überhaupt keine ausführbare Datei ist. ENOENT bei einer ELF-Datei bedeutet meist, dass der Interpreter fehlt, obwohl die Datei, die Sie angefordert haben, existiert. Dasselbe ENOENT kann auch bedeuten, dass der Interpreter eines Skripts fehlt, deshalb zählt die erste Zeile eines Skripts. So oder so benennt die Meldung die Ebene, und jeden Nicht-Gefunden-Fall als fehlende Konfiguration zu behandeln, schickt die Untersuchung in die falsche Richtung. Zitieren Sie den Fehlerwert im Ticket, denn er übersteht das Nacherzählen besser als der Satz um ihn herum.
Was man nicht tun sollte, wenn die Binärdatei nicht startet
Eine unerklärte Binärdatei durch einen Shell-Wrapper zu zwingen, bringt sie nicht zum Laufen. Führen Sie eine Abhängigkeitsprüfung nicht leichtfertig an einer Datei aus, der Sie nicht trauen, denn ihr Lauf kann unter Umständen Code aus der Binärdatei ausführen. Fügen Sie keine Loader-Symlinks hinzu, tauschen Sie keine Host-Bibliotheken aus und holen Sie kein altes Archiv von einem Drittspiegel, um die Meldung zu umgehen. Jedes davon erweitert die Änderungsfläche, ohne die Nichtübereinstimmung zu berühren, die der Header bereits genannt hat.
Wenn Sie den Hersteller ansprechen, senden Sie Werte statt einer Geschichte: die OS-Version, die Paketarchitektur, die Klasse- und Maschinen-Zeichenketten, den angeforderten Interpreter und die erste Fehlerzeile. Dieser Satz löst Support-Fragen schneller als ein Screenshot eines scheiternden Installers. Alte Artefakte und erinnerte Forumsausgaben sind keine aktuelle Support-Matrix, und sobald eine native Binärdatei lädt, bleiben Profil, Authentifizierung und Routing getrennte Arbeit.