קריאה של דוחות איתור באגים

באגים קיימים בכל סוג של פיתוח — ודיווח על באגים חיוניים לזיהוי בעיות ולפתרון שלהן. כל גרסאות התמיכה ב-Android יצירת דוחות על באגים באמצעות Android Debug Bridge (adb); גרסאות Android 4.2 ואילך תומכות מפתח אפשרות לדיווח על באגים ושיתוף באימייל, ב-Drive וכו'.

דוחות איתור באגים ב-Android מכילים את dumpsys, dumpstate וגם נתוני logcat בפורמט טקסט (.txt), כדי לאפשר לך לחפש בקלות לתוכן ספציפי. בקטעים הבאים תמצאו פירוט של רכיבי דוח איתור הבאגים, מתארים בעיות נפוצות ונותנים טיפים מועילים ופקודות grep למציאת יומנים שקשורים לבאגים האלה. רוב הקטעים כוללים גם דוגמאות לפקודה והפלט של grep ו/או לפלט dumpsys.

Logcat

היומן logcat הוא תמונת מצב מבוססת-מחרוזת של כל logcat מידע. החלק של המערכת שמור ל-framework, יש היסטוריה ארוכה יותר מההיסטוריה הראשית, שמכילה את כל השאר. כל שורה מתחילה בדרך כלל ב-timestamp UID PID TID log-level, אם כי יכול להיות ש-UID לא מופיע בגרסאות ישנות של Android.

הצגת יומן האירועים

היומן הזה מכיל ייצוגי מחרוזות של הודעות יומן בפורמט בינארי. הוא פחות רועשת מיומן logcat, אבל גם קצת יותר קשה לקרוא אותו. כשמציגים יומני אירועים, אפשר לחפש בקטע הזה מזהה תהליך ספציפי (PID) כדי לבדוק איזה תהליך בוצע. הפורמט הבסיסי הוא: timestamp PID TID log-level log-tag tag-values

רמות היומן כוללות את הפרטים הבאים:

  • V: דרגת מלל
  • ד: ניפוי באגים
  • I: מידע
  • W: אזהרה
  • ה: שגיאה

 

לתגים שימושיים נוספים של יומן אירועים, ראו /services/core/java/com/android/server/EventLogTags.logtags.

מקרי ANR ותקלות ללא הפרעות

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

זיהוי אפליקציות שלא מגיבות

כשאפליקציה לא מגיבה בתוך פרק זמן מסוים, בדרך כלל עקב ה-thread הראשי חסום או עמוס, המערכת קוטעת את התהליך ומעבירה את הערימה /data/anr כדי לגלות מהו מקור הבעיה ב-ANR, צריך להגדיר am_anr ביומן האירועים הבינארי.

אפשר גם gRep עבור ANR in ביומן logcat, שמכיל מידע נוסף על מה שהשתמשו במעבד (CPU) בזמן שגיאת ה-ANR.

חיפוש דוחות קריסות

לרוב אפשר למצוא דוחות קריסות שמתאימים ל-ANR. צריך לוודא שהמאפיינים חותמת הזמן וה-PID של מעקבי ה-VM תואמים ל-ANR שאתם חוקרים, ואז לבדוק את ה-thread הראשי של התהליך. חשוב לזכור:

  • לפי ה-thread הראשי אפשר לראות רק מה הוא עשה שגיאת ANR, שיכולה להתאים לסיבה האמיתית ל-ANR, או לא. (הערימה ב: דוח איתור באגים עשוי להיות תמים. יכול להיות שמשהו אחר נתקע כבר הרבה זמן זמן – אבל לא מספיק ארוך כדי לקלוט את ה-ANR – לפני שתפסיקו לשקוע.)
  • יותר מקבוצה אחת של דוחות קריסות (VM TRACES JUST NOW וגם VM TRACES AT LAST ANR) קיים. חשוב לוודא שאתם מציגים החלק הנכון.

איתור מנעולים

בדרך כלל, מנעולנים מופיעים לראשונה כמקרי ANR כי שרשורים נתקעים. אם המיקום הקיפאון פוגע בשרת המערכת, והטיימר המפקח (watchdog) ירוג אותו, שמובילה לרשומה ביומן שדומה לזו: WATCHDOG KILLING SYSTEM PROCESS מנקודת המבט של המשתמש, של המכשיר מופעלת מחדש, למרות שמבחינה טכנית מדובר בהפעלה מחדש של סביבת זמן הריצה בזמן הפעלה מחדש.

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

כדי למצוא מנעולנים, בודקים בקטעים של מעקב ה-VM אם יש דפוס של thread A בהמתנה למשהו שממתין ל-thread B, שממתין למשהו נשמר ב-thread A.

פעילויות

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

צפייה בפעילויות שמתמקדות

כדי להציג היסטוריה של פעילויות ממוקדות, צריך לחפש את am_focused_activity

הצגת התחלת התהליך

כדי להציג היסטוריה של התחלת תהליכים, צריך לחפש את המילה Start proc.

האם המכשיר רועש

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

זיכרון

מאחר שלמכשירי Android לרוב יש זיכרון פיזי מוגבל, לכן ניהול זיכרון גישה אקראית (RAM) הוא קריטי. דוחות איתור באגים כוללים מספר אינדיקטורים של זיכרון נמוך ומצב של Dumpstate שמספק תמונת מצב של הזיכרון.

זיהוי חוסר זיכרון

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

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

הצגת אינדיקטורים היסטוריים

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

הצגת אינדיקטורים של חבטות קשות

אינדיקטורים אחרים של התעסקות במערכת (ניהול דפים, טעינה ישירה וכו') כוללים kswapd, kworker ו-mmcqd צורכים למחזורים שונים. (חשוב לזכור שדוח הבאג שנאסף יכול להשפיע על תקרית אינדיקטורים).

יומני ANR יכולים לספק תמונת מצב דומה של הזיכרון.

רוצה לראות תמונת מצב של הזיכרון?

תמונת המצב של הזיכרון היא קובץ dumpstate שבו מפורטות הרצת Java ו-Native בתהליכים שונים (לפרטים, אפשר לעיין במאמר בנושא הצגה הקצאת זיכרון כוללת). חשוב לזכור שקובץ ה-snapshot מספק רק את המצב בנקודת זמן ספציפית; ייתכן שהמערכת הייתה במצב טוב יותר (או גרוע יותר) לפני התמונה.

שידורים

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

הצגת שידורים היסטוריים

שידורים היסטוריים הם שידורים שכבר נשלחו, המפורטים ב בסדר כרונולוגי הפוך.

הקטע תקציר הוא סקירה כללית של 300 הנתונים האחרונים שידורים בחזית ו-300 השידורים האחרונים ברקע.

בקטע detail תוכלו למצוא את המידע המלא על 50 השידורים האחרונים בחזית ו-50 השידורים האחרונים ברקע, וגם המקלטים של כל שידור. מקלטים בעלי:

  • רשומות BroadcastFilter רשומות בזמן ריצה ונשלחות רק על תהליכים שכבר פועלים.
  • רשומות ResolveInfo נרשמות באמצעות רשומות המניפסט. ActivityManager מתחיל את התהליך עבור כל ResolveInfo, אם עדיין לא פועל.

הצגת השידורים הפעילים

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

הצגת מאזינים לשידור

כדי להציג רשימה של מקלטים שמאזינים לשידור, צריך לבדוק את המקלט טבלת מקודדים ב-dumpsys activity broadcasts. הבאים לדוגמה מוצגים כל המקלטים שמאזינים למשך USER_PRESENT.

מעקב אחר התחרות

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

ביומן המערכת:

10-01 18:12:44.343 29761 29914 W art     : Long monitor contention event with owner method=void android.database.sqlite.SQLiteClosable.acquireReference() from SQLiteClosable.java:52 waiters=0 for 3.914s

ביומן האירועים:

10-01 18:12:44.364 29761 29914 I dvm_lock_sample: [com.google.android.youtube,0,pool-3-thread-9,3914,ScheduledTaskMaster.java,138,SQLiteClosable.java,52,100]

אוסף ברקע

ההידור עלול להיות יקר ולטעון את המכשיר.

הידור עשוי להתרחש ברקע כשעדכונים של חנות Google Play מתבצעת הורדה. במקרה כזה, הודעות מהאפליקציה של חנות Google Play (finsky) וגם installd מופיעים לפני dex2oat הודעות.

הידור עשוי גם להתרחש ברקע כשהאפליקציה נטענת קובץ dex שעדיין לא עבר הידור. במקרה הזה, לא תראו רישום ביומן של finsky או installd.

העלילה

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

סנכרון לוחות הזמנים

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

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

10-03 17:19:52.939  1963  2071 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.google.android.googlequicksearchbox/com.google.android.launcher.GEL (has extras)} from uid 1000 on display 0

לגבי אותה פעולה, יומן האירועים מדווח:

10-03 17:19:54.279  1963  2071 I am_focused_activity: [0,com.google.android.googlequicksearchbox/com.google.android.launcher.GEL]

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

<6>[201640.779997] PM: suspend exit 2015-10-03 19:11:06.646094058 UTC
…
<6>[201644.854315] PM: suspend entry 2015-10-03 19:11:10.720416452 UTC

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

זיהוי המועד לדיווח על באג

כדי לדעת מתי נוצר דוח על באג, אתם צריכים קודם לבדוק את יומן המערכת (Logcat) עבור dumpstate: begin:

10-03 17:19:54.322 19398 19398 I dumpstate: begin

בשלב הבא צריך לבדוק את חותמות הזמן של יומן הליבה (dmesg) עבור ההודעה של Starting service 'bugreport':

<5>[207064.285315] init: Starting service 'bugreport'...

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

כוח

יומן האירועים מכיל את סטטוס ההפעלה של המסך, שבו 0 הוא המסך כבוי, 1 הוא המסך מופעל, והשני הוא סיום השמירה באמצעות מקש.

דוחות על באגים כוללים גם נתונים סטטיסטיים לגבי חסימות מצב שינה, מנגנון שמשמש את מפתחי אפליקציות שיציינו שלאפליקציה שלהם צריכה להיות להישאר. (לקבלת פרטים על חסימות מצב שינה, עיינו במאמר PowerManager.WakeLock ו-Keep את המעבד (CPU) שבו.)

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

לקבלת עזרה נוספת בהצגת סטטוס צריכת החשמל, אפשר היסטוריית סוללות, כלי קוד פתוח של Google לניתוח של צרכני הסוללה באמצעות דוח על באג ב-Android .

חבילות

הקטע DUMP OF SERVICE package מכיל גרסאות של אפליקציות (ועוד שימושיות ).

תהליכים

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

קביעת זמן הריצה של התהליך

הקטע procstats מכיל נתונים סטטיסטיים מלאים על משך הזמן וכל השירותים המשויכים אליהם פועלים. כדי ליצור תגובה מהירה וקריאה לאנשים לסיכום, חפשו את AGGREGATED OVER כדי להציג נתונים במהלך 3 או 24 השעות האחרונות, ואז לחפש Summary: כדי להציג את הרשימה של תהליכים, משך הזמן של התהליכים האלה עדיפויות שונות, השימוש ב-RAM בפורמט הבא: min-average-max PSS/min-Average-max USS.

סיבות להפעלת תהליך

בקטע dumpsys activity processes מוצגת רשימת כל הפריטים בשלב זה תהליכים פועלים מסודרים לפי ציון oom_adj (Android מציין לעבד את החשיבות על ידי הקצאת ערך oom_adj, יכול להתעדכן באופן דינמי על ידי ActivityManager). הפלט דומה לפלט של תמונת מצב של הזיכרון, אבל כוללת תמונות נוספות על מה שגורם לתהליך לפעול. בדוגמה הבאה, הרשומות המודגשות מציינות שהתהליך של gms.persistent פועל בעדיפות vis (גלויה), כי תהליך המערכת קשור NetworkLocationService שלו.

סריקות

כדי לזהות אפליקציות שרמת הביצועים שלהן גבוהה מדי: סריקות Bluetooth עם צריכת אנרגיה נמוכה (BLE):

  • חיפוש הודעות יומן עבור BluetoothLeScanner:
    $ grep 'BluetoothLeScanner' ~/downloads/bugreport.txt
    07-28 15:55:19.090 24840 24851 D BluetoothLeScanner: onClientRegistered() - status=0 clientIf=5
    
  • מאתרים את ה-PID בהודעות היומן. בדוגמה הזו, "24840" וגם 24851 הם PID (מזהה תהליך) ו-TID (מזהה שרשור).
  • מאתרים את האפליקציה שמשויכת ל-PID:
    PID #24840: ProcessRecord{4fe996a 24840:com.badapp/u0a105}
    

    בדוגמה הזו, שם החבילה הוא com.badapp.

  • צריך לחפש את שם החבילה ב-Google Play כדי לזהות את הגורם האחראי יישום: https://play.google.com/store/apps/details?id=com.badapp.

הערה: במכשירי Android 7.0, המערכת אוספת נתונים לסריקות BLE ומשייכת את הפעילויות האלה עם האפליקציה שמתחילה את התהליך. פרטים נוספים זמינים במאמר צריכת אנרגיה נמוכה (LE) וסריקות Bluetooth.