0Pricing
C++ Academy · درس

UBSan وTSan

اعثر على السلوك غير المعرّف وظروف السباق

UBSan وTSan درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.

أداتا فحص إضافيتان

إلى جانب ASan، تستهدف أداتا فحص فئتين مختلفتين من الأخطاء.

  • UBSan: السلوك غير المعرّف، مثل تجاوز السعة والإزاحات غير الصحيحة وإلغاء إشارة مؤشر فارغ
  • TSan: تعارضات البيانات في الشفرة متعددة الخيوط

تفعيل UBSan

يُفعّل UndefinedBehaviorSanitizer باستخدام -fsanitize=undefined. ويمكن دمجه مع ASan.

g++ -fsanitize=undefined -g main.cpp -o app
./app

تجاوز سعة الأعداد الصحيحة الموقّعة

يُعد تجاوز سعة عدد صحيح موقّع سلوكًا غير معرّف في C++. ويصدر UBSan تقريرًا عنه عند السطر المحدد تمامًا.

#include <climits>
#include <iostream>

int main() {
    int x = INT_MAX;
    int y = x + 1; // signed overflow: UB
    std::cout << y << "\n";
    return 0;
}

أخطاء UB الأخرى التي يكتشفها UBSan

يرصد UBSan العديد من الأخطاء الدقيقة.

  • الإزاحات الخارجة عن النطاق (x << 40 لعدد صحيح حجمه 32 بت)
  • إلغاء إشارة مؤشر فارغ
  • الوصول غير المحاذي
  • قيم enum أو bool غير صالحة

إيقاف UBSan عند الخطأ

يطبع UBSan رسائل الخطأ ويتابع التنفيذ افتراضيًا. أضف -fno-sanitize-recover=undefined لإيقاف التنفيذ عند أول خطأ، وهو أفضل لبيئات CI.

g++ -fsanitize=undefined -fno-sanitize-recover=undefined -g main.cpp -o app

تفعيل TSan

يُفعّل ThreadSanitizer باستخدام -fsanitize=thread. ويكتشف تعارضات البيانات، أي وصول خيطين إلى الذاكرة نفسها دون مزامنة، على أن يجري أحدهما عملية كتابة على الأقل.

g++ -fsanitize=thread -g main.cpp -o app -pthread
./app

مثال على تعارض بيانات

يزيد خيطان قيمة عدّاد مشترك دون استخدام قفل. ويصدر TSan تقريرًا عن عمليات الوصول المتعارضة ومكدسات استدعاءاتها.

#include <thread>
#include <iostream>

int counter = 0;

void work() { for (int i = 0; i < 1000; ++i) ++counter; }

int main() {
    std::thread t1(work), t2(work);
    t1.join();
    t2.join();
    std::cout << counter << "\n";
    return 0;
}

إصلاح التعارض

احمِ البيانات المشتركة باستخدام كائن mutex أو استخدم std::atomic. بعد الإصلاح، لن يرصد TSan أي تعارضات.

#include <thread>
#include <atomic>
#include <iostream>

std::atomic<int> counter{0};

void work() { for (int i = 0; i < 1000; ++i) ++counter; }

int main() {
    std::thread t1(work), t2(work);
    t1.join();
    t2.join();
    std::cout << counter << "\n";
    return 0;
}

التوافق بين TSan وASan

لا يمكن دمج TSan مع ASan في الإصدار نفسه، لأنهما يتعارضان. استخدم إعدادين منفصلين للإنشاء: أحدهما لـ ASan+UBSan، والآخر لـ TSan.

مصفوفة إصدارات أدوات الفحص

يشغّل إعداد عملي لبيئة CI مجموعة الاختبارات ضمن إصدارين يستخدمان أدوات الفحص.

  • الإصدار A: -fsanitize=address,undefined
  • الإصدار B: -fsanitize=thread

يغطي هذا أخطاء الذاكرة والسلوك غير المعرّف والتزامن.

التكلفة والحدود

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

تحقق سريع

تذكّر ما الذي يكتشفه TSan.

مراجعة

لقد تعلّمتم UBSan وTSan.

  • يكتشف UBSan (-fsanitize=undefined) تجاوز السعة والإزاحات غير الصحيحة وإلغاء إشارة المؤشرات الفارغة
  • استخدموا -fno-sanitize-recover لإيقاف التنفيذ عند أول سلوك غير معرّف
  • يكتشف TSan (-fsanitize=thread) تعارضات البيانات؛ أصلحوها باستخدام mutex أو atomic
  • يحتاج TSan وASan إلى إصدارات منفصلة

الأسئلة الشائعة

هل درس «UBSan وTSan» مجاني؟

نعم — نص درس «UBSan وTSan» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.

ماذا ستتعلم في «UBSan وTSan»؟

اعثر على السلوك غير المعرّف وظروف السباق تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟

لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «UBSan وTSan»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟

نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. استخدام gdb وlldb
  2. AddressSanitizer
  3. UBSan وTSan
  4. أساسيات Valgrind
← العودة إلى C++ Academy