توسيع "أداة فحص الذاكرة" لتصحيح الأخطاء عبر بروتوكول C/C++

في الإصدار 92 من Chrome، قدّمنا أداة فحص الذاكرة، وهي أداة لفحص المخازن المؤقتة الخطية للذاكرة. في هذه المقالة، سنناقش كيفية تحسين "أداة الفحص" لتصحيح أخطاء C/C++ والتحدّيات الفنية التي واجهناها في هذه العملية.

في ما يلي بعض المشاركات ذات الصلة في المدونات إذا كنت مبتدئًا في تصحيح أخطاء C/C++ واستخدام أداة فحص الذاكرة:

مقدمة

تزوِّدك أداة فحص الذاكرة بخيارات أكثر فعالية لتصحيح الأخطاء في المخازن المؤقتة الخطية للذاكرة. في حالة استخدام C/C++، يمكنك فحص كائنات ذاكرة C/C++ في ذاكرة WebAssembly Memory.

كان من الصعب التعرّف على وحدات البايت الخاصة بالكائن بين ذاكرة WebAssembly المحيطة. يجب معرفة حجم العنصر واحتساب عدد البايتات من بداية العنصر. في لقطة الشاشة أدناه، تم اختيار البايت الأول من مصفوفة int32 المكوّنة من 10 عناصر، ولكن ليس من الواضح على الفور أي وحدات البايت الأخرى التي تنتمي إلى المصفوفة. ألن يكون من الأفضل التعرّف فورًا على جميع وحدات البايت التي تخص الكائن؟

لقطة شاشة لأداة فحص الذاكرة الأصلية تتضمّن بايت واحد مميّز

تمييز العناصر في "أداة فحص الذاكرة"

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

لقطة شاشة لمدقّق الذاكرة المعدَّل مع صفيف مميّز بألوان زاهية

يمكنك مشاهدة الفيديو أدناه لمعرفة كيفية استخدام أداة فحص الذاكرة. عند الكشف عن الصفيف x في أداة "فحص الذاكرة"، تظهر الذاكرة المميّزة في "عارض الذاكرة" مع شريحة جديدة فوقها مباشرةً. تذكّرك هذه الشريحة باسم الذكرى المميّزة ونوعها. انقر على الشريحة للانتقال إلى ذاكرة العنصر. إذا مرّرت مؤشّر الماوس فوق الشريحة، سيظهر رمز متقاطع، انقر عليه لإزالة التمييز.

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

لا يقتصر خيار تمييز العناصر على الصفائف. يمكنك أيضًا فحص البنى والعناصر والمؤشرات. تسهّل هذه التغييرات استكشاف ذاكرة تطبيقات C/C++ أكثر من أي وقت مضى.

هل تريد تجربتها؟ عليك إجراء ما يلي:

  • استخدام الإصدار 107 من Chrome أو إصدار أحدث
  • ثبِّت إضافة C/C++ DWARF.
  • تفعيل تصحيح أخطاء DWARF في DevTools > الإعدادات. الإعدادات > التجارب > تصحيح أخطاء WebAssemble: تفعيل دعم DWARF
  • افتح صفحة العرض التوضيحي هذه.
  • اتّبِع التعليمات الواردة في الصفحة.

مثال على تصحيح الأخطاء

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

#include <iostream>

int main()
{
    int numbers[] = {1, 2, 3, 4};
    int *ptr = numbers;
    int arraySize = sizeof(numbers)/sizeof(int);
    int* lastNumber = ptr + arraySize;  // Can you notice the bug here?
    std::cout <<../ *lastNumber <<../ '\n';
    return 0;
}

يلجأ المبرمج إلى أداة فحص الذاكرة لتصحيح أخطاء المشكلة. يمكنك متابعة هذا العرض التوضيحي. يفحصون أولاً الصفيف في أداة فحص الذاكرة ويرى أنّ مصفوفة numbers تحتوي فقط على الأعداد الصحيحة 1 و2 و3 و4، على النحو المتوقّع.

لقطة شاشة لأداة فحص الذاكرة المفتوحة مع صفيف int32 تم فحصه يتم تمييز جميع عناصر الصفيفة.

بعد ذلك، يكشفان عن المتغيّر lastNumber من جزء النطاق ويلاحظان أنّ المؤشر يشير إلى عدد صحيح خارج المصفوفة. بعد الاطّلاع على هذه المعلومات، أدرك المبرمج أنّه أحصى بشكل خاطئ إزاحة المؤشر في السطر 8. كان من المفترض أن تكون الساعة ptr + arraySize - 1.

لقطة شاشة لأداة فحص الذاكرة المفتوحة تعرِض الذاكرة المميّزة التي يشير إليها مؤشر باسم lastNumber. تقع الذاكرة المميّزة مباشرةً بعد البايت الأخير من الصفيف المميّز سابقًا.

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

كيفية تحديد "أدوات مطوّري البرامج" لما يجب تسليط الضوء عليه

في هذا القسم، سنلقي نظرة على منظومة الأدوات التي تتيح تصحيح أخطاء C/C++. وبشكل أكثر تحديدًا، ستتعرّف على كيفية استخدام أدوات المطوّرين وV8 وC/C++ DWARF Extension وEmscripten لتصحيح أخطاء C/C++ في Chrome.

للاستفادة من الإمكانات الكاملة لتصحيح أخطاء C/C++ في "أدوات مطوّري البرامج"، عليك إجراء أمرَين:

  • تثبيت إضافة DWARF C/C++ في Chrome
  • ملفات مصدر C/C++ التي تم تجميعها إلى WebAssembly باستخدام أحدث إصدار من مُجمِّع Emscripten وفقًا للتعليمات الواردة في هذه المشاركة في المدونة

ولكن لماذا؟ لا يعرف V8، وهو محرّك JavaScript وWebAssembly في Chrome، كيفية تنفيذ C أو C++. وبفضل Emscripten، وهو مُجمِّع لتحويل C/C++ إلى WebAssembly، يمكنك تجميع التطبيقات المُنشأة بلغة C أو C++ كتطبيقات WebAssembly وتنفيذها في المتصفّح.

أثناء التحويل البرمجي، سيتضمن برنامج emscripten بيانات تصحيح أخطاء DWARF في برنامجك الثنائي. على مستوى عالٍ، تساعد هذه البيانات الإضافة في معرفة متغيرات WebAssembly التي تتوافق مع متغيرات C/C++ الخاصة بك، وأكثر من ذلك. بهذه الطريقة، يمكن أن تعرض لك "أدوات مطوري البرامج" متغيّرات C++ على الرغم من أنّ V8 يشغّل WebAssembly. للاطّلاع على مثال لبيانات تصحيح الأخطاء في DWARF، يمكنك الاطّلاع على مشاركة المدونة هذه.

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

إذا نظرت إلى lastNumber في المثال السابق، قد تلاحظ أنّنا فحَصنا lastNumber: int *، ولكن الشريحة في أداة فحص الذاكرة تعرض الحالة *lastNumber: int، فما السبب؟ يستخدم المفتش أسلوب C++ لإزالة الإشارة إلى المؤشر للإشارة إلى نوع العنصر المعروض لك. إذا فحصت مؤشرًا، سيعرض لك المفتش ما يشير إليه.

الاحتفاظ بالعناصر المميّزة في خطوات مصحِّح الأخطاء

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

عندما يصل برنامج تصحيح الأخطاء إلى نقطة فاصلة جديدة، يطلب أداة فحص الذاكرة مرة أخرى V8 والإضافة الخاصة بالمتغيّر المرتبط بالتمييز السابق. بعد ذلك، تتم مقارنة المواقع الجغرافية للعناصر وأنواعها. إذا تطابقا، يستمر التمييز. في الفيديو أعلاه، هناك حلقة for-loop تكتب في الصفيف x. لا تغيّر هذه العمليات نوع الصفيف أو موضعه، لذا يبقى مميّزًا.

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

الخاتمة

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

الخطوات التالية

لمزيد من المعلومات، يُرجى الاطّلاع على: