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 يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.