כמעט 4 שנים לפתרון באג

במאי 2009 ביצעתי שינוי בצורה שבה fakeroot-ng תופס תהליכים חדשים שנוצרים. במקום להסתמך על מנגנון מובנה של מערכת ptrace, שלא עבד בצורה אמינה על קרנלים של redhat שהשתמשו ב–utrace, החלפתי את המנגנון למשהו שהועתק, כמעט במדויק, מ–strace. בגדול, מחליפים את הפרמטרים לפקודה clone כך שאומרים לה שהדיבאגר של האבא הוא גם הדיבאגר של הבן.

וזה עבד מצויין, חוץ מאשר ב–threads. משום מה, זה לא עבד עליהם. הם פשוט לא היו מתחילים לרוץ.

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

מכיוון שהקוד עבד על strace, ניסיתי לבדוק מה ההבדלים. בהרצה במקביל של strace ושל fakeroot-ng לא מצאתי שום הבדל משמעותי בקריאות ל–ptrace. זה הגיע לכדי כך שהרצתי קרנל מיוחד שמדפיס את הקריאות ל–ptrace כדי שאני אוכל להשוות בין fakeroot-ng לבין ptrace. שום הבדל.

בזמן האחרון אני בין עבודות (מתחיל עבודה חדשה ביום ראשון). אמנם רוב הזמן הפנוי שנוצר לי נשרף לחלוטין על סידורים של קניית דירה חדשה, מכירת הדירה הישנה ונסיון לקנות אוטו, אבל היום הצלחתי בכל זאת לשבת טיפה על הנושא (שוב פעם). אלא שהיום ניסתי לנקוט בגישה חדשה. במקום לנסות להבין מה fakeroot-ng עושה שונה מ–strace, ניסיתי לכתוב תוכנה חדשה שזה כל מה שהיא עושה.

תיקון הבאג קצר בצורה מביכה. להלן השינוי, במלואו (זמין גם באתר):

Index: arch/linux/os.c
===================================================================
--- arch/linux/os.c     (revision 326)
+++ arch/linux/os.c     (revision 327)
@@ -50,7 +50,7 @@
 
 int ptlib_linux_wait( pid_t *pid, int *status, ptlib_extra_data *data, int async )
 {
-    *pid=wait4(-1, status, async?WNOHANG:0, data );
+    *pid=wait4(-1, status, (async?WNOHANG:0)|__WALL, data );
 
     if( async && *pid==0 ) {
         errno=EAGAIN;

במשך קרוב לארבע שנים אני מתמקד בהבדלים ב–ptrace בין strace לבין fakeroot-ng, ולא מוצא. כל זאת בלי לשים לב שיש הבדל ב–wait.

ועל זה נאמר: „שום דבר הוא לא מבוזבז. לכל היותר, הוא יכול להיות פוסט משעשע בבלוג”.

שחר

מאת

שחר שמש

מייסד ומנכ"ל "לינגנו ייעוץ קוד פתוח בע"מ" חבר ועד בעמותת "המקור" וסתם פעיל קוד פתוח ולינוקס