نصبکننده VPN میگوید 32 بیت: بهجایش سرآیند ELF را بررسی کنید
اندازه واژه مجموعه دستور را مشخص نمیکند. رویه خواندن کلاس، ماشین و مفسر و سپس درخواست ساختی که با میزبان همخوان باشد.
یک صفحه دانلود میگوید 32 بیت، فایل روی Raspberry Pi فرود میآید و نصبکننده با پیامی شکست میخورد که هیچ بخش مفیدی از مشکل را نام نمیبرد. دو فایل اجرایی کاملاً متفاوت هر دو در معنای ELF 32 بیت شمرده میشوند و تنها یکی از آنها میتواند روی آن برد اجرا شود. فیلد کلاس یک واقعیت است، فیلد ماشین واقعیت دیگری و نام فایل بهطور قابل اعتماد هیچکدام را به شما نمیگوید. پیش از تغییر یک کتابخانه یا آزمودن آینه دیگر، سرآیند را بخوانید.
کلاس اندازه واژه را میگوید، ماشین مجموعه دستور را
مرجع ELF لینوکس در سرآیند فایل یک فیلد کلاس و یک فیلد ماشین تعریف میکند و این دو به پرسشهای متفاوتی پاسخ میدهند. کلاس میگوید فایل از قالب 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 میتواند یعنی مفسر یک اسکریپت هم غایب است و از این رو خط اول اسکریپت اهمیت دارد. در هر حال پیام لایه را نام میبرد و برخورد با هر «پیدا نشد» بهعنوان پیکربندی غایب، تحقیق را به جهت نادرست میفرستد. مقدار خطا را در تیکت نقل کنید، چون از جمله پیرامونش بهتر جان سالم به در میبرد.
وقتی باینری اجرا نمیشود چه نکنیم
بهزور عبور دادن یک باینری توضیحدادهنشده از یک پوشش پوسته آن را اجرا نمیکند. بررسیکننده وابستگی را بیدقت روی فایلی که به آن اعتماد ندارید اجرا نکنید، چون اجرای آن در برخی شرایط میتواند کدی از باینری اجرا کند. پیوندهای نمادین بارگذار را اضافه نکنید، کتابخانههای میزبان را عوض نکنید و بایگانی کهنهای از آینه شخص ثالث نگیرید تا از پیام بگذرید. هر یک از اینها سطح تغییر را میگستراند بیآنکه ناسازگاریای را که سرآیند پیشتر نام برده بود لمس کند.
وقتی به فروشنده مراجعه میکنید، مقدار بفرستید نه داستان: نسخه سیستمعامل، معماری بسته، رشتههای کلاس و ماشین، مفسر درخواستی و نخستین خط خطا. این مجموعه پرسشهای پشتیبانی را سریعتر از تصویر یک نصبکننده شکستخورده حل میکند. مصنوعات کهنه و خروجیهای بهیادمانده انجمن ماتریس پشتیبانی کنونی نیستند و پس از بارگذاری یک باینری بومی، نمایه، احراز هویت و مسیریابی کار جداگانهای میمانند.