נעים להכיר: בודק הזיכרון

Kim-Anh Tran
Kim-Anh Tran

במאמר הזה נסביר על Memory Inspector, כלי שנוסף ל-Chrome בגרסה 91. הוא מאפשר לבדוק את ArrayBuffer,‏ TypedArray,‏ DataView ו-Wasm Memory.

מבוא

אי פעם רצית להבין את הנתונים ב-ArrayBuffer? לפני Memory Inspector, DevTools אפשרה רק תובנות מוגבלות לגבי ArrayBuffers. הבדיקה בתצוגה Scope במהלך סשן ניפוי באגים הייתה מוגבלת להצגת רשימה של ערכים בודדים במאגר המערך, ולכן היה קשה להבין את הנתונים כמכלול. לדוגמה, בתצוגה היקף, המאגר מוצג כטווחים של מערכי נתונים שניתן להרחיב, כפי שמוצג בדוגמה הבאה:

תצוגת ההיקף בכלי הפיתוח

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

בדיקת ערכים באמצעות בודק הזיכרון

בודק הזיכרון

ב-Chrome 91 אנחנו משיקים את Memory Inspector, כלי לבדיקת מאגרי מערכי נתונים. יכול להיות נתקלתם בעבר בכלים לבדיקת זיכרון כדי להציג נתונים בינאריים. הכלים האלה מציגים את התוכן הבינארי בתצוגת רשת עם הכתובות שלו, ומציעים דרכים שונות לפרש את הערכים הבסיסיים. זה מה שבודק הזיכרון מספק לכם. בעזרת Memory Inspector אפשר עכשיו להציג את התוכן, לנווט בו ולבחור את הסוגים שישמשו לפרשנות הערכים הקיימים. הוא מציג את ערכי ה-ASCII לצד הבייטים, ומאפשר למשתמש לבחור endianness שונה. בהמשך אפשר לראות את בודק הזיכרון בפעולה:

רוצה לנסות? במאמר המסמכים שלנו בנושא Memory Inspector מוסבר איך פותחים את Memory Inspector וצופים במאגר המערך (או ב-TypedArray, ב-DataView או ב-Wasm Memory), ומוסבר איך משתמשים בו. אפשר לנסות את זה בדוגמאות הקטנות האלה (ל-JS, ל-Wasm ול-C++).

תכנון הכלי לבדיקת זיכרון

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

יכול להיות שראיתם את הפוסט שלנו בבלוג בנושא מעבר לרכיבי Web, שבו Jack פרסם את המדריך הפנימי שלנו ליצירת רכיבי ממשק משתמש באמצעות רכיבי Web. המעבר לרכיבי Web התרחש במקביל לעבודה שלנו על Memory Inspector, ולכן החלטנו לנסות את המערכת החדשה. בתרשים הבא מוצגים הרכיבים שיצרנו כדי ליצור את Memory Inspector (לתשומת ליבכם: אנחנו קוראים לו Linear Memory Inspector בתוך החברה):

Web Components

הרכיב LinearMemoryInspector הוא הרכיב ההורה שמכיל את רכיבי המשנה שמרכיבים את כל הרכיבים ב-Memory Inspector. בעיקרון, הוא מקבל Uint8Array ו-address, ובכל שינוי באחד מהם הוא מעביר את הנתונים לצאצאים שלו, וכתוצאה מכך מתבצע עיבוד מחדש. ה-LinearMemoryInspector עצמו מניב שלושה רכיבי משנה:

  1. LinearMemoryViewer (הצגת הערכים),
  2. LinearMemoryNavigator (מתן הרשאה לניווט), וגם
  3. LinearMemoryValueInterpreter (הצגת פרשנויות מסוגים שונים של הנתונים הבסיסיים).

הרכיב האחרון הוא רכיב הורה שמרינדר את ValueInterpreterDisplay (הצגת הערכים) ואת ValueInterpreterSettings (בחירת הסוגים שיוצגו בתצוגה).

כל אחד מהרכיבים מיועד לייצג רק רכיב קטן אחד בממשק המשתמש, כך שאפשר יהיה לעשות שימוש חוזר ברכיבים במקרה הצורך. בכל פעם שמגדירים נתונים חדשים ברכיב, מתבצעת עיבוד מחדש (re-render) שמציג את השינוי שחל בנתונים שהוגדרו ברכיב. דוגמה אחת לתהליך עבודה עם הרכיבים שלנו מוצגת בהמשך. המשתמש משנה את הכתובת בסרגל הכתובות, מה שמפעיל עדכון על ידי הגדרת הנתונים החדשים, במקרה הזה הכתובת שרוצים להציג:

תרשים הרכיבים

ה-LinearMemoryInspector מוסיף את עצמו כמאזין ב-LinearMemoryNavigator. הפונקציה addressChanged מופעלת באירוע address-changed. ברגע שהמשתמש עורך את הקלט של הכתובת, המערכת שולחת את האירוע שצוין למעלה, כך שהפונקציה addressChanged נקראת. הפונקציה הזו שומרת עכשיו את הכתובת באופן פנימי ומעדכנת את רכיבי המשנה שלה באמצעות פונקציית setter של data(address, ..). רכיבי המשנה שומרים את הכתובת באופן פנימי ומריצים מחדש את הרינדור של התצוגות שלהם, כדי להציג את התוכן בכתובת הספציפית הזו.

יעד התכנון: ביצועיים ושימוש בזיכרון שאינם תלויים בגודל המאגר

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

כפי שראיתם בחלק הקודם, הרכיב LinearMemoryInspector מקבל UInt8Array כדי להציג את הערכים. יחד עם זאת, רצינו לוודא שבודק הזיכרון לא יצטרך לשמור את כל הנתונים, כי בודק הזיכרון מציג רק חלק מהם (למשל, זיכרון Wasm יכול להגיע לגודל של 4GB, ואנחנו לא רוצים לאחסן 4GB בתוך בודק הזיכרון).

לכן, כדי להבטיח שהמהירות והצריכה של זיכרון ב-Memory Inspector לא יהיו תלויים במאגר הזמני בפועל שאנחנו מציגים, אנחנו מאפשרים לרכיב LinearMemoryInspector לשמור רק טווח משנה של המאגר הזמני המקורי.

כדי שהפעולה הזו תפעל, קודם צריך להעביר ל-LinearMemoryInspector עוד שני ארגומנטים: memoryOffset ו-outerMemoryLength. השדה memoryOffset מציין את ההיסט, שבו מתחיל ה-Uint8Array שהוענק, והוא נדרש כדי להציג את כתובות הנתונים הנכונות. הערך outerMemoryLength הוא אורך המאגר הזמני המקורי, והוא נדרש כדי להבין איזה טווח נוכל להציג:

buffer

המידע הזה מאפשר לנו להבטיח שעדיין נוכל להציג את אותה תצוגה כמו קודם (התוכן שמסביב ל-address), גם אם לא כל הנתונים יהיו זמינים. מה עושים אם מבקשים כתובת אחרת שנכללת בטווח אחר? במקרה כזה, ה-LinearMemoryInspector מפעיל RequestMemoryEvent, שמעדכן את הטווח הנוכחי שנשמר. דוגמה מופיעה בהמשך:

תרשים זרימה של טריגרים לאירועים

בדוגמה הזו, המשתמש מנווט בדף הזיכרון (כלי Memory Inspector משתמש בחלוקה לדפים כדי להציג קטעי נתונים), מה שמפעיל אירוע PageNavigationEvent, שמפעיל בעצמו אירוע RequestMemoryEvent. האירוע הזה מתחיל את אחזור הטווח החדש, שמופץ לאחר מכן לרכיב LinearMemoryInspector באמצעות הגדרת הנתונים. כתוצאה מכך, אנחנו מציגים את הנתונים שאוחזרו לאחרונה.

אה, וידעתם? אפשר אפילו לבדוק את הזיכרון בקוד Wasm ובקוד C/C++

הכלי Memory Inspector זמין לא רק ל-ArrayBuffers ב-JavaScript, אלא גם לבדיקה של זיכרון Wasm וזיכרון שמפנים אליו הפניות/הצבעות של C/C++ (באמצעות התוסף DWARF שלנו – כדאי לנסות אותו אם עדיין לא עשיתם זאת). כאן מוסבר איך לנפות באגים ב-WebAssembly באמצעות כלים מודרניים. סקירה קצרה על Memory Inspector בפעולה לניפוי באגים מקורי של C++ באינטרנט:

בדיקת זיכרון ב-C++‎

סיכום

במאמר הזה הצגנו את Memory Inspector והראנו הצצה לתכנון שלו. אנחנו מקווים שכלי Memory Inspector יעזור לכם להבין מה קורה ב-ArrayBuffer שלכם :-). אם יש לכם הצעות לשיפור, נשמח לשמוע מכם ולשלוח דיווח על באג.

מורידים את הערוצים של התצוגה המקדימה.

מומלץ להשתמש ב-Chrome Canary, ב-Dev או ב-Beta כדפדפן הפיתוח שמוגדר כברירת מחדל. ערוצי התצוגה המקדימה האלה מעניקים לכם גישה לתכונות העדכניות ביותר של DevTools, מאפשרים לכם לבדוק ממשקי API מתקדמים לפלטפורמות אינטרנט ולמצוא בעיות באתר לפני שהמשתמשים שלכם יעשו זאת.

יצירת קשר עם צוות כלי הפיתוח ל-Chrome

אתם יכולים להשתמש באפשרויות הבאות כדי לדון בתכונות החדשות, בעדכונים או בכל דבר אחר שקשור ל-DevTools.