مثبّت VPN يقول 32 بت: افحص ترويسة ELF بدلًا من ذلك
حجم الكلمة لا يحدّد مجموعة التعليمات. دليل إجرائي لقراءة الصنف والآلة والمفسّر، ثم طلب بناء يطابق المضيف.
تقول صفحة تنزيل إن الملف 32 بت، ثم يهبط الملف على Raspberry Pi، ويفشل المثبّت برسالة لا تسمّي أي جزء مفيد من المشكلة. يُعدّ ملفان تنفيذيان مختلفان تمامًا كلاهما 32 بت بمعنى ELF، وواحد فقط منهما يستطيع العمل على تلك اللوحة. حقل الصنف حقيقة واحدة، وحقل الآلة حقيقة أخرى، واسم الملف لا يخبرك بأي منهما بثقة. اقرأ الترويسة قبل تغيير مكتبة أو تجربة مرآة أخرى.
الصنف يقول حجم الكلمة، والآلة تقول مجموعة التعليمات
يحدّد مرجع ELF في Linux حقل صنف وحقل آلة في ترويسة الملف، والاثنان يجيبان عن سؤالين مختلفين. يقول الصنف هل يستخدم الملف صيغة 32 بت أم 64 بت؛ وتقول الآلة لأي مجموعة تعليمات بُني. بناء x86 من 32 بت وبناء ARM من 32 بت يتفقان على الأول ويختلفان على الثاني. هكذا يسلّم ملصق يعد بحجم الكلمة الصحيح شيفرة لا يستطيع المعالج فكّها. القيمة الثالثة الجديرة بالقراءة هي المفسّر المطلوب، وهو ما تسمّيه ترويسات البرنامج عندما يعلن الملف الثنائي واحدًا.
readelf -h -- ./vendor-vpn
readelf -l -- ./vendor-vpn
readelf -d -- ./vendor-vpn | grep NEEDED
يطبع الأمر الأول الترويسة، ويطبع الثاني ترويسات البرنامج عندما يكون للملف أي منها، ويسرد الثالث الكائنات المشتركة التي سيحتاجها المُحمّل. سجّل الصنف والآلة والمفسّر معًا، لأن تلك القيم الثلاث هي مسألة التوافق بأكملها في هذه الطبقة. لا تظهر أي من الثلاث على زر تنزيل، ولهذا يجب فحص الملف بدلًا من وصفه.
أي مفسّر يطلبه من النواة
الملف التنفيذي الذي يعلن مفسّرًا يطلب من النواة مسار مُحمّل واحدًا محدّدًا. حين يغيب ذلك المُحمّل يفشل التشغيل رغم أن الملف الذي سمّيته موجود هناك تمامًا. هذه هي النقطة التي يقرّر فيها الناس أن التنزيل تالف، بينما الجواب الفعلي هو مُحمّل لا يوفّره التوزيع.
طابق المُحمّل مع النظام الذي تشغّله فعلًا: إصدار نظام التشغيل، ومعمارية مساحة المستخدم، والحزمة التي توفّر المُحمّل. يمكن لنواة 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 تعني أن الصيغة لم تُعرَف: معمارية خاطئة، أو صنف خاطئ، أو شيء ليس ملفًا تنفيذيًا أصلًا. ENOENT على ملف ELF تعني عادةً أن المفسّر مفقود، رغم أن الملف الذي طلبته موجود. يمكن أن تعني ENOENT نفسها أيضًا أن مفسّر سكربت غائب، ولهذا يهمّ السطر الأول من السكربت. في كلتا الحالتين تسمّي الرسالة الطبقة، ومعاملة كل «غير موجود» كإعداد مفقود توجّه التحقيق في الاتجاه الخاطئ. اقتبس قيمة الخطأ في التذكرة، لأنها تصمد أمام إعادة السرد أكثر من الجملة المحيطة بها.
ما لا يجب فعله عندما لا يبدأ الملف الثنائي
إجبار ملف ثنائي غير مفسّر على العمل عبر غلاف صدفة لا يجعله يعمل. لا تشغّل فاحص تبعيات بلا مبالاة على ملف لا تثق به، لأن تشغيله قد ينفّذ شيفرة من الملف الثنائي في بعض الظروف. لا تضف روابط رمزية للمُحمّل، ولا تبدّل مكتبات المضيف، ولا تجلب أرشيفًا قديمًا من مرآة طرف ثالث لتجاوز الرسالة. كل ذلك يوسّع مساحة التغيير دون أن يمسّ عدم التطابق الذي سمّته الترويسة أصلًا.
عندما تتواصل مع المورّد، أرسل قيمًا لا حكاية: إصدار نظام التشغيل، ومعمارية الحزمة، وسلاسل الصنف والآلة، والمفسّر المطلوب، وأول سطر خطأ. تلك المجموعة تحلّ أسئلة الدعم أسرع من لقطة شاشة لمثبّت فاشل. المخرجات القديمة ونواتج المنتديات المتذكّرة ليست مصفوفة دعم حالية، وبعد أن يُحمّل ملف ثنائي أصلي يبقى الملف الشخصي والمصادقة والتوجيه عملًا منفصلًا.