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