עמוד הורדה אומר 32-bit, הקובץ נוחת על Raspberry Pi, והמתקין נכשל בהודעה שאינה נוקבת בשום חלק שימושי של הבעיה. שני קבצים הרצים שונים לחלוטין נחשבים שניהם 32-bit במשמעות ELF, ורק אחד מהם יכול לרוץ על הלוח הזה. שדה המחלקה הוא עובדה אחת, שדה המכונה הוא אחרת, ושם קובץ אינו אומר לכם בביטחון אף אחד מהם. קראו את הכותרת לפני שאתם משנים ספרייה או מנסים מראה אחרת.

המחלקה אומרת גודל מילה, המכונה אומרת ערכת הוראות

מדריך 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 downloadELF classe_machineInterpreter the kernel wantsHow it fails on the wrong host
amd64ELF64x86-64/lib64/ld-linux-x86-64.so.2Immediate exec failure on an ARM board
armhfELF32ARM/lib/ld-linux-armhf.so.3Loads on a soft-float system, then fails on a float ABI call
i386ELF32Intel 80386/lib/ld-linux.so.2Exec format error where no 32-bit loader package exists

כל שורה היא מקרה שבו גודל המילה נראה נכון והקוד עדיין מתנהג שלא כשורה, או שבו הוא מתחיל ואז נכשל שכבה אחת למטה. קראו את עמודת המפרש כדרישה קשיחה ולא כרמז, מפני שהליבה פותרת את הנתיב הזה לפני שכל קוד שלכם רץ. אמולציה היא החלטת פריסה עם השלכות ביצועים ותמיכה משלה, והיא לעולם אינה משתמעת ממעבד שמפרסם גודל מילה רחב יותר.

dpkg --print-architecture

ENOEXEC ו-ENOENT הם כשלים שונים

שלב ההפעלה מדווח על אחת משתי שגיאות, והן מצביעות על בעיות שונות. קריאת ערך השגיאה מסווגת את הכשל לפני שתפעילו משהו אחר.

ENOEXEC פירושה שהתבנית לא זוהתה: ארכיטקטורה שגויה, מחלקה שגויה או משהו שאינו קובץ הרצה כלל. ENOENT על קובץ ELF פירושה בדרך כלל שהמפרש חסר, אף שהקובץ שביקשתם קיים. אותו ENOENT יכול גם לומר שמפרש של סקריפט חסר, ולכן השורה הראשונה של סקריפט חשובה. כך או כך ההודעה נוקבת בשכבה, והתייחסות לכל „לא נמצא” כאל תצורה חסרה שולחת את החקירה לכיוון הלא נכון. צטטו את ערך השגיאה בכרטיס, מפני שהוא שורד סיפור חוזר טוב יותר מהמשפט שסביבו.

מה לא לעשות כשהקובץ הבינארי לא מתחיל

כפייה של קובץ בינארי לא מוסבר דרך עטיפת מעטפת אינה מפעילה אותו. אל תריצו בודק תלויות בקלות דעת על קובץ שאינכם סומכים עליו, מפני שהרצתו עשויה בנסיבות מסוימות להריץ קוד מהקובץ הבינארי. אל תוסיפו קישורים סימבוליים לטוען, אל תחליפו ספריות מארח ואל תורידו ארכיון ישן ממראה של צד שלישי כדי לעקוף את ההודעה. כל אחד מאלה מרחיב את משטח השינוי בלי לגעת אי-ההתאמה שהכותרת כבר ציינה.

כשאתם פונים לספק, שלחו ערכים ולא סיפור: גרסת מערכת ההפעלה, ארכיטקטורת החבילה, מחרוזות המחלקה והמכונה, המפרש המבוקש ושורת השגיאה הראשונה. המערכת הזו פותרת שאלות תמיכה מהר יותר מצילום מסך של מתקין שנכשל. חפצים ישנים ופלטי פורום זכורים אינם מטריצת תמיכה עדכנית, ולאחר שקובץ בינארי מקומי נטען, פרופיל, אימות וניתוב נשארים עבודה נפרדת.

מאמרים קשורים