هندسة الفوضى لـ C++: كيفية تقوية برامجك

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

الفوضى ليست خطأ، بل ميزة: التعرف على هندسة الفوضى في C++

\n

تخيل: خدمة C++ الخاصة بك تعمل لأشهر دون أعطال. ثم فجأة! - فشل القرص، فقدان حزمة، أو SIGKILL مفاجئ. وينتهي كل شيء. النظام ينهار، المستخدمون غاضبون، وأنت تبحث بشكل محموم عن الخطأ في السجلات. هل هذا الموقف مألوف؟

\n

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

\n

هندسة الفوضى لـ C++ ليست مجرد "تشغيل chaos monkey والصلاة". إنها تتعلق بتجارب محكومة تكشف نقاط الضعف قبل أن يجدها المستخدمون. سنتعلم كيفية إدخال أعطال الذاكرة، ومحاكاة الإدخال/الإخراج البطيء، وقطع اتصالات الشبكة - وكل ذلك باستخدام كود C++ نقي.

\n\n

لماذا تحتاج C++ بشكل خاص إلى هندسة الفوضى؟

\n

لغة C++ تمنح المطور قوة هائلة: إدارة يدوية للذاكرة، وصول منخفض المستوى للموارد، وعدم وجود جامع قمامة. لكن هذه القوة سلاح ذو حدين. خطأ في delete[]، تسرب في غلاف RAII، أو reinterpret_cast غير صحيح يمكن أن يحول نظامًا مستقرًا إلى بيت من ورق هش.

\n

نادرًا ما يختبر اختبار الوحدات التقليدي كيف سيتصرف الكود في حالة:

\n
    \n
  • نقص الذاكرة العشوائية (std::bad_alloc)
  • \n
  • إغلاق مفاجئ لوصف الملف
  • \n
  • تأخيرات في الشبكة (latency spikes)
  • \n
  • فساد البيانات في الذاكرة المشتركة
  • \n
\n

هندسة الفوضى لـ C++ تسد هذه الفجوات. نحن لا نكتب اختبارات فقط - بل نستفز النظام لارتكاب الأخطاء ونرى إن كان سينجو.

\n\n

الأدوات: كيفية إدخال الفوضى في كود C++

\n

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

\n
    \n
  • على مستوى الكود: اعتراض استدعاءات النظام عبر LD_PRELOAD أو dlsym
  • \n
  • على مستوى المكتبات: استبدال المخصصات والمقابس القياسية
  • \n
  • على مستوى نظام التشغيل: استخدام ptrace أو eBPF للتدخل في عمل العملية
  • \n
\n

سنتبع المسار الأكثر عملية - سنكتب مكتبتنا الخاصة لحقن الأخطاء، والتي يمكن دمجها بسهولة في أي مشروع C++.

\n\n

مثال 1: محاكاة فشل تخصيص الذاكرة

\n

واحدة من أكثر المشاكل شيوعًا في C++ هي std::bad_alloc غير المتوقع. كيف سيتصرف كودك إذا أعاد new استثناءً؟ دعنا نتحقق.

\n
// chaos_memory.h\n#pragma once\n#include <new>\n#include <cstdlib>\n#include <atomic>\n#include <cstddef>\n\nclass ChaosAllocator {\npublic:\n    // تعيين احتمالية الفشل (0.0 - 1.0)\n    static void set_failure_probability(double prob) {\n        failure_probability_ = prob;\n    }\n\n    static void* allocate(std::size_t size) {\n        if (should_fail()) {\n            throw std::bad_alloc();\n        }\n        return std::malloc(size);\n    }\n\n    static void deallocate(void* ptr) {\n        std::free(ptr);\n    }\n\nprivate:\n    static bool should_fail() {\n        // مولد أرقام عشوائية بسيط للعرض\n        static std::atomic<unsigned int> seed = 42;\n        seed = seed * 1103515245 + 12345;\n        return (seed / 65536) % 100 < failure_probability_ * 100;\n    }\n\n    inline static double failure_probability_ = 0.0;\n};
\n

الآن يمكننا استبدال المخصص القياسي والتحقق من كيفية معالجة الكود الخاص بنا لأعطال الذاكرة:

\n
// main.cpp\n#include <iostream>\n#include <vector>\n#include "chaos_memory.h"\n\n// مخصص مخصص                

المدونات

توصيات الكتب