أمضى مهندسو OpenAI أسابيع في محاولة شرح الأعطال الغامضة في Rockset، وهي خدمة البنية التحتية لبيانات C++ التي تعمل على تشغيل المكونات الإضافية للبحث والبيانات في ChatGPT. يبدو أن الوظائف تعود إلى عناوين الذاكرة الزائفة. يبدو أن مؤشرات المكدس تتحول بمقدار 8 بايت في منتصف التنفيذ. كل فرضية يمكن للفريق أن يبنيها كانت لها أدلة قوية ضدها. بدا الخطأ مستحيلا.

ما افترضوه كان خللًا واحدًا تبين أنه خللان غير مرتبطين، تم اكتشافهما بالصدفة في نفس الوقت. لم يأت هذا الإنجاز من فحص أعمق للحوادث الفردية، بل من التحول إلى ما يسميه الفريق تصحيح الأخطاء الوبائية: بناء خط أنابيب لتحليل كل تفريغ أساسي للإنتاج من العام الماضي تلقائيًا، ثم البحث عن أنماط على مستوى السكان بدلاً من التفكير في الحالات الفردية.

طلب الفريق من ChatGPT كتابة برنامج نصي يقوم بتنزيل بادئة لكل ملف أساسي، واستخراج السجلات، وتصفية الإيجابيات الكاذبة المعروفة، وتصنيف كل حادث على أنه عودة إلى الصفر، أو مكدس غير محاذي، أو غير ذلك. لقد قاموا بتشغيله بالتوازي مع كل مكب نفايات Rockset الأساسي من العام السابق. ظهرت الارتباطات على الفور. ما بدا وكأنه متلازمة واحدة كان في الواقع مجموعتين مختلفتين من حوادث التصادم بتوقيعات مختلفة تمامًا.

جاءت جميع حالات تحطم المكدس غير المتوافقة من منطقة Azure واحدة، وكان لها تاريخ بدء واضح، ولم تظهر أبدًا على العقد طويلة الأمد. قام الفريق بتتبعهم إلى مضيف فعلي واحد حيث كانت وحدة المعالجة المركزية تنتج بصمت نتائج غير صحيحة. لا يوجد ارتفاع في درجة الحرارة، ولا يتم طرح استثناءات للتحقق من الآلة، بل مجرد خطأ في الرياضيات بهدوء. بمجرد إزالة هذا المضيف من الخدمة، اختفت أعطال المكدس المنحرف تمامًا.

مع فصل أعطال الأجهزة، أصبحت أعطال العودة إلى الصفر المتبقية قابلة للتتبع. كان الفريق قد استبعد سابقًا تفكيك استثناء C++ كسبب لأنهم اعتقدوا أن لديهم أمثلة مضادة: أعطال في مسارات التعليمات البرمجية التي لا تستخدم الاستثناءات. لكن هذه الأمثلة المضادة جاءت جميعها من مجموعة فساد الأجهزة. بمجرد إزالة هذا التلوث، كان كل التعطل المتبقي يحدث أثناء تفكيك الاستثناء.

كان السبب الجذري هو حالة السباق في وظيفة _Ux86_64_setcontext الخاصة بـ GNU libunwind والتي كانت موجودة لمدة 18 عامًا. أثناء تفكيك استثناء C++، يقوم libunwind بتجميع بنية ucontext_t على المكدس، ويملأ حالة التسجيل المطلوبة، ثم يستدعي _Ux86_64_setcontext لنقل التحكم إلى معالج التنظيف. المشكلة: يقوم _Ux86_64_setcontext بتحديث مؤشر المكدس (%rsp) للإشارة إلى إطار المكدس الجديد قبل أن ينتهي من قراءة مؤشر التعليمات من البنية القديمة. في اللحظة التي يتغير فيها %rsp، لم تعد البنية جزءًا من المكدس النشط ولم تعد محمية بضمان المنطقة الحمراء للنواة. إذا وصلت إشارة في تلك النافذة بالضبط بين تحديث %rsp وقراءة %rip، فإن النواة تبني إطار الإشارة الخاص بها أعلى البنية، مما يؤدي إلى إتلاف مؤشر التعليمات. تنتقل الدالة بعد ذلك إلى NULL أو البيانات المهملة.

نافذة السباق بعرض تعليمات واحدة بالضبط. وبسرعات الساعة الحديثة، يبلغ هذا حوالي 100 بيكو ثانية. في معظم البرامج لن يتم تشغيله أبدًا. تستخدم Rockset من OpenAI timer_create لتقديم إشارة SIGUSR2 كل بضعة ميلي ثانية من وقت وحدة المعالجة المركزية من أجل حساب خفيف الوزن لكل استعلام، مما يؤدي إلى إنشاء أحداث تسليم إشارة أكثر بكثير من التطبيقات النموذجية. أدى هذا التردد إلى تحويل السباق المحتمل نظريًا إلى انهيار الإنتاج.

قام الفريق بنقل إصلاح وناسخ مستقل إلى GNU libunwind، والتحقق من أن أدوات فك اللف الأخرى (libgcc) لا تعاني من نفس المشكلة. يقوم الإصلاح بإعادة ترتيب الإرشادات بحيث تتم قراءة %rip قبل تحديث %rsp، مما يؤدي إلى إزالة النافذة بالكامل.

يستحق ملخص الدرس الخاص بالفريق تكراره بالكامل:

لم تكن الخطوة الأكثر أهمية هي القراءة الذكية للتجميع أو المعرفة العميقة بالتفاصيل. لقد كان يبني مجموعة بيانات عالية الجودة. في غياب مجموعة البيانات هذه، كنا نخلط ظاهرتين مختلفتين في قصة واحدة ونحاول إيجاد طريقنا للخروج من هذا الارتباك. وبمجرد حصولنا على بيانات سكانية دقيقة وكاملة، أصبح هيكل المشكلة واضحا.

بالنسبة لأي فريق يقوم بتصحيح أعطال الإنتاج التي تقاوم التفسير: تحقق مما إذا كنت تخلط بين أخطاء متعددة. الأعراض التي تبدو متعارضة مع كل فرضية قد لا تكون متعارضة على الإطلاق؛ قد تكون متسقة مع فرضيتين مختلفتين تخلطهما عن طريق الخطأ. أسرع طريق لرؤية البنية ليس التحليل العميق للحالات الفردية، بل البيانات الكاملة والمصنفة عبر مجموعة كاملة من الأشخاص الفاشلين.

يتضمن منشور المدونة الهندسية الكامل مخططات تفصيلية للمكدس، وتعليمات التجميع الضعيفة، وتصورات معدل الأعطال التي كشفت عن المجموعتين السكانيتين.



شاركها.
اترك تعليقاً