Valgrind: أهي أداة مهملة من عالم الظلال أم أداة جدية لتصحيح الأخطاء؟

Last updated

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

اليوم، سنعود قليلاً إلى الماضي ونتحدث عن أداة قديمة لكنها لا تزال قوية جدًّا تُدعى Valgrind. وقد ظلت هذه الأداة تخدم المطورين منذ فترة طويلة، حيث إنها تكتشف مجموعة واسعة من الأخطاء مثل قراءة الذاكرة غير المُهيأة، وتجاوز سعة مخزن الـ«هيوب»، وتسربات الذاكرة، وحالات التعطل المتبادل، وما إلى ذلك.

بعد أن أطلقت Clang مجموعتها من أدوات التعقيم، تراجع دور Valgrind إلى الخلفية، لكن كما سترون في هذه المدونة، هناك بعض الحالات التي يتفوق فيها Valgrind فعليًّا على أدوات التعقيم بشكل ساحق. 

وحش تحت غطاء المحرك

تتمثل إحدى أكبر مزايا Valgrind مقارنةً ببرامج التنقية في أنه لا يتطلب تجهيز البرنامج بأدوات الرصد قبل فحصه. وهذا يعني أنه يمكن استخدامه لتصحيح أخطاء أي نوع من البرامج «فورًا» دون الحاجة إلى الوصول إلى كود المصدر الخاص بها.

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

على عكس أدوات الفحص، يستخدم Valgrind تقنية «التجهيز الثنائي الديناميكي» (DPI) والتجميع «في الوقت المناسب» (JIT) لدمج كود برنامجنا مع كود التجهيز، أي لاعتراض استدعاءات وظائف التخصيص بهدف تخزين بعض المعلومات الإضافية. 

Here’s how it works. Each allocated block maps to a shadow block where the call stack at the time of the malloc function call is stored. Once the free function is called, Valgrind tries to find the shadow block corresponding to the address passed to free. If the block is not found, Valgrind emits an error message. Otherwise, the block is added to the queue and gets marked as inaccessible. This way, it is possible to detect invalid access to freed memory. However, please note that blocks can be removed from the queue once the system runs out of free space.

هل ترغب في معرفة المزيد؟
اتصل بنا اليوم للتحدث إلى أحد خبراء Microblink المتخصصين في مكافحة الاحتيال وحماية الهوية

المرونة التي توفرها البنية الطبقية

كما هو موضح في الشكل أدناه، يتكون Valgrind من طبقتين: نواة Valgrind ومكوّن الأداة الإضافي الذي يمكن أن يكون أيًا من الأدوات الموجودة في مجموعة أدوات Valgrind، بما في ذلك: 

  • Memcheck – يتتبع عمليات تخصيص الذاكرة ويبلغ عن تسربات الذاكرة
  • Helgrind – يكتشف المشكلات المتعلقة بالتعدد الخيطي (مثل حالات التعطل المتبادل، وتنافس البيانات، وما إلى ذلك)
  • Cachegrind – يعمل كأداة تحليل أداء ذاكرة التخزين المؤقت وتوقع الفروع
  • Massif – يحلل استخدام ذاكرة الكومة

ضع في اعتبارك أن Valgrind هو برنامج مفتوح المصدر، ويمكنك كتابة أداة خاصة بك إذا أردت. 

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

طريقة أسهل لتصحيح الأخطاء

كما ذكرنا في منشور المدونة السابق، تتطلب أدوات التنقية في لغة C++ إعادة ترجمة الكود. وقد يشكل ذلك عائقًا عندما ترغب في اختبار الكود باستخدام كل من AddressSanitizer وMemorySanitizer. ونظرًا لأن هذين البرنامجين لا يمكنهما العمل معًا، فستحتاج إلى إجراء عدة جولات اختبار للكشف عن عمليات قراءة الذاكرة غير المُهيأة والأخطاء الأخرى المتعلقة بالعناوين. من ناحية أخرى، يمكن لـ Valgrind تشغيل أي برنامج تقريبًا كما هو. والشيء الوحيد الذي يحتاجه هو دعم جميع التعليمات التي يستخدمها برنامجنا.

لنفترض أنك تريد تصحيح أخطاء مكتبة لا يمكن الوصول إلى شفرة مصدرها. لن يؤدي استخدام أدوات التنقية إلى أي نتائج لأنها، على عكس Valgrind، تعمل على مستوى المُجمِّع. مع Valgrind، يمكنك التعامل مع هذه الحالات بشكل افتراضي، لكن ضع في اعتبارك أنك قد تحصل في النهاية على رسائل خطأ لا تعني لك الكثير لأنك لا تملك أي سيطرة على تلك الشفرة. ومع ذلك، يمكنك تصفية هذه الرسائل عن طريق تدوينها في ملف «suppressions» الذي يتم قراءته عند بدء تشغيل Valgrind. 

إلى جانب عملية تصحيح الأخطاء الأكثر سلاسة، يُعد Valgrind بديلاً ممتازًا على الأنظمة الأساسية التي لا تدعم أدوات التنقية. فعلى سبيل المثال، لا يأتي Apple Clang مزودًا بـ LeakSanitizer، مما يجعل Valgrind هو أفضل بديل متاح لك ما لم تكن مستعدًا للتحول إلى مُجمِّع برمجي آخر. 

الأداء باعتباره أكبر عيب

دعونا نلقي نظرة على نسخة معدلة قليلاً من المثال الوارد في منشورنا الأول حول أدوات التنقية في لغة C++: 

char const * src{ "Hello world!" };
auto const dst{ std::make_unique< char[] >( std::strlen( src ) ) };

for ( auto i{ 0ul }; i < 1000000; ++i )
{
std::strcpy( dst.get(), src );
}

std::puts( dst.get() );

A for loop has been added to emphasize the performance difference between AddressSanitizer and Valgrind. In both cases, the code is compiled using the following command (running ASan also requires us to add -fsanitize=address):

clang++ example.cpp -g -o example.out

تكشف نظرة سريعة على الرسم البياني أدناه عن فجوة هائلة في الأداء بين Valgrind و ASan، وهذا هو السبب الذي قد يجعل الكثير من المطورين يترددون في استخدام هذه الأداة منذ البداية.

مقارنة جنبًا إلى جنب 

من أجل فهم أفضل للأخطاء التي يمكن لـ Valgrind وأدوات التنقية (sanitizers) اكتشافها، دعونا نلقي نظرة على الجدول التالي: 

* يكتشف MSan عمليات
قراءة الذاكرة غير المُهيأة** يكتشف UBSan السلوك غير المُعرَّف

As you can see, Valgrind won’t help you catch overflows in stack and global variables. This is because it only has access to the heap allocations performed by malloc function. Also, don’t count on it detecting any undefined behavior in your code — though you’ll get warned about trying to access memory that resulted from undefined behavior.  

وفي الوقت نفسه، فإن ASan ليست مثالية هي الأخرى. فهي لا تكتشف عمليات قراءة الذاكرة غير المُهيأة ولا السلوك غير المُعرَّف، في حين أن MSan وUBSan تقومان بذلك. 

«فالغريند» أم أدوات التنقية: أيهما ينبغي أن نستخدم؟

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

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

إذا كان لديك مشروع كبير بين يديك ولا تريد أن تقلق بشأن إعادة ترجمة الكود الخاص بك، فقد يكون استخدام Valgrind خيارًا أكثر منطقية. لقد وجدنا أنه مفيد بشكل خاص في تصحيح أخطاء المكتبات ذات المصدر المغلق واكتشاف مشكلات مثل أخطاء «الاستخدام بعد التحرير» (use-after-free) بسهولة أكبر. ومع ذلك، وبما أن أدوات التنقية (sanitizers) تتحسن باستمرار، فإننا نميل إلى تفضيلها على Valgrind.

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

اكتشف حلولنا

استكشاف حلولنا على بُعد نقرة واحدة فقط. جرّب منتجاتنا أو تحدث معنا مع أحد خبرائنا للتعمق أكثر في ما نقدمه.

المزيد من المعلومات

مواصلة القراءة

استكشاف المزيد
The New Authorization Problem Created by AI Agents 

The New Authorization Problem Created by AI Agents 

AI agents introduce a new wrinkle into digital trust: a legitimate user can direct a legitimate agent to take an action that…

اقرأ أكثر
ختام العام بالتطلع إلى المستقبل: لماذا أصبح المجتمع والتعاون أكثر أهمية من أي وقت مضى

ختام العام بالتطلع إلى المستقبل: لماذا أصبح المجتمع والتعاون أكثر أهمي…

مع اقتراب نهاية العام، وجدت نفسي أفكر في العوامل التي أحدثت فرقًا حقيقيًّا في عام 2025. ليس فقط من حيث التكنولوجيا أو مؤشرات…

اقرأ أكثر
لماذا يحتاج التحقق من الهوية إلى التحليلات، وليس الدقة فحسب 

لماذا يحتاج التحقق من الهوية إلى التحليلات، وليس الدقة فحسب 

لسنوات عديدة، ركزت المؤسسات التي تقيّم حلول التحقق من الهوية على مجموعة مألوفة من المعايير. فقد كانت معدلات الدقة، وتغطية الو…

اقرأ أكثر
لماذا يُحسّن التقاط الصور بدون إطار من أداء التحقق من صحة المستندات

لماذا يُحسّن التقاط الصور بدون إطار من أداء التحقق من صحة المستندات

لا تفشل عملية التحقق من الهوية بسبب عدم دقة الأنظمة. بل إنها تفشل عادةً لأن المستخدمين ينسحبون قبل أن يتمكن النظام من أداء مه…

اقرأ أكثر
لماذا يُعد كل من المقارنة المعيارية والقدرة على التفسير أمرين بالغين الأهمية في عملية التحقق من الهوية

لماذا يُعد كل من المقارنة المعيارية والقدرة على التفسير أمرين بالغين ا…

تناولت مدونة حديثة للرئيس التنفيذي لشركة Microblink، هارتلي طومسون، الكيفية التي يغير بها الذكاء الاصطناعي التوليدي (Gen AI)…

اقرأ أكثر
عندما تتصرف العناصر الذكية الاصطناعية (وربما تهاجم)

عندما تتصرف العناصر الذكية الاصطناعية (وربما تهاجم)

في الآونة الأخيرة، بدأ نوع جديد من القلق يظهر في أوساط التكنولوجيا. لا يتعلق الأمر بانتهاكات الأمن أو انقطاعات الخدمة، بل بال…

اقرأ أكثر
تقرير
تحديد ملامح تزايد حالات الاحتيال المتعلقة بالهوية المدعومة بالذكاء الاصطناعي

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

اطلع على البيانات