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

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

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

مقدمة

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

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

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

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

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

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

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

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

لا يقتصر دعم تمييز الكائنات على الصفائف. يمكنك أيضًا فحص البنى والكائنات والمؤشرات. هذه التغييرات تجعل استكشاف ذاكرة تطبيقات 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.

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

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

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

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

للاستفادة من الإمكانات الكاملة لتصحيح أخطاء 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 على الصفيف x. لا تغير هذه العمليات نوع الصفيف أو موضعه، لذا تظل مميزة.

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

الخاتمة

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

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

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