في الإصدار 92 من Chrome، طرحنا أداة فحص الذاكرة، وهي أداة لفحص مخازن الذاكرة الخطية المؤقتة. في هذه المقالة، سنناقش كيفية تحسين "المدقّق" لتصحيح أخطاء C/C++ والتحدّيات الفنية التي واجهناها في هذه العملية.
في ما يلي بعض المشاركات ذات الصلة في المدونات إذا كنت مبتدئًا في تصحيح أخطاء C/C++ واستخدام أداة فحص الذاكرة:
- هل يهمّك تصحيح أخطاء الذاكرة بشكل معمّق؟ اطّلِع على لمحة عن "أداة فحص الذاكرة".
- هل تريد الحصول على مقدمة عن مجموعة أدوات تصحيح أخطاء C/C++ الكاملة؟ اطّلِع على مقالتَي تصحيح أخطاء WASM باستخدام أدوات حديثة وتصحيح أخطاء WebAssembly بشكل أسرع.
مقدمة
يوفّر لك أداة فحص الذاكرة خيارات تصحيح أخطاء أكثر فعالية لمخازن الذاكرة الخطية المؤقتة. في حال استخدام C/C++، يمكنك فحص عناصر ذاكرة C/C++ في ذاكرة WebAssembly.
كان من الصعب التعرّف على وحدات البايت الخاصة بالكائن بين ذاكرة WebAssembly المحيطة. يجب معرفة حجم العنصر واحتساب عدد البايتات من بداية العنصر. في لقطة الشاشة أدناه، تم اختيار البايت الأول من صفيف int32
يتألف من 10 عناصر، ولكن ليس من الواضح على الفور البايتات الأخرى التي تنتمي إلى الصفيف. أليس من الرائع أن تتمكّن من التعرّف على الفور على جميع البايتات التي تنتمي إلى العنصر؟
تمييز العناصر في "أداة فحص الذاكرة"
بدءًا من الإصدار 107 من Chrome، يُبرز أداة فحص الذاكرة جميع وحدات البايت الخاصة بعنصر ذاكرة C/C++. ويساعدك ذلك في تمييزها عن الذكريات المحيطة بها.
يمكنك مشاهدة الفيديو أدناه للاطّلاع على أداة فحص الذاكرة أثناء استخدامها. عند الكشف عن الصفيف x
في أداة "فحص الذاكرة"، تظهر الذاكرة المميّزة في "عارض الذاكرة" مع شريحة جديدة فوقها مباشرةً. تذكّرك هذه الشريحة باسم الذاكرة المميّزة ونوعها. انقر على الشريحة للانتقال إلى ذاكرة العنصر. إذا مرّرت مؤشر الماوس فوق الشريحة، سيظهر رمز صليب. انقر عليه لإزالة التمييز.
عند اختيار بايت خارج العنصر الذي تفحصه، يتم إيقاف تمييزه لتجنُّب تشتيت انتباهك. لإعادة التركيز مرة أخرى، انقر على أي من وحدات البايت الخاصة بالكائن أو على الشريحة مرة أخرى.
لا يقتصر خيار تمييز العناصر على الصفائف. يمكنك أيضًا فحص البنى والعناصر والمؤشرات. تسهّل هذه التغييرات استكشاف ذاكرة تطبيقات C/C++ أكثر من أي وقت مضى.
هل تريد تجربة ذلك؟ عليك إجراء ما يلي:
- استخدام الإصدار 107 من Chrome أو إصدار أحدث
- ثبِّت إضافة C/C++ DWARF.
- فعِّل تصحيح أخطاء DWARF في أدوات مطوّري البرامج > الإعدادات > التجارب > تصحيح أخطاء 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
، كما هو متوقّع.
بعد ذلك، يكشفون عن المتغيّر lastNumber
من لوحة النطاق ويلاحظون أنّ المؤشر يشير إلى عدد صحيح خارج الصفيف. بعد الاطّلاع على هذه المعلومات، أدرك المبرمج أنّه أحصى بشكل خاطئ إزاحة المؤشر في السطر 8. من المفترض أن يكون ptr + arraySize - 1
.
على الرغم من أنّ هذا مثال بسيط، إلا أنّه يوضّح كيف ينقل تمييز العناصر حجم عناصر الذاكرة وموقعها بفعالية، ما يمكن أن يساعدك في فهم ما يحدث داخل ذاكرة تطبيق C/C++ بشكل أفضل.
كيفية تحديد "أدوات مطوّري البرامج" للعناصر التي يجب تمييزها
في هذا القسم، سنلقي نظرة على منظومة الأدوات التي تتيح تصحيح أخطاء C/C++. وبشكل أكثر تحديدًا، ستتعرّف على كيفية استخدام أدوات المطوّرين وV8 وC/C++ DWARF Extension وEmscripten لتصحيح أخطاء C/C++ في Chrome.
للاستفادة من الإمكانات الكاملة لتصحيح أخطاء C/C++ في "أدوات مطوّري البرامج"، عليك إجراء أمرَين:
- إضافة C/C++ DWARF المثبَّتة في Chrome
- ملفات مصدر C/C++ التي تم تجميعها إلى WebAssembly باستخدام أحدث إصدار من مُجمِّع Emscripten وفقًا للتعليمات الواردة في هذه المشاركة في المدونة
ولكن لماذا؟ لا يعرف V8، وهو محرّك JavaScript وWebAssembly في Chrome، كيفية تنفيذ C أو C++. وبفضل Emscripten، وهو مُجمِّع لتحويل C/C++ إلى WebAssembly، يمكنك تجميع التطبيقات المُنشأة بلغة C أو C++ كتطبيقات WebAssembly وتنفيذها في المتصفّح.
أثناء عملية الترجمة، سيضمِّن emscripten بيانات تصحيح أخطاء DWARF في ملفك الثنائي. على مستوى عالٍ، تساعد هذه البيانات الإضافة في معرفة متغيّرات WebAssembly التي تتوافق مع متغيّرات C/C++ وغيرها. بهذه الطريقة، يمكن لأداة DevTools عرض متغيّرات C++ على الرغم من أنّ V8 يشغّل WebAssembly. إذا كنت مهتمًا، يمكنك الاطّلاع على مشاركة المدوّنة هذه للحصول على مثال على بيانات تصحيح الأخطاء في DWARF.
ماذا يحدث عند الكشف عن lastNumber
؟ بعد النقر على رمز الذاكرة، تتحقّق "أدوات مطوّري البرامج" من المتغيّر الذي تريد فحصه. بعد ذلك، يطلب من الإضافة نوع البيانات وموقع lastNumber
الجغرافي. بعد أن تستجيب الإضافة بهذه المعلومات، يمكن لأداة Memory Inspector عرض الشريحة ذات الصلة من الذاكرة ومعرفة نوعها، ويمكنها أيضًا عرض حجم العنصر.
إذا اطّلعت على lastNumber
في المثال السابق، قد تلاحظ أنّنا فحصنا lastNumber: int *
، ولكنّ الشريحة في أداة فحص الذاكرة تعرض *lastNumber: int
. ما الذي يحدث؟ يستخدم المفتش أسلوب C++ لإزالة الإشارة إلى المؤشر للإشارة إلى نوع العنصر المعروض لك. إذا فحصت مؤشرًا، سيعرض لك المفتش ما يشير إليه.
الاحتفاظ بالعناصر المميّزة في خطوات مصحِّح الأخطاء
عند عرض عنصر في أداة فحص الذاكرة والانتقال باستخدام أداة تصحيح الأخطاء، تُبقي أداة الفحص العنصر مميّزًا إذا كانت تعتقد أنّه لا يزال ذا صلة. لم تكن هذه الميزة مضمّنة في خطّتنا في البداية، ولكن سرعان ما تبيّن لنا أنّ ذلك يؤثر سلبًا في تجربة تصحيح الأخطاء. تخيل أنّك بحاجة إلى إعادة فحص الصفيف بعد كل خطوة كما هو موضّح في الفيديو أدناه.
عندما يصل مصحِّح الأخطاء إلى نقطة توقّف جديدة، يُجري مدقّق الذاكرة طلب بحث مرة أخرى في V8 والإضافات للمتغيّر المرتبط بالتمييز السابق. بعد ذلك، تتم مقارنة المواقع الجغرافية للعناصر وأنواعها. في حال تطابقهما، يستمر تمييزها. في الفيديو أعلاه، هناك حلقة for-loop تكتب في الصفيف x
. لا تغيّر هذه العمليات نوع الصفيف أو موضعه، لذا يبقى مميّزًا.
قد تتساءل عن كيفية تأثير ذلك في المؤشرات. إذا كان لديك مؤشر مميّز وأعدته إلى عنصر مختلف، يختلف موضع العناصر المميّزة القديم والجديد، ويختفي التمييز. بما أنّ الكائن الذي يتم الإشارة إليه حديثًا يمكن أن يظهر في أي مكان في ذاكرة WebAssembly ومن المرجّح أن يكون له صلة قليلة بالموقع السابق للذاكرة، فإنّ إزالة التمييز أكثر وضوحًا من الانتقال إلى موقع جديد في الذاكرة. يمكنك تمييز المؤشر مرة أخرى من خلال النقر على رمز الذاكرة في لوحة النطاق.
الخاتمة
توضّح هذه المقالة التحسينات التي أجريناها على أداة "فحص الذاكرة" لتصحيح أخطاء C/C++. نأمل أن تسهّل الميزات الجديدة تصحيح أخطاء ذاكرة تطبيقات C/C++. إذا كانت لديك اقتراحات لتحسينها، يُرجى إعلامنا بها من خلال الإبلاغ عن خطأ.
الخطوات التالية
لمزيد من المعلومات، يُرجى الاطّلاع على: