תיעוד נתוני מעקב באמצעות פקודות adb

אפשר לאסוף את הטרייסים של Winscope באמצעות שורת הפקודה adb ב-builds לניפוי באגים (כלומר, build של userdebug ו-eng). לפני שאוספים עקבות של Winscope באמצעות adb, מריצים את adb root.

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

ב-Android מגרסה 14 ואילך, לכל מעקב Winscope יש פקודה שונה, ואפשר לאסוף כל מעקב בנפרד. מידע נוסף זמין במאמר תיעוד נתוני מעקב ב-Android מגרסה 14 ומטה.

WindowManager

משתמשים בשם של מקור הנתונים android.windowmanager לסוג המעקב הזה.

אפשרויות הגדרה

  • רמת הרישום ביומן (log_level): קובעת את רמת הפירוט ביומן. ערכים נתמכים:

    • LOG_LEVEL_VERBOSE: הרישום ביומן כולל את כל הרכיבים עם כמות המידע המקסימלית.
    • LOG_LEVEL_DEBUG: מתועדים ביומן כל הרכיבים, אבל לא כל נתוני ההגדרה.
    • LOG_LEVEL_CRITICAL: מתועדים רק רכיבים גלויים, עם כמות מינימלית של זמן אחזור.
  • תדירות הרישום ביומן (log_frequency): ההגדרה קובעת את התדירות שבה הפריטים מתועדים ביומן:

    • LOG_FREQUENCY_FRAME: מעקב אחר קובצי snapshot של מצב כשמסגרת מועברת ל-commit.
    • LOG_FREQUENCY_TRANSACTION: מעקב אחר קובצי snapshot של מצב בכל פעם שמתבצעת טרנזקציה.
    • LOG_FREQUENCY_SINGLE_DUMP: מעקב אחר קובצי snapshot של מצב יחיד כשמפעילים את מקור הנתונים.

פרטים על ערכי ההגדרה מופיעים במאמר WindowManager.

דוגמה

דוגמה לסוג המעקב של WindowManager עבור adb:

$ adb shell -t perfetto \
     -c - --txt \
     -o /data/misc/perfetto-traces/trace \
   <<EOF
   unique_session_name: "my_custom_session"
   buffers: {
       size_kb: 63488
       fill_policy: RING_BUFFER
   }
   data_sources: {
       config {
           name: "android.windowmanager"
           windowmanager_config: {
              log_level: LOG_LEVEL_VERBOSE
              log_frequency: LOG_FREQUENCY_TRANSACTION
           }
       }
   }
EOF

ProtoLog

משתמשים בשם של מקור הנתונים android.protolog לסוג המעקב הזה.

אפשרויות הגדרה

Tracing mode (tracing_mode): קובע את הגדרת היומן שבה נעשה שימוש:

  • DEFAULT: מתבצע מעקב רק אחרי קבוצות יומנים ורמות שצוינו ב-group_overrides.
  • ENABLE_ALL: מעקב אחרי כל הקבוצות והרמות של היומנים, אלא אם צוין אחרת ב-group_overrides.

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

  • PROTOLOG_LEVEL_DEBUG
  • PROTOLOG_LEVEL_VERBOSE
  • PROTOLOG_LEVEL_INFO
  • PROTOLOG_LEVEL_WARN
  • PROTOLOG_LEVEL_ERROR
  • PROTOLOG_LEVEL_WTF

שינויים קבוצתיים (group_overrides): מאפשרים להגדיר באופן ידני את רמת היומן לכל קבוצת ProtoLog. כל קבוצה מכילה:

  • name: שם הקבוצה של ProtoLog, שמופיע בקוד המקור של Android.
  • log_from: זהה ל-default_log_from_level, אבל מצוין רק לקבוצה הנוכחית.
  • collect_stacktrace: כשהערך מוגדר ל-true, המערכת אוספת את נתיב הסטאק של כל הודעת ProtoLog בקבוצה שנמצאת במעקב.

דוגמה

דוגמה לסוג המעקב של ProtoLog עבור adb:

$ adb shell -t perfetto \
     -c - --txt \
     -o /data/misc/perfetto-traces/trace \
   <<EOF
   unique_session_name: "my_custom_session"
   buffers: {
       size_kb: 63488
       fill_policy: RING_BUFFER
   }
   data_sources: {
       config {
           name: "android.protolog"
           protolog_config: {
              tracing_mode: DEFAULT
              default_log_from_level: PROTOLOG_LEVEL_WARN
              group_overrides: {
                 group_name: "WM_SHELL_STARTING_WINDOW"
                 log_from: PROTOLOG_LEVEL_DEBUG
                 collect_stacktrace: true
              }
           }
       }
   }
EOF

קלט

משתמשים בשם של מקור הנתונים android.input.inputevent לסוג המעקב הזה.

אפשרויות הגדרה

מצב מעקב (trace_mode): קובע אם מעקב הקלט צריך להתחיל באמצעות כללים לשמירה על הפרטיות או לתעד את כל אירועי הקלט:

  • TRACE_MODE_TRACE_ALL: מתועדים בו כל אירועי הקלט שעברו עיבוד על ידי המערכת, ללא קשר להקשר שבו הם עברו עיבוד.
  • TRACE_MODE_USE_RULES: המערכת משתמשת בכללי המעקב שהוגדרו בתצורה הזו כדי לציין אילו אירועים יתבצע מעקב אחריהם. מידע נוסף על ציון הכללים למעקב מפורט במאמר android_input_event_config.proto.

דוגמה

דוגמה לסוג המעקב אחר הקלט של adb:

$ adb shell -t perfetto \
     -c - --txt \
     -o /data/misc/perfetto-traces/trace \
   <<EOF
   unique_session_name: "my_custom_session"
   buffers: {
       size_kb: 63488
       fill_policy: RING_BUFFER
   }
   data_sources: {
       config {
           name: "android.input.inputevent"
           android_input_event_config: {
              mode: TRACE_MODE_TRACE_ALL
           }
       }
   }
EOF

SurfaceFlinger (שכבות)

משתמשים בשם של מקור הנתונים android.surfaceflinger.layers לסוג המעקב הזה.

אפשרויות הגדרה

מצב מעקב (mode): מגדיר את התדירות שבה הפריטים מתועדים ביומן:

  • MODE_ACTIVE: מעקב אחר קובצי snapshot של שכבות. תמונת המצב נוצרת בכל פעם שמתבצע שינוי בשכבות.
  • MODE_GENERATED: יוצר קובצי snapshot של שכבות מהעסקאות שנשמרות במאגר הטבעת הפנימי של SurfaceFlinger. יצירת קובצי ה-snapshot של השכבה מתרחשת כשמקור הנתונים הזה מתרוקן.
  • MODE_DUMP: מעקב אחר קובץ snapshot של שכבה אחת.
  • MODE_GENERATED_BUGREPORT_ONLY: זהה ל-MODE_GENERATED, אבל היצירה של קובצי snapshot של השכבות מופעלת רק כשיוצרים דוח באג, ולא בכל פעם שמתבצע שטיפה של נתיב.

דגלים למעקב (trace_flags):

  • TRACE_FLAG_INPUT: אם המשטח מכיל נתוני קלט, הוא עוקב אחרי הפרטים של חלון הקלט.
  • TRACE_FLAG_COMPOSITION: מעקב אחר סוג הקומפוזיציה והאזור הגלוי.
  • TRACE_FLAG_EXTRA: מעקב אחרי מטא-נתונים נוספים של פלטפורמה, כולל שכבות מחוץ למסך.

  • TRACE_FLAG_HWC: מעקב אחר מטא-נתונים נוספים של מלחין חומרה לא מובנה.

  • TRACE_FLAG_BUFFERS: הגדרת SurfaceFlinger למעקב אחרי כל השינויים במאגר ב-surface. כברירת מחדל, SurfaceFlinger מתעד מצב חדש רק כשמתרחשות שינויים בגיאומטריה.

  • TRACE_FLAG_VIRTUAL_DISPLAYS: כולל שכבות תצוגה וירטואליות במעקב.

דוגמה

הדוגמה הבאה מראה את סוג המעקב של SurfaceFlinger ב-adb:

$ adb shell -t perfetto \
     -c - --txt \
     -o /data/misc/perfetto-traces/trace \
   <<EOF
   unique_session_name: "my_custom_session"
   buffers: {
       size_kb: 63488
       fill_policy: RING_BUFFER
   }
   data_sources: {
       config {
           name: "android.surfaceflinger.layers"
           surfaceflinger_layers_config: {
              mode: MODE_ACTIVE
              trace_flags: TRACE_FLAG_INPUT
              trace_flags: TRACE_FLAG_COMPOSITION
              trace_flags: TRACE_FLAG_HWC
              trace_flags: TRACE_FLAG_BUFFERS
              trace_flags: TRACE_FLAG_VIRTUAL_DISPLAYS
           }
       }
   }
EOF

במאמר SurfaceFlinger מוסבר מה המשמעות של ערכי ההגדרה השונים.

מעברים של מעטפת

צריך להשתמש בשם של מקור הנתונים com.android.wm.shell.transition לסוג המעקב הזה.

אפשרויות הגדרה

לסוג המעקב הזה אין אפשרויות תצורה.

דוגמה

דוגמה לסוג המעקב של מעבר מעטפת עבור adb:

$ adb shell -t perfetto \
     -c - --txt \
     -o /data/misc/perfetto-traces/trace \
   <<EOF
   unique_session_name: "my_custom_session"
   buffers: {
       size_kb: 63488
       fill_policy: RING_BUFFER
   }
   data_sources: {
       config {
           name: "com.android.wm.shell.transition"
       }
   }
EOF

SurfaceFlinger (עסקאות)

משתמשים בשם של מקור הנתונים android.surfaceflinger.transactions לסוג המעקב הזה.

אפשרויות הגדרה

מצב מעקב (mode): מגדיר את התדירות שבה הפריטים מתועדים ביומן:

  • MODE_CONTINUOUS: ‏SurfaceFlinger כותב את מאגר הטרנזקציות הפנימי שלו בכל פעם שמתבצע שטיפה של מקור הנתונים. מאגר הטבעת מכיל את המצב הראשוני של SurfaceFlinger ואת העסקאות האחרונות.

  • MODE_ACTIVE: SurfaceFlinger כותב את המצב הראשוני ואז כל עסקה נכנסת עד שמקור הנתונים מושבת.

דוגמה

הדוגמה הבאה ממחישה את סוג המעקב אחר טרנזקציות של SurfaceFlinger עבור adb.

$ adb shell -t perfetto \
     -c - --txt \
     -o /data/misc/perfetto-traces/trace \
   <<EOF
   unique_session_name: "my_custom_session"
   buffers: {
       size_kb: 63488
       fill_policy: RING_BUFFER
   }
   data_sources: {
       config {
           name: "android.surfaceflinger.transactions"
           surfaceflinger_transactions_config: {
              mode: MODE_ACTIVE
           }
       }
   }
EOF

IME

משתמשים בשם של מקור הנתונים: android.inputmethod לסוג המעקב הזה.

אפשרויות הגדרה

לסוג המעקב הזה אין אפשרויות תצורה.

דוגמה

דוגמה לסוג המעקב של IME עבור adb:

$ adb shell -t perfetto \
     -c - --txt \
     -o /data/misc/perfetto-traces/trace \
   <<EOF
   unique_session_name: "my_custom_session"
   buffers: {
       size_kb: 63488
       fill_policy: RING_BUFFER
   }
   data_sources: {
       config {
           name: "android.inputmethod"
       }
   }
EOF

ViewCapture

צריך להשתמש בשם של מקור הנתונים android.viewcapture לסוג המעקב הזה.

אפשרויות הגדרה

לסוג המעקב הזה אין אפשרויות תצורה.

דוגמה

דוגמה לסוג המעקב ViewCapture ב-adb:

$ adb shell -t perfetto \
     -c - --txt \
     -o /data/misc/perfetto-traces/trace \
   <<EOF
   unique_session_name: "my_custom_session"
   buffers: {
       size_kb: 63488
       fill_policy: RING_BUFFER
   }
   data_sources: {
       config {
           name: "android.viewcapture"
       }
   }
EOF

דוגמה מלאה

Perfetto מאפשר לאסוף נתונים ממקורות מרובים בהגדרה אחת. אפשר לאסוף את כל עקבות Winscope באמצעות פקודה אחת:

$ adb shell -t perfetto \
     -c - --txt \
     -o /data/misc/perfetto-traces/trace \
   <<EOF
   unique_session_name: "my_custom_session"
   buffers: {
       size_kb: 63488
       fill_policy: RING_BUFFER
   }
   data_sources: {
       config {
           name: "android.windowmanager"
           windowmanager_config: {
              log_level: LOG_LEVEL_VERBOSE
              log_frequency: LOG_FREQUENCY_TRANSACTION
           }
       }
   }
   data_sources: {
       config {
           name: "android.protolog"
           protolog_config: {
              tracing_mode: ENABLE_ALL
           }
       }
   }
   data_sources: {
       config {
           name: "android.input.inputevent"
           android_input_event_config: {
              mode: TRACE_MODE_TRACE_ALL
           }
       }
   }
   data_sources: {
       config {
           name: "android.surfaceflinger.layers"
           surfaceflinger_layers_config: {
              mode: MODE_ACTIVE
              trace_flags: TRACE_FLAG_INPUT
              trace_flags: TRACE_FLAG_COMPOSITION
              trace_flags: TRACE_FLAG_HWC
              trace_flags: TRACE_FLAG_BUFFERS
              trace_flags: TRACE_FLAG_VIRTUAL_DISPLAYS
           }
       }
   }
   data_sources: {
       config {
           name: "com.android.wm.shell.transition"
       }
   }
   data_sources: {
       config {
           name: "android.surfaceflinger.transactions"
           surfaceflinger_transactions_config: {
              mode: MODE_ACTIVE
           }
       }
   }
   data_sources: {
       config {
           name: "android.inputmethod"
       }
   }
   data_sources: {
       config {
           name: "android.viewcapture"
       }
   }
EOF

תיעוד נתוני מעקב ב-Android 14 ובגרסאות קודמות

מריצים את adb root לפני שמריצים את הפקודות adb shell לכל אחד מהמעקבים הבאים. בסיום המעקב, קובצי המעקב יהיו זמינים ב-/data/misc/wmtrace. במאמר העתקת קבצים אל מכשיר וממנו מוסבר איך מעתיקים קובץ או ספרייה ואת ספריות המשנה שלהם ממכשיר.

נתוני מעקב של WindowManager

כדי לתעד את העקבות של WindowManager:

  • מפעילים את המעקב:

    adb shell wm tracing start
    
  • משביתים את המעקב:

    adb shell wm tracing stop
    
  • שמירת נתוני הרישום ביומן בקובץ בזמן הרצת תהליך תיעוד:

    adb shell wm tracing save-for-bugreport
    
  • רישום ביומן פעם אחת לכל מסגרת:

    adb shell wm tracing frame
    
  • מתעדים כל עסקה ביומן:

    adb shell wm tracing transaction
    
  • מגדירים את הגודל המקסימלי של היומן (ב-KB):

    adb shell wm tracing size
    
  • הדפסת סטטוס המעקב:

    adb shell wm tracing status
    
  • מגדירים את רמת היומן ל-critical (רק חלונות גלויים עם מידע מופחת), ל-trim (כל החלונות עם מידע מופחת) או ל-all (כל החלונות והמידע):

    adb shell wm tracing level
    

דיווחים על טעויות ב-WindowManager

כדי לצלם דיווחים על טעויות של WindowManager:

adb exec-out dumpsys window --proto > window_dump.winscope

ProtoLog

הפקודות הבאות משמשות למערכת ProtoLog.

בתהליך system_server:

  • התחלת ProtoLog:

    adb shell cmd window logging start
    
  • הפסקת ProtoLog:

    adb shell cmd window logging stop
    
  • מפעילים את ProtoLog לקבוצות יומנים נתונות:

    adb shell cmd window logging enable [group...]
    
  • משביתים את ProtoLog בקבוצות יומנים נתונות:

    adb shell cmd window logging disable [group...]
    
  • מפעילים את הרישום ביומן של Logcat לקבוצות יומנים נתונות:

    adb shell cmd window logging enable-text [group...]
    
  • משביתים את הרישום ביומן Logcat לקבוצות יומן נתונות:

    adb shell cmd window logging disable-text [group...]
    

ב-WMShell:

  • התחלת ProtoLog:

    adb shell dumpsys activity service SystemUIService WMShell
    

מעקבים (שכבות) של SurfaceFlinger

במעקב אחר שכבות של SurfaceFlinger נעשה שימוש ב-Perfetto trace לצורך תיעוד. מידע נוסף על ההגדרות זמין במאמר הגדרת מעקב.

דוגמה להגדרה של מעקב שכבות ב-SurfaceFlinger:

unique_session_name: "surfaceflinger_layers_active"
buffers: {
    size_kb: 63488
    fill_policy: RING_BUFFER
}
data_sources: {
    config {
        name: "android.surfaceflinger.layers"
        surfaceflinger_layers_config: {
            mode: MODE_ACTIVE
            trace_flags: TRACE_FLAG_INPUT
            trace_flags: TRACE_FLAG_COMPOSITION
            trace_flags: TRACE_FLAG_HWC
            trace_flags: TRACE_FLAG_BUFFERS
            trace_flags: TRACE_FLAG_VIRTUAL_DISPLAYS
        }
    }
}

הפקודה הבאה היא דוגמה ליצירת מעקב אחרי שכבות של SurfaceFlinger:

adb shell -t perfetto \
    -c - --txt \
    -o /data/misc/perfetto-traces/trace \

קובצי dump (שכבות) של SurfaceFlinger

כדי לצלם דיווחים של SurfaceFlinger:

adb exec-out dumpsys SurfaceFlinger --proto > sf_dump.winscope

מעברים של מעטפת

הפקודות הבאות משמשות למעקב אחרי מעברים.

בתהליך system_server:

  • מתחילים מעקב:

    adb shell cmd window shell tracing start
    
  • כדי להפסיק מעקב:

    adb shell cmd window shell tracing stop
    
  • מתחילים מעקב ב-WMShell:

    adb shell dumpsys activity service SystemUIService WMShell transitions tracing start
    
  • כדי להפסיק מעקב ב-WMShell:

    adb shell dumpsys activity service SystemUIService WMShell transitions tracing stop
    

IME

הפקודות הבאות משמשות למעקב אחר עורך שיטות הקלט (IME):

  • מתחילים את המעקב אחר IME עבור לקוחות של שיטות קלט (IM), שירות שיטות קלט (IMS) ושירות ניהול שיטות קלט (IMMS):

    adb shell ime tracing start
    
  • מתחילים לעקוב אחרי לקוחות IME,‏ IMS ו-IMMS:

    adb shell ime tracing stop
    

SurfaceFlinger (טרנזקציות)

במעקב אחר עסקאות ב-SurfaceFlinger נעשה שימוש ב-Perfetto trace לצורך תיעוד. מידע נוסף על ההגדרות זמין במאמר הגדרת מעקב.

בדוגמה הבאה מופיעה הגדרה של Perfetto למעקב פעיל ב-SurfaceFlinger:

unique_session_name: "surfaceflinger_transactions_active"
buffers: {
    size_kb: 1024
    fill_policy: RING_BUFFER
}
data_sources: {
    config {
        name: "android.surfaceflinger.transactions"
        surfaceflinger_transactions_config: {
            mode: MODE_ACTIVE
        }
    }
}
write_into_file: true
file_write_period_ms: 100

בדוגמה הבאה מופיעה הגדרה של Perfetto ל-SurfaceFlinger למעקב רציף:

unique_session_name: "surfaceflinger_transactions_continuous"
buffers: {
    size_kb: 1024
    fill_policy: RING_BUFFER
}
data_sources: {
    config {
        name: "android.surfaceflinger.transactions"
        surfaceflinger_transactions_config: {
            mode: MODE_CONTINUOUS
        }
    }
}

כדי ליצור מעקב אחר טרנזקציות של SurfaceFlinger, אפשר להשתמש בפקודה לדוגמה הבאה:

    adb shell perfetto \
    -c - --txt \
    -o /data/misc/perfetto-traces/trace \