التحقيق في انهيار SIGBUS المتقطع في تطبيقات iOS

غالباً ما تتطلب الانهيارات المتقطعة في بيئة الإنتاج عزلاً مضبوطاً للأخطاء عندما تفشل السجلات والاختبار المحلي في تحديد المشكلة. فانخفاض معدل الانهيار الإجمالي لا يضمن حل السبب الجذري، إذ يمكن لتغييرات غير ذات صلة أن تغيّر توقيت عيوب التزامن.
في تحقيق حديث، أشارت إشارة SIGBUS إلى وصول غير صالح إلى الذاكرة في تطبيق iOS استهلاكي واسع النطاق. أصاب الانهيار مجموعة فرعية من عمليات التنفيذ فقط وظهر بشكل غير متوقع، ما دفع إلى تحقيق مركّز وإصلاح عاجل.
رغم جهود المطورين ومهندسي ضمان الجودة، تعذّرت إعادة إنتاج الانهيار بشكل متسق. أشار تقرير SIGBUS إلى معالجة attributed string لكنه لم يحدد سطراً معيناً في كود Swift. ترك ذلك مساحة بحث واسعة، مع الأخذ في الاعتبار عوامل مثل عمر الكائن، وملكية view model في SwiftUI، والعمل غير المتزامن.
بدأ التحقيق بفحوصات معيارية، شملت تفعيل Zombie Objects ومراجعة الملكية حول الشاشات المتأثرة. أُجريت تحسينات دفاعية، شددت ملكية الكائنات القابلة للملاحظة ووضحت التزامن. ورغم أن هذه التغييرات خفّضت معدل الانهيار الإجمالي، استمرت بصمة الانهيار الأصلية.
كانت التحسينات الأولية مضللة؛ فبينما انخفض معدل الانهيار الإجمالي، لم يثبت ذلك علاقة سببية. يمكن أن تصبح الأعطال الحساسة للتوقيت أقل تكراراً دون إزالة العيب الكامن. كانت نافذة التحقيق تضيق، وجاء الاختراق عندما اكتشفت مهندسة ضمان جودة أنها تستطيع إعادة إنتاج الانهيار بشكل متقطع.
غيّر هذا الفشل القابل لإعادة الإنتاج مسار التحقيق، وأتاح اختباراً عملياً. اختُبرت كل نسخة تجريبية على الجهاز، واستمرت حلقة تغيير منطقة واحدة وبناء IPA واختباره. شمل التحقيق أيضاً نقاشات في مجتمعات المطورين، رغم تعذّر مشاركة معلومات خاصة.
استُخدم العزل المنهجي للأخطاء، مع تحويل التركيز من الكود المشبوه إلى تحديد الكود الضروري لحدوث الانهيار. ضيّقت هذه العملية المشكلة إلى عملية واحدة: تحويل بيانات HTML إلى attributed string.
شمل التدفق المتأثر عرض قسم إفصاح ثابت منسق بصيغة HTML، تضمن عناصر تفاعلية. كانت المشكلة الحرجة أن تحويل HTML إلى attributed string يمكن استدعاؤه من مسار غير متزامن دون ضمان التنفيذ على الخيط الرئيسي، ما يخالف قيد التزامن في Foundation.
يمكن أن تنجو العيوب المعتمدة على التوقيت من العديد من عمليات التنفيذ الناجحة، ما يفسر ظهور الانهيار عشوائياً. أثّرت التغييرات في معالجة دورة الحياة والتزامن على التوقيت لكنها لم تزل سياق التنفيذ غير المدعوم.
تضمن الإصلاح الفوري إجراء تحويل HTML على main actor. أُدخل مساعد مشترك لفرض شرط التنفيذ كجزء من API، ما قلل التكرار ومركز اعتماد Foundation.
بعد تنفيذ الإصلاح، اختبرت مهندسة ضمان الجودة التدفق على الجهاز الذي كان يمثل مشكلة سابقاً، ولم يظهر الفشل بعد ذلك. أكد اختبار إضافي الإصلاح عبر العروض ذات الصلة، وأظهرت مراقبة الإنتاج انخفاضاً كبيراً في الانهيار المستهدف.
أبرز التحقيق أهمية إنشاء أدلة جديدة عندما تكون الأدلة الحالية غير مكتملة. كان الفشل القابل لإعادة الإنتاج أكثر قيمة من قائمة تغييرات كود محتملة، إذ أتاح اختبار فرضيات واضح. كما شدد الحادث على ضرورة تقييم تجريدات الأطر بعناية، لأن مهيئات Swift قد تخفي سلوكيات غير آمنة موروثة من أطر أخرى.
كان تغيير الكود النهائي صغيراً، لكن التحقيق تطلب التعامل مع معلومات انهيار غير مكتملة، وتحسينات مبكرة مضللة، وضغط الوقت. لم يقتصر تحديد السبب الجذري وتنفيذ الإصلاح بنجاح على حل المشكلة الفورية فحسب، بل جعل التكرار المستقبلي أقل احتمالاً.
المصدر: InfoQ