Ο εγκαταστάτης VPN λέει 32-bit: ελέγξτε την κεφαλίδα ELF
Το μέγεθος λέξης δεν προσδιορίζει το σύνολο εντολών. Διαδικασία για ανάγνωση κλάσης, μηχανής και διερμηνέα και έπειτα για αίτημα build που ταιριάζει στον host.
Μια σελίδα λήψης λέει 32-bit, το αρχείο προσγειώνεται σε ένα Raspberry Pi και ο εγκαταστάτης αποτυγχάνει με μήνυμα που δεν ονομάζει κανένα χρήσιμο μέρος του προβλήματος. Δύο εντελώς διαφορετικά εκτελέσιμα αρχεία μετράνε και τα δύο ως 32-bit με την έννοια του ELF, και μόνο ένα από αυτά μπορεί να τρέξει σε εκείνη την πλακέτα. Το πεδίο κλάσης είναι ένα γεγονός, το πεδίο μηχανής είναι άλλο, και ένα όνομα αρχείου δεν σας λέει αξιόπιστα κανένα από τα δύο. Διαβάστε την κεφαλίδα πριν αλλάξετε βιβλιοθήκη ή δοκιμάσετε άλλο mirror.
Η κλάση λέει μέγεθος λέξης, η μηχανή λέει σύνολο εντολών
Η αναφορά ELF του Linux ορίζει πεδίο κλάσης και πεδίο μηχανής στην κεφαλίδα του αρχείου, και τα δύο απαντούν σε διαφορετικά ερωτήματα. Η κλάση λέει αν το αρχείο χρησιμοποιεί μορφή 32-bit ή 64-bit· η μηχανή λέει για ποιο σύνολο εντολών χτίστηκε. Ένα build x86 32-bit και ένα build ARM 32-bit συμφωνούν στο πρώτο και διαφωνούν στο δεύτερο. Έτσι μια ετικέτα που υπόσχεται το σωστό μέγεθος λέξης παραδίδει κώδικα που ο επεξεργαστής δεν μπορεί να αποκωδικοποιήσει. Η τρίτη τιμή που αξίζει ανάγνωση είναι ο ζητούμενος διερμηνέας, τον οποίο ονομάζουν οι κεφαλίδες προγράμματος όταν το δυαδικό αρχείο δηλώνει έναν.
readelf -h -- ./vendor-vpn
readelf -l -- ./vendor-vpn
readelf -d -- ./vendor-vpn | grep NEEDED
Η πρώτη εντολή εκτυπώνει την κεφαλίδα, η δεύτερη εκτυπώνει τις κεφαλίδες προγράμματος όταν το αρχείο έχει, και η τρίτη απαριθμεί τα κοινόχρηστα αντικείμενα που θα χρειαστεί ο φορτωτής. Καταγράψτε κλάση, μηχανή και διερμηνέα μαζί, γιατί αυτές οι τρεις τιμές είναι ολόκληρο το ζήτημα συμβατότητας σε αυτό το επίπεδο. Καμία από τις τρεις δεν εμφανίζεται σε κουμπί λήψης, γι’ αυτό το αρχείο πρέπει να επιθεωρηθεί και όχι να περιγραφεί.
Ποιον διερμηνέα ζητά από τον πυρήνα
Ένα εκτελέσιμο αρχείο που δηλώνει διερμηνέα ζητά από τον πυρήνα μια συγκεκριμένη διαδρομή φορτωτή. Όταν αυτός ο φορτωτής λείπει, η εκκίνηση αποτυγχάνει παρόλο που το αρχείο που ονομάσατε βρίσκεται ακριβώς εκεί. Αυτό είναι το σημείο όπου οι άνθρωποι αποφασίζουν ότι η λήψη είναι κατεστραμμένη, ενώ η πραγματική απάντηση είναι ένας φορτωτής που η διανομή δεν παρέχει.
Ταιριάξτε τον φορτωτή με το σύστημα που πραγματικά εκτελείτε: την έκδοση του λειτουργικού, την αρχιτεκτονική του χώρου χρήστη και το πακέτο που παρέχει τον φορτωτή. Ένας πυρήνας 64-bit μπορεί να εκτελέσει χώρο χρήστη 32-bit μόνο όταν αυτός ο χώρος και ο φορτωτής του είναι εγκατεστημένα, άρα οι δυνατότητες του επεξεργαστή δεν είναι ο καθοριστικός παράγοντας. Ένας σύντομος έλεγχος ονομάζει τον διερμηνέα σε μία γραμμή, και διαρκεί λιγότερο από ένα δελτίο υποστήριξης. Ένα σενάριο κελύφους αποτυγχάνει πάλι διαφορετικά, γιατί ο διερμηνέας του ονομάζεται στην πρώτη γραμμή και όχι σε κεφαλίδα ELF, και η ανάγνωση αυτής της γραμμής δεν κοστίζει τίποτα.
file --brief ./vendor-vpn
Ταιριάξτε τη λήψη με την αρχιτεκτονική του πακέτου
Οι αρχιτεκτονικές πακέτων των διανομών κωδικοποιούν την ίδια διάκριση στο δικό τους λεξιλόγιο, και σε αυτό το λεξιλόγιο αναφέρεται η δήλωση υποστήριξης ενός προμηθευτή. Συγκρίνετε την τιμή που αναφέρει ο διαχειριστής πακέτων σας με την τιμή που τεκμηριώνει ο προμηθευτής, αντί να συγκρίνετε μια ετικέτα μάρκετινγκ με ένα όνομα αρχείου. Τα ζεύγη που δημιουργούν πρόβλημα είναι amd64 έναντι arm64 και armhf έναντι armel, γιατί κάθε ζεύγος φαίνεται εναλλάξιμο σε μια λίστα λήψης. Ένα όνομα αρχείου που τελειώνει σε x64 ή ia32 περιγράφει στόχο build, όχι τη μηχανή που το κρατά.
| 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 |
Κάθε γραμμή είναι μια περίπτωση όπου το μέγεθος λέξης φαίνεται σωστό και ο κώδικας εξακολουθεί να συμπεριφέρεται λάθος, ή όπου ξεκινά και μετά αποτυγχάνει ένα επίπεδο πιο κάτω. Διαβάστε τη στήλη διερμηνέα ως σκληρή απαίτηση και όχι ως υπόδειξη, γιατί ο πυρήνας επιλύει αυτή τη διαδρομή πριν εκτελεστεί οποιοσδήποτε κώδικάς σας. Η εξομοίωση είναι απόφαση ανάπτυξης με δικές της συνέπειες στην απόδοση και την υποστήριξη, και ποτέ δεν υπονοείται από επεξεργαστή που διαφημίζει ευρύτερο μέγεθος λέξης.
dpkg --print-architecture
Τα ENOEXEC και ENOENT είναι διαφορετικές αποτυχίες
Το στάδιο εκκίνησης αναφέρει ένα από δύο σφάλματα, και δείχνουν σε διαφορετικά προβλήματα. Η ανάγνωση της τιμής σφάλματος ταξινομεί την αποτυχία πριν εκτελέσετε οτιδήποτε άλλο.
Το ENOEXEC σημαίνει ότι η μορφή δεν αναγνωρίστηκε: λάθος αρχιτεκτονική, λάθος κλάση ή κάτι που δεν είναι καθόλου εκτελέσιμο αρχείο. Το ENOENT σε αρχείο ELF συνήθως σημαίνει ότι λείπει ο διερμηνέας, παρόλο που το αρχείο που ζητήσατε υπάρχει. Το ίδιο ENOENT μπορεί επίσης να σημαίνει ότι λείπει ο διερμηνέας ενός σεναρίου, γι’ αυτό έχει σημασία η πρώτη γραμμή ενός σεναρίου. Σε κάθε περίπτωση το μήνυμα ονομάζει το επίπεδο, και το να αντιμετωπίζετε κάθε «δεν βρέθηκε» ως λείπουσα ρύθμιση στέλνει την έρευνα σε λάθος κατεύθυνση. Παραθέστε την τιμή σφάλματος στο δελτίο, γιατί αντέχει στην αναδιήγηση καλύτερα από την πρόταση γύρω της.
Τι να μην κάνετε όταν το δυαδικό αρχείο δεν ξεκινά
Το να σπρώξετε ένα ανεξήγητο δυαδικό αρχείο μέσα από περιτύλιγμα κελύφους δεν το κάνει να τρέξει. Μην εκτελείτε έλεγχο εξαρτήσεων απερίσκεπτα σε αρχείο που δεν εμπιστεύεστε, γιατί η εκτέλεσή του μπορεί σε ορισμένες περιπτώσεις να εκτελέσει κώδικα από το δυαδικό αρχείο. Μην προσθέτετε συμβολικούς δεσμούς φορτωτή, μην ανταλλάσσετε βιβλιοθήκες του host και μην κατεβάζετε παλιό αρχείο από mirror τρίτου για να ξεπεράσετε το μήνυμα. Κάθε ένα από αυτά διευρύνει την επιφάνεια αλλαγής χωρίς να αγγίζει την ασυμφωνία που η κεφαλίδα έχει ήδη ονομάσει.
Όταν απευθύνεστε στον προμηθευτή, στείλτε τιμές και όχι ιστορία: την έκδοση του λειτουργικού, την αρχιτεκτονική του πακέτου, τις συμβολοσειρές κλάσης και μηχανής, τον ζητούμενο διερμηνέα και την πρώτη γραμμή σφάλματος. Αυτό το σύνολο λύνει ερωτήματα υποστήριξης γρηγορότερα από ένα στιγμιότυπο οθόνης ενός εγκαταστάτη που αποτυγχάνει. Τα παλιά artifacts και οι θυμημένες έξοδοι φόρουμ δεν είναι τρέχων πίνακας υποστήριξης, και μόλις φορτωθεί ένα εγγενές δυαδικό αρχείο, το προφίλ, η ταυτοποίηση και η δρομολόγηση παραμένουν ξεχωριστή εργασία.