הבנת דוחות HWASan

כאשר הכלי HWASan מזהה באג זיכרון, התהליך מסתיים עם abort(), ודוח מודפס ל-stderr ול-logcat. כמו כל קריסות מקוריות באנדרואיד, ניתן למצוא שגיאות HWASan תחת /data/tombstones .

בהשוואה לקריסות מקומיות רגילות, HWASan נושא מידע נוסף בשדה "הודעת ביטול" ליד החלק העליון של המצבה. ראה התרסקות לדוגמה המבוססת על ערימה למטה (עבור באגים מחסנית, ראה את ההערה למטה עבור הסעיפים הספציפיים לחסימה).

דוח לדוגמה

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/flame_hwasan/flame:Tiramisu/MASTER/7956676:userdebug/dev-keys'
Revision: 'DVT1.0'
ABI: 'arm64'
Timestamp: 2019-04-24 01:13:22+0000
pid: 11154, tid: 11154, name: sensors@1.0-ser  >>> /vendor/bin/hw/android.hardware.sensors@1.0-service <<<
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
Abort message: '

[...]

[0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5








[ … regular crash dump follows …]

זה דומה מאוד לדוח AddressSnitizer . בניגוד לאלה, כמעט כל הבאגים של HWASan הם "אי-התאמה בתג", כלומר גישה לזיכרון שבה תג מצביע אינו תואם לתג הזיכרון המתאים. זה יכול להיות אחד מהם

  • גישה מחוץ לתחום בערימה או ערימה
  • השתמש לאחר חינם בערימה
  • שימוש לאחר החזרה על הערימה

מקטעים

להלן הסבר על כל אחד מהסעיפים בדוח HWAsan:

שגיאת גישה

מכיל מידע על הגישה השגויה לזיכרון, כולל:

  • סוג גישה ("READ" לעומת "WRITE")
  • גודל גישה (לכמה בתים ניסו לגשת)
  • מספר השרשור של הגישה
  • מצביע ותגי זיכרון (לניפוי באגים מתקדם)

גישה ל-Stack Trace

עקבות מחסנית של הגישה השגויה לזיכרון. עיין בסעיף סימבוליזציה לסמל.

גורם

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

  • שימוש-לאחר-חינם
  • מחסנית תג-אי-התאמה: זה יכול להיות שימוש במחסנית-אחר-החזרה / שימוש לאחר-היקף, או מחוץ לתחום
  • ערימה-חיץ-הצפה
  • גלישה גלובלית

מידע זיכרון

מתאר את מה ש-HWASan יודע על הזיכרון שאליו ניגשים, ועשוי להשתנות בהתאם לסוג הבאג.

סוג באג גורם פורמט דוח
תג-אי התאמה שימוש-לאחר-חינם
<address> is located N bytes inside of M-byte region [<start>, <end>)
  freed by thread T0 here:
ערימה-חיץ-הצפה שימו לב שזה יכול להיות גם זרימה נמוכה.
<address> is located N bytes to the right of M-byte region [<start>, <end>)
  allocated here:
חוסר התאמה של תג מחסנית דוחות מחסנית אינם מבדילים בין באגים של הצפת/יתר ובאגים של שימוש לאחר החזרה. בנוסף, כדי למצוא את הקצאת המחסנית שהיא מקור השגיאה, נדרש שלב סימבול לא מקוון. עיין בסעיף הבנת דוחות מחסנית למטה.
פסול ללא תוקף שימוש-לאחר-חינם זהו באג חינמי כפול. אם זה קורה בזמן כיבוי התהליך, זה יכול להעיד על הפרת ODR .
<address> is located N bytes inside of M-byte region [<start>, <end>)
  freed by thread T0 here:
לא יכול לתאר כתובת או פנוי פראי (ללא זיכרון שלא הוקצה קודם לכן), או פנוי כפול לאחר שהזיכרון שהוקצה הוצא מהמאגר הפנוי של HWASan.
0x... הוא HWAsan זיכרון צל. זה בהחלט חינמי פראי, מכיוון שהאפליקציה ניסתה לשחרר זיכרון שהוא פנימי ל-HWASan.

מעקב מחסנית ביטול ההקצאה

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

מעקב מחסנית הקצאה

עקבות מחסנית של המקום שבו הוקצה הזיכרון. ראה סעיף סימבוליזציה לסמל.

מידע ניפוי באגים מתקדם

דוח HWASan כולל גם מידע מתקדם של ניפוי באגים, כולל (לפי הסדר):

  1. רשימת השרשורים בתהליך
  2. רשימת השרשורים בתהליך
  3. הערך של תגי הזיכרון ליד הזיכרון התקול
  4. ה-dump של הרגיסטרים בנקודת הגישה לזיכרון

זיכרון תג dump

ניתן להשתמש ב-Tag memory dump כדי לחפש הקצאות זיכרון בקרבת מקום עם תג זהה לתג המצביע. אלה יכולים להצביע על גישה מחוץ לתחום עם היסט גדול. תג אחד מתאים ל-16 בתים של זיכרון; תג המצביע הוא 8 הביטים העליונים של הכתובת. dump הזיכרון של התגים יכול לתת רמזים, לדוגמה, הדבר הבא הוא גלישת מאגר מימין:

tags: ad/5c (ptr/mem)
[...]
Memory tags around the buggy address (one tag corresponds to 16 bytes):
  0x006f33ae1ff0: 0e  0e  0e  57  20  20  20  20  20  2e  5e  5e  5e  5e  5e  b5
=>0x006f33ae2000: f6  f6  f6  f6  f6  4c  ad  ad  ad  ad  ad  ad [5c] 5c  5c  5c
  0x006f33ae2010: 5c  04  2e  2e  2e  2e  2e  2f  66  66  66  66  66  80  6a  6a
Tags for short granules around the buggy address (one tag corresponds to 16 bytes):
  0x006f33ae1ff0: ab  52  eb  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
=>0x006f33ae2000: ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  .. [..] ..  ..  ..
  0x006f33ae2010: ..  5c  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
(שים לב לריצה של 6 × 16 = 96 בתים של תגי "מודעה" משמאל התואמים לתג המצביע).

אם הגודל של הקצאה אינו כפולה של 16, שאר הגודל יישמר כתג הזיכרון והתג יאוחסן כתג גרגיר קצר . בדוגמה שלמעלה ממש אחרי המודעה המתויגת בהקצאה מודגשת, יש לנו הקצאה של 5 × 16 + 4 = 84 בתים של תג 5c.

תג זיכרון אפס (לדוגמה tags: ad/ 00 (ptr/mem) ) מציין בדרך כלל באג של שימוש במחסנית לאחר החזרה.

הרשמה dump

dump האוגר בדוחות HWASan תואם את ההוראה בפועל שביצעה את הגישה הלא חוקית לזיכרון. אחריו מופיעה עוד dump של רישום ממטפל האותות הרגיל של אנדרואיד - התעלם מהשני , הוא נלקח כאשר HWASan קרא abort() ואינו רלוונטי לבאג.

סימבוליזציה

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

התקנה בפעם הראשונה: התקן את llvm-symbolizer

כדי לסמל, על המערכת שלך להיות מותקן llvm-symbolizer ונגיש מ-$PATH. בדביאן, אתה יכול להתקין אותו באמצעות sudo apt install llvm .

השג קבצי סמלים

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

עבור מבנים מקומיים , ניתן למצוא את קובצי הסמלים ב- out/target/product/<product>/symbols/ .

עבור בניית AOSP (למשל, הבזק מ- Flashstation ), ניתן למצוא את ה-buildות ב- Android CI . ב-"Artifacts" עבור ה-build, יהיה קובץ `${PRODUCT}-symbols-${BUILDID}.zip`.

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

לְסַמֵל

hwasan_symbolize –-symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash

הבנת דוחות מחסנית

עבור באגים המתרחשים עם משתני מחסנית, דוח HWASan יכיל פרטים כמו זה:

Cause: stack tag-mismatch
Address 0x007d4d251e80 is located in stack of thread T64
Thread: T64 0x0074000b2000 stack: [0x007d4d14c000,0x007d4d255cb0) sz: 1088688 tls: [0x007d4d255fc0,0x007d4d259000)
Previously allocated frames:
  record_addr:0x7df7300c98 record:0x51ef007df3f70fb0  (/apex/com.android.art/lib64/libart.so+0x570fb0)
  record_addr:0x7df7300c90 record:0x5200007df3cdab74  (/apex/com.android.art/lib64/libart.so+0x2dab74)
  [...]
	

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

הפרות ODR

כמה באגים שדווחו על ידי HWASan שדווחו על ידי HWASan יכולים גם להצביע על הפרה של כלל הגדרה אחת (ODR). הפרת ODR מתרחשת כאשר אותו משתנה מוגדר מספר פעמים באותה תוכנית. זה גם אומר שהמשתנה מושמד מספר פעמים, מה שעלול להוביל לשגיאה לאחר השימוש.

לאחר סימבוליזציה, הפרות ODR מציגות שימוש-אחרי-חופשי עם __cxa_finalize , הן בערימת הגישה הלא חוקית והן בערימת "החופשה כאן". המחסנית "קודם לכן הוקצה כאן" מכילה __dl__ZN6soinfo17call_constructorsEv וצריכה להצביע על המיקום בתוכנית שלך שמגדיר את המשתנה הגבוה יותר בערימה.

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

פתרון תקלות

"HWAddressSanitizer לא יכול לתאר כתובת ביתר פירוט."

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

  HWAddressSanitizer can not describe address in more detail.

במקרים מסוימים ניתן לפתור זאת על ידי הפעלת הבדיקה מספר פעמים. אפשרות נוספת היא להגדיל את גודל ההיסטוריה של HWASan. ניתן לעשות זאת באופן גלובלי ב- build/soong/cc/sanitize.go (חפש את hwasanGlobalOptions ), או בסביבת התהליך שלך (נסה adb shell echo $HWASAN_OPTIONS כדי לראות את ההגדרות הנוכחיות).

זה יכול לקרות גם אם הזיכרון שנגיש אליו אינו ממופה, או מוקצה על ידי מקצה שאינו מודע ל-HWASan. במקרה זה, תג mem המופיע בכותרת הקריסה יהיה בדרך כלל 00 . אם יש לך גישה למצבה המלאה, אולי יעזור לך להתייעץ עם dump מפות הזיכרון כדי לגלות לאיזה מיפוי (אם בכלל) שייכת הכתובת.

"באג מקונן באותו שרשור"

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