VPN इंस्टॉलर कहता है 32-बिट: इसके बजाय ELF हेडर जाँचें
शब्द का आकार अनुदेश समुच्चय की पहचान नहीं करता। क्लास, मशीन और इंटरप्रेटर पढ़ने और फिर होस्ट से मेल खाता बिल्ड माँगने की प्रक्रिया।
एक डाउनलोड पेज 32-बिट कहता है, फ़ाइल Raspberry Pi पर पहुँचती है, और इंस्टॉलर ऐसे संदेश के साथ विफल हो जाता है जो समस्या के किसी उपयोगी हिस्से का नाम नहीं लेता। दो पूरी तरह अलग निष्पादन योग्य फ़ाइलें ELF अर्थ में दोनों 32-बिट गिनी जाती हैं, और उनमें से केवल एक ही उस बोर्ड पर चल सकती है। क्लास फ़ील्ड एक तथ्य है, मशीन फ़ील्ड दूसरा, और फ़ाइल का नाम आपको दोनों में से कोई भी भरोसे से नहीं बताता। लाइब्रेरी बदलने या दूसरा मिरर आज़माने से पहले हेडर पढ़ें।
क्लास शब्द का आकार कहती है, मशीन अनुदेश समुच्चय
Linux ELF संदर्भ फ़ाइल हेडर में क्लास फ़ील्ड और मशीन फ़ील्ड परिभाषित करता है, और दोनों अलग-अलग सवालों के जवाब देते हैं। क्लास बताती है कि फ़ाइल 32-बिट या 64-बिट रूप इस्तेमाल करती है; मशीन बताती है कि यह किस अनुदेश समुच्चय के लिए बनाई गई। 32-बिट x86 बिल्ड और 32-बिट ARM बिल्ड पहले पर सहमत और दूसरे पर अलग हैं। इस तरह सही शब्द आकार का वादा करने वाला लेबल भी ऐसा कोड देता है जिसे प्रोसेसर डिकोड नहीं कर सकता। पढ़ने लायक तीसरा मान माँगा गया इंटरप्रेटर है, जिसका नाम प्रोग्राम हेडर तब लेते हैं जब बाइनरी एक घोषित करती है।
readelf -h -- ./vendor-vpn
readelf -l -- ./vendor-vpn
readelf -d -- ./vendor-vpn | grep NEEDED
पहला कमांड हेडर छापता है, दूसरा फ़ाइल में होने पर प्रोग्राम हेडर छापता है, और तीसरा उन साझा ऑब्जेक्ट की सूची देता है जिनकी लोडर को ज़रूरत होगी। क्लास, मशीन और इंटरप्रेटर साथ लिख लें, क्योंकि ये तीन मान इस परत पर पूरा संगतता प्रश्न हैं। तीनों में से कोई डाउनलोड बटन पर नहीं दिखता, इसलिए फ़ाइल का वर्णन नहीं, निरीक्षण करना पड़ता है।
यह कर्नेल से कौन-सा इंटरप्रेटर माँगता है
इंटरप्रेटर घोषित करने वाली निष्पादन योग्य फ़ाइल कर्नेल से एक विशेष लोडर पथ माँगती है। जब वह लोडर नहीं होता, तो आपकी बताई फ़ाइल ठीक वहीं होने पर भी शुरू होना विफल हो जाता है। यही वह बिंदु है जहाँ लोग तय करते हैं कि डाउनलोड खराब है, जबकि वास्तविक उत्तर ऐसा लोडर है जो वितरण नहीं देता।
लोडर को उस सिस्टम से मिलाएँ जिसे आप वास्तव में चलाते हैं: OS संस्करण, उपयोगकर्ता स्थान की आर्किटेक्चर और वह पैकेज जो लोडर देता है। 64-बिट कर्नेल 32-बिट उपयोगकर्ता स्थान तभी चला सकता है जब वह स्थान और उसका लोडर स्थापित हों, इसलिए प्रोसेसर की क्षमताएँ निर्णायक कारक नहीं हैं। एक छोटी जाँच इंटरप्रेटर का नाम एक पंक्ति में बताती है, और यह सहायता टिकट से कम समय लेती है। शेल स्क्रिप्ट फिर अलग तरह से विफल होती है, क्योंकि उसका इंटरप्रेटर पहली पंक्ति में नामित होता है, ELF हेडर में नहीं, और उस पंक्ति को पढ़ने में कुछ नहीं लगता।
file --brief ./vendor-vpn
डाउनलोड को पैकेज आर्किटेक्चर से मिलाएँ
वितरण पैकेज आर्किटेक्चर उसी भेद को अपनी शब्दावली में कूटबद्ध करते हैं, और विक्रेता का सहायता वक्तव्य उसी शब्दावली का संदर्भ देता है। आपका पैकेज प्रबंधक जो मान बताता है उसकी तुलना विक्रेता के दस्तावेज़ी मान से करें, मार्केटिंग लेबल की फ़ाइल नाम से तुलना करने के बजाय। परेशानी पैदा करने वाले जोड़े amd64 बनाम arm64, और armhf बनाम armel हैं, क्योंकि हर जोड़ा डाउनलोड सूची में बदले जाने योग्य दिखता है। x64 या ia32 पर समाप्त होने वाला फ़ाइल नाम बिल्ड लक्ष्य बताता है, उसे रखने वाली मशीन नहीं।
| 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 का अर्थ है प्रारूप पहचाना नहीं गया: गलत आर्किटेक्चर, गलत क्लास, या ऐसा कुछ जो बिल्कुल निष्पादन योग्य नहीं है। ELF फ़ाइल पर ENOENT का अर्थ आमतौर पर यह है कि इंटरप्रेटर गायब है, हालाँकि आपकी माँगी फ़ाइल मौजूद है। वही ENOENT यह भी बता सकता है कि स्क्रिप्ट का इंटरप्रेटर गायब है, इसलिए स्क्रिप्ट की पहली पंक्ति मायने रखती है। किसी भी तरह संदेश परत का नाम लेता है, और हर “नहीं मिला” को गुम कॉन्फ़िगरेशन मानना जाँच को गलत दिशा में भेजता है। टिकट में त्रुटि का मान उद्धृत करें, क्योंकि वह आसपास के वाक्य से बेहतर दोबारा कहने में टिकता है।
बाइनरी शुरू न हो तो क्या न करें
अस्पष्ट बाइनरी को शेल आवरण से ज़बरदस्ती निकालना उसे चलाता नहीं। जिस फ़ाइल पर भरोसा नहीं है उस पर निर्भरता जाँच लापरवाही से न चलाएँ, क्योंकि उसे चलाना कुछ परिस्थितियों में बाइनरी से कोड चला सकता है। लोडर सिमलिंक न जोड़ें, होस्ट लाइब्रेरी न बदलें और संदेश से बचने के लिए तीसरे पक्ष के मिरर से पुराना संग्रह न लाएँ। इनमें से हर एक बदलाव का दायरा बढ़ाता है बिना उस असंगति को छुए जिसका नाम हेडर पहले ही ले चुका है।
जब विक्रेता से संपर्क करें, तो कहानी नहीं मान भेजें: OS संस्करण, पैकेज आर्किटेक्चर, क्लास और मशीन स्ट्रिंग, माँगा गया इंटरप्रेटर और पहली त्रुटि पंक्ति। वह समुच्चय सहायता प्रश्नों को विफल इंस्टॉलर के स्क्रीनशॉट से तेज़ हल करता है। पुराने आर्टिफ़ैक्ट और याद रखे गए फ़ोरम आउटपुट वर्तमान सहायता मैट्रिक्स नहीं हैं, और नेटिव बाइनरी लोड होने के बाद प्रोफ़ाइल, प्रमाणीकरण और रूटिंग अलग काम रहते हैं।