הרחבת 'בודק הזיכרון' לניפוי באגים ב-C/C++

בגרסה 92 של Chrome השקנו את בודק הזיכרון, כלי לבדיקת מאגרי זיכרון לינאריים. במאמר הזה נסביר איך שיפרנו את הכלי לניפוי באגים ב-C/C++ והאתגרים הטכניים שנתקלו לאורך הדרך.

ריכזנו כאן כמה פוסטים רלוונטיים בבלוגים, אם אתם משתמשים חדשים בניפוי באגים ב-C/C++ ובבודק הזיכרון:

מבוא

בודק הזיכרון מספק אפשרויות מתקדמות יותר לניפוי באגים במאגרי זיכרון לינאריים. במקרה של C/C++, אפשר לבדוק אובייקטים של זיכרון C/C++ בזיכרון WebAssembly.

קשה היה לזהות את הבייטים של האובייקט בתוך הזיכרון של WebAssembly שמסביב. צריך לדעת מה גודל האובייקט ולספור בייטים מתחילת האובייקט. בצילום המסך שלמטה, נבחר הבייט הראשון של מערך int32 עם 10 רכיבים, אבל לא ברור מיד אילו בייטים אחרים שייכים למערך. הייתם רוצים לדעת אם הייתם מזהים מיד את כל הבייטים ששייכים לאובייקט?

צילום מסך של בודק הזיכרון המקורי עם בייט מודגש אחד

הדגשת אובייקטים ב'בודק הזיכרון'

החל מגרסה 107 של Chrome, כל הבייטים של אובייקט זיכרון C/C++ מודגשים בבודק הזיכרון. כך תוכלו להבדיל ביניהם מהזיכרון שמסביב.

צילום מסך של בודק הזיכרון המעודכן, עם מערך מודגש בצבעים מלאי חיים

צפו בסרטון שבהמשך כדי לראות את בודק הזיכרון בפעולה. כשחושפים את המערך x ב'בודק הזיכרון', זיכרון מודגש מופיע ב'מציג הזיכרון' עם צ'יפ חדש מעליו. הצ'יפ הזה מזכיר את השם והסוג של הזיכרון המודגש. לוחצים על הצ'יפ כדי לדלג לזיכרון של האובייקט. אם מעבירים את העכבר מעל הצ'יפ, מופיע סמל צלב – לוחצים עליו כדי להסיר את ההדגשה.

כשבוחרים בייט מחוץ לאובייקט שבודקים, ההדגשה נעלמת כדי לא להסיח את הדעת. כדי למקד אותו מחדש שוב, לוחצים שוב על אחד מהבייטים או על הצ'יפ של האובייקט.

התמיכה בהדגשת אובייקטים לא מוגבלת למערכים. אפשר גם לבדוק מבני, אובייקטים ומצביעים. עם השינויים האלה, קל יותר מתמיד לגלות את הזיכרון של אפליקציות C/C++ !

רוצה לנסות? צריך לבצע את הפעולות הבאות:

  • דפדפן Chrome מגרסה 107 ואילך.
  • מתקינים את התוסף 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;
}

המתכנת עובר לבודק הזיכרון כדי לנפות את הבאגים שגרמו לבעיה. אפשר לעקוב אחר ההדגמה הזו! קודם כל הם בודקים את המערך ב-Memory Inspector כדי לראות שהמערך numbers מכיל רק את המספרים השלמים 1, 2, 3 ו-4, כצפוי.

צילום מסך של בודק הזיכרון פתוח עם מערך int32 נבדק. כל רכיבי המערך מודגשים.

בשלב הבא, הם חושפים את המשתנה lastNumber מהחלונית Scope, ומראים שהסמן מפנה למספר שלם מחוץ למערך! הודות לידע הזה, המתכנת מבין שהוא סופר באופן שגוי את היסט המצביע בשורה 8. השעה הייתה צריכה להיות ptr + arraySize - 1.

צילום מסך של בודק הזיכרון פתוח, שבו מוצג זיכרון מודגש שמצביע פונה אליו בשם &#39;lastNumber&#39;. הזיכרון המודגש נמצא מיד אחרי הבייט האחרון של המערך המודגש.

זוהי דוגמה לצעצוע, אבל היא ממחישה איך הדגשת אובייקטים מעבירה ביעילות את הגודל והמיקום של האובייקטים בזיכרון, וכך עוזרת להבין טוב יותר מה קורה בזיכרון של אפליקציית C/C++.

איך כלי הפיתוח קובעים מה כדאי להדגיש

בקטע הזה נבחן את הסביבה העסקית של הכלים שמאפשרים ניפוי באגים ב-C/C++. נסביר באופן ספציפי איך כלי הפיתוח, V8, תוסף C/C++ DWARF ו-Emscripten מאפשרים לניפוי באגים של C/C++ ב-Chrome.

כדי ליהנות מכל היתרונות של ניפוי הבאגים ב-C/C++ בכלי הפיתוח, צריך לבצע שני דברים:

  • תוסף C/C++ DWARF שמותקן ב-Chrome
  • קובצי מקור מסוג C/C++ שעברו הידור ל-WebAssembly באמצעות המהדר האחרון של Emscripten, כפי שמוסבר בפוסט בבלוג

אבל למה? V8 , מנוע WebAssembly ו-JavaScript של 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 ועל התוסף של המשתנה שמשויך להדגשה הקודמת. לאחר מכן מתבצעת השוואה בין המיקומים והסוגים של האובייקטים. אם הם תואמים, ההדגשה תישאר. בסרטון שלמעלה, יש כתיבה מסוג 'לופ' למערך x. הפעולות האלו לא משנות את הסוג או את המיקום של המערך, ולכן הוא נשאר מודגש.

יכול להיות שתהיתם איך זה משפיע על המצביעים. אם יש לכם מצביע מודגש והקציתם אותו מחדש לאובייקט אחר, המיקומים הישנים והחדשים של האובייקטים המודגשים יהיו שונים וההדגשה תיעלם. מכיוון שהאובייקט החדש שמצביע עליו יכול להיות בכל מקום בזיכרון WebAssembly וסביר להניח שיש לו מעט מאוד קשר למיקום הזיכרון הקודם, הסרת ההדגשה ברורה יותר מדילוג למיקום זיכרון חדש. כדי להדגיש את מיקום הסמן שוב, לוחצים על סמל הזיכרון שלו בחלונית היקף.

סיכום

במאמר הזה נתאר את השיפורים שלנו בכלי לבדיקת זיכרון לניפוי באגים ב-C/C++. אנחנו מקווים שהתכונות החדשות יפשטו את ניפוי הבאגים בזיכרון של אפליקציות C/C++ . אם יש לך הצעות לשיפור נוסף, אפשר להודיע לנו על ידי דיווח על באג.

מה השלב הבא?

מידע נוסף זמין במאמרים הבאים: