ניפוי באגים באפליקציה

ב-Android Studio יש כלי לניפוי באגים שמאפשר לכם לבצע את הפעולות הבאות ועוד:

  • בוחרים מכשיר לניפוי הבאגים באפליקציה.
  • הגדרת נקודות עצירה בקוד Java,‏ Kotlin ו-C/C++‎.
  • בדיקת משתנים והערכת ביטויים בזמן ריצה.

בדף הזה מוסברות פעולות בסיסיות של ניפוי באגים. מידע נוסף זמין גם במסמכי התיעוד בנושא ניפוי באגים ב-IntelliJ IDEA.

הפעלת ניפוי באגים

לפני שמתחילים בניפוי הבאגים, צריך לבצע את הפעולות הבאות:

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

משתמשים בגרסת build שכוללת את debuggable true (isDebuggable = true בסקריפטים של Kotlin) בהגדרת ה-build.

בדרך כלל אפשר לבחור את גרסת ברירת המחדל 'debug' שכלולה בכל פרויקט של Android Studio, גם אם היא לא מוצגת בקובץ build.gradle. עם זאת, אם מגדירים סוגי build חדשים שאפשר לבצע בהם ניפוי באגים, צריך להוסיף את debuggable true לסוג ה-build:

מגניב

android {
    buildTypes {
        customDebugType {
            debuggable true
            ...
        }
    }
}

Kotlin

android {
    buildTypes {
        create("customDebugType") {
            isDebuggable = true
            ...
        }
    }
}

המאפיין הזה חל גם על מודולים עם קוד C/C++‎.

הערה: המאפיין jniDebuggable כבר לא בשימוש.

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

התחלת ניפוי באגים

כדי להתחיל סשן ניפוי באגים:

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

    אם לא הגדרתם מכשירים, תצטרכו לחבר מכשיר באמצעות USB, לחבר מכשיר באמצעות Wi-Fi או ליצור AVD כדי להשתמש בAndroid Emulator.

  3. בסרגל הכלים, לוחצים על Debug (ניפוי באגים) .

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

    אם מוסיפים קוד C ו-C++‎ לפרויקט,‏ Android Studio מפעיל גם את כלי הניפוי LLDB בחלון Debug (ניפוי באגים) כדי לנפות באגים בקוד המקורי.

  4. אם חלון הניפוי באגים לא פתוח, בוחרים באפשרות View > Tool Windows > Debug (תצוגה > חלונות כלים > ניפוי באגים), או לוחצים על Debug (ניפוי באגים) בסרגל חלון הכלים.

חיבור מנפה הבאגים לאפליקציה שפועלת

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

  1. לוחצים על צירוף מאתר הבאגים לתהליך Android .
  2. בתיבת הדו-שיח Choose Process, בוחרים את התהליך שאליו רוצים לצרף את מאתר הבאגים.
    1. אם אתם משתמשים באמולטור או במכשיר עם הרשאת root, אתם יכולים לסמן את התיבה הצגת כל התהליכים כדי לראות את כל התהליכים. במכשיר עם הרשאת Root, יוצגו כל התהליכים שפועלים במכשיר. עם זאת, במכשיר לא פרוץ, יוצגו רק תהליכים שניתן לבצע בהם ניפוי באגים.
    2. בתפריט Use Android Debugger Settings from, אפשר לבחור הגדרת הפעלה/ניפוי באגים קיימת. במקרה של קוד C ו-C++‎, האפשרות הזו מאפשרת לעשות שימוש חוזר בפקודות ההפעלה של LLDB, בפקודות של LLDB אחרי ההצמדה ובספריות הסמלים בהגדרה קיימת.
    3. אם אין לכם הגדרת הרצה או ניפוי באגים קיימת, בוחרים באפשרות Create New (יצירת הגדרה חדשה). הבחירה הזו מפעילה את התפריט סוג ניפוי הבאגים, שבו אפשר לבחור סוג אחר של ניפוי באגים. כברירת מחדל, Android Studio משתמש בסוג ניפוי הבאגים Detect Automatically (זיהוי אוטומטי) כדי לבחור את אפשרות ניפוי הבאגים הטובה ביותר עבורכם, בהתאם לשאלה אם הפרויקט כולל קוד Java או קוד C/C++.
  3. לוחצים על אישור.

    יופיע חלון ניפוי הבאגים.

בכרטיסייה Processes (תהליכים) בכלי Device Explorer (סייר המכשירים) (View > Tool Windows > Device Explorer (תצוגה > חלונות כלים > סייר המכשירים)) מופיעה גם רשימה של תהליכים שאפשר לבצע בהם ניפוי באגים. משם אפשר לבחור תהליך ולבצע פעולת השבתה (kill) , עצירה בכוח או צירוף של מאתר הבאגים לתהליך נתון .

חלון ניפוי הבאגים

איור 2. חלון ניפוי הבאגים.

חלון ניפוי הבאגים מחולק ל

  1. סרגל הכלים של ההפעלה והניווט. ראו עבודה עם נקודות עצירה
  2. בורר שרשורים
  3. הזנת ביטוי שעון והערכה. איך בודקים משתנים
  4. הצגת מקבץ התמונות
  5. חלונית המשתנים. איך בודקים משתנים

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

שינוי סוג הכלי לניפוי באגים

כדי לנפות באגים בקוד Java/Kotlin ובקוד C/C++, צריך להשתמש בכלי ניפוי באגים שונים. לכן, כלי ניפוי הבאגים של Android Studio מאפשר לכם לבחור את סוג כלי ניפוי הבאגים שבו תרצו להשתמש. כברירת מחדל, Android Studio מחליט באיזה מאתר באגים להשתמש על סמך השפות שהוא מזהה בפרויקט באמצעות סוג מאתר הבאגים Detect Automatically.

כדי לבחור ידנית את מאתר הבאגים בהגדרת ניפוי הבאגים, לוחצים על Run > Edit Configurations (הפעלה > עריכת הגדרות). אפשר גם לבחור את מאתר הבאגים בתיבת הדו-שיח שמופיעה כשלוחצים על Run > Attach debugger to Android process (הפעלה > צירוף מאתר הבאגים לתהליך של Android).

אלה סוגי הניפוי באגים שזמינים:

זיהוי אוטומטי
בוחרים בסוג הניפוי הזה אם רוצים ש-Android Studio יבחר אוטומטית את האפשרות הטובה ביותר עבור הקוד שמנפים בו באגים. לדוגמה, אם יש לכם קוד C או C++ בפרויקט, Android Studio משתמש אוטומטית בסוג Dual debug. אחרת, Android Studio משתמש בסוג הניפוי באגים Java-Only.
Java בלבד
בוחרים בסוג הניפוי הזה אם רוצים לנפות באגים רק בקוד שנכתב ב-Java או ב-Kotlin. המאגר רק של Java מתעלם מכל נקודות העצירה או הצפיות שהגדרתם בקוד המקורי.
פורמטים מותאמים בלבד (זמין רק עם קוד C/C++)
בוחרים בסוג הניפוי הזה אם רוצים להשתמש רק ב-LLDB כדי לנפות באגים בקוד. כשמשתמשים בסוג הניפוי הזה, התצוגה של סשן ניפוי הבאגים של Java לא זמינה. כברירת מחדל,‏ LLDB בודק רק את הקוד המקורי ומתעלם מנקודות עצירה בקוד Java. אם רוצים גם לנפות באגים בקוד Java, צריך לעבור לאפשרות Detect Automatically או Dual debug type.

ניפוי באגים מקורי פועל רק במכשירים שעומדים בדרישות הבאות:

  • המכשיר תומך ב-run-as.

    כדי לבדוק אם המכשיר תומך ב-run-as, מריצים את הפקודה הבאה במעטפת ADB שמחוברת למכשיר:

    run-as your-package-name pwd
    

    מחליפים את your-package-name בשם החבילה של האפליקציה. אם המכשיר תומך ב-run-as, הפקודה אמורה לחזור ללא שגיאות.

  • במכשיר מופעלת התכונה ptrace.

    כדי לבדוק אם ptrace מופעל, מריצים את הפקודה הבאה במעטפת ADB שמחוברת למכשיר:

    sysctl kernel.yama.ptrace_scope
    

    אם האפשרות ptrace מופעלת, הפקודה תדפיס את הערך 0 או את השגיאה unknown key. אם ptrace לא מופעל, יודפס ערך אחר מ-0.

כפול (Java + Native) – זמין רק עם קוד C/C++‎
בוחרים בסוג הזה של ניפוי באגים אם רוצים לעבור בין ניפוי באגים של קוד Java וקוד מקורי. ‫Android Studio מצרף את מאתר הבאגים של Java ואת LLDB לתהליך של האפליקציה, כך שאתם יכולים לבדוק נקודות עצירה גם בקוד Java וגם בקוד מקורי בלי להפעיל מחדש את האפליקציה או לשנות את הגדרות הניפוי.

באיור 2, שימו לב לשתי הכרטיסיות שמשמאל לכותרת של חלון הניפוי באגים. מכיוון שהאפליקציה כוללת קוד Java וקוד C++, כרטיסייה אחת מיועדת לניפוי שגיאות בקוד המקורי והשנייה לניפוי שגיאות בקוד Java, כפי שמצוין ב-‎-java.

איור 3. Tab לניפוי באגים בקוד נייטיב ו-Tab לניפוי באגים בקוד Java.

הערה: במהלך ניפוי באגים בקוד מקורי שעבר אופטימיזציה על ידי הקומפיילר, יכול להיות שתופיע הודעת האזהרה הבאה:
This function was compiled with optimizations enabled. Some debugger features may not be available. כשמשתמשים בדגלי אופטימיזציה, המהדר מבצע שינויים בקוד המהודר כדי שהקוד יפעל בצורה יעילה יותר. הדבר עלול לגרום למנפה הבאגים לדווח על מידע לא צפוי או שגוי, כי קשה למנפה הבאגים למפות את הקוד המהודר שעבר אופטימיזציה בחזרה לקוד המקור המקורי. לכן, כדאי להשבית את האופטימיזציות של הקומפיילר בזמן ניפוי הבאגים של הקוד המקומי.

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

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

כתיבת הודעות ביומן בקוד

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

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

Kotlin

import android.util.Log
...
class MyActivity : Activity() {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        if (savedInstanceState != null) {
            Log.d(TAG, "onCreate() Restoring previous state")
            /* restore state */
        } else {
            Log.d(TAG, "onCreate() No saved state available")
            /* initialize app */
        }
        ...
    }
  ...
  companion object {
    private val TAG: String = MyActivity::class.java.simpleName
    ...
  }
}

Java

import android.util.Log;
...
public class MyActivity extends Activity {
    private static final String TAG = MyActivity.class.getSimpleName();
    ...
    @Override
    public void onCreate(Bundle savedInstanceState) {
       ...
       if (savedInstanceState != null) {
            Log.d(TAG, "onCreate() Restoring previous state");
            /* restore state */
        } else {
            Log.d(TAG, "onCreate() No saved state available");
            /* initialize app */
        }
        ...
    }
}

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

Kotlin

fun someOtherMethod() {
    try {
        ...
    } catch (e : SomeException) {
        Log.d(TAG, "someOtherMethod()", e)
    }
}

Java

void someOtherMethod() {
    try {
        ...
    } catch (SomeException e) {
        Log.d(TAG, "someOtherMethod()", e);
    }
}

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

צפייה ביומן המערכת

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

כדי להשתמש ב-Logcat, מתחילים בניפוי באגים ובוחרים בכרטיסייה Logcat.

איור 4. חלון Logcat עם הגדרות סינון.

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

עבודה עם נקודות עצירה (breakpoint)

‫Android Studio תומך בנקודות עצירה שמפעילות פעולות שונות של ניפוי באגים. יש כמה סוגים של נקודות עצירה:

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

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

כדי להוסיף נקודת עצירה בשורה, פועלים לפי השלבים הבאים:

  1. מאתרים את שורת הקוד שבה רוצים להשהות את ההרצה.
  2. לוחצים על השוליים השמאליים לאורך שורת הקוד או מציבים את הסמן בשורה ומקישים על Control+F8 (ב-macOS, על Command+F8).
  3. אם האפליקציה כבר פועלת, לוחצים על Attach debugger to Android process . אחרת, כדי להתחיל בניפוי באגים, לוחצים על ניפוי באגים .

כשמגדירים נקודת עצירה, מופיעה נקודה אדומה לצד השורה, כמו שמוצג באיור 5.

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

כשהרצת הקוד מגיעה לנקודת העצירה, Android Studio משהה את הרצת האפליקציה.

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

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

  • כדי לעבור לשורה הבאה בקוד בלי להזין שיטה, לוחצים על Step Over .

  • כדי להתקדם לשורה הראשונה בתוך קריאה למתודה, לוחצים על Step Into .

  • כדי לעבור לשורה הבאה מחוץ לשיטה הנוכחית, לוחצים על Step Out .

  • כדי להמשיך להפעיל את האפליקציה כרגיל, לוחצים על המשך הפעלת התוכנית .

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

הערה: כדי ש-Android Studio יזהה נקודות עצירה בקוד C או C++, צריך להשתמש בסוג ניפוי באגים שתומך ב-LLDB, כמו Detect Automatically,‏ Native או Dual. אפשר לשנות את סוג הניפוי באגים שבו משתמשים ב-Android Studio על ידי עריכת הגדרות הניפוי באגים. מידע נוסף על סוגי הניפוי השונים זמין בקטע על שימוש בסוגים אחרים של ניפוי באגים.

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

איור 6. ניפוי באגים בקוד מקורי באמצעות LLDB.
  1. כשמאותת מאתר הבאגים LLDB על נקודת עצירה בקוד C/C++,‏ Android Studio עובר לכרטיסייה <your-module>. החלוניות Frames, ‏ Variables ו-Watches זמינות גם הן, והן פועלות בדיוק כמו שהן פועלות כשמבצעים ניפוי באגים בקוד Java.

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

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

  2. ‫Android Studio עובר לכרטיסייה <your-module>-java כשמאבחן הבאגים של Java נתקל בנקודת עצירה בקוד Java או Kotlin.
  3. במהלך ניפוי באגים באמצעות LLDB, אפשר להשתמש בטרמינל LLDB בתצוגת סשן LLDB כדי להעביר אפשרויות של שורת הפקודה אל LLDB. אם יש פקודות מסוימות שאתם רוצים שמערכת LLDB תבצע בכל פעם שתתחילו לנפות באגים באפליקציה, ממש לפני או ממש אחרי שמנפה הבאגים יצורף לתהליך האפליקציה, תוכלו להוסיף את הפקודות האלה להגדרת ניפוי הבאגים.

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

צפייה בנקודות עצירה והגדרתן

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

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

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

בוחרים נקודת עצירה מהרשימה כדי להגדיר את ההגדרות שלה. אפשר להגדיר נקודת עצירה כך שהיא תושבת בהתחלה, והמערכת תפעיל אותה אחרי שנקודת עצירה אחרת תופעל. אפשר גם להגדיר אם נקודת עצירה צריכה להיות מושבתת אחרי שהיא מופעלת. כדי להגדיר נקודת עצירה לכל חריגה, בוחרים באפשרות Exception Breakpoints ברשימת נקודות העצירה.

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

ניפוי באגים של פריימים של חלונות

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

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

בדיקת משתנים

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

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

איור 8. עץ האובייקטים ותיבת הזנת הביטוי בחלון Debug.
  1. מזינים את הביטוי שרוצים לעקוב אחריו או להציג אותו.
  2. לוחצים על הוספה לרשימת המעקב או מקישים על Enter כדי להעריך את הביטוי פעם אחת.

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

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

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

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

הוספת נקודות מעקב

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

ב-Android Studio, אפשר ליצור נקודת מעקב במהלך זמן הריצה על ידי בחירת משתנה ספציפי, אבל LLDB מקצה את נקודת המעקב רק לבלוק הזיכרון שהמערכת מקצה למשתנה הזה, ולא למשתנה עצמו. זה שונה מהוספת משתנה לחלונית Watches, שמאפשרת לכם לצפות בערך של משתנה אבל לא מאפשרת להשעות את תהליך האפליקציה כשמערכת קוראת את הערך שלו בזיכרון או משנה אותו.

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

כדי להגדיר נקודת מעקב, צריך לעמוד בדרישות הבאות:

  • המכשיר הפיזי או האמולטור שאתם רוצים להשתמש בהם מבוססים על מעבד x86 או x86_64. אם המכשיר שלכם משתמש במעבד ARM, אתם צריכים ליישר את הגבול של כתובת המשתנה בזיכרון ל-4 בייטים, למעבדים של 32 ביט, או ל-8 בייטים, למעבדים של 64 ביט. כדי ליישר משתנה בקוד המקורי, מציינים את הערך __attribute__((aligned(num_bytes))) בהצהרת המשתנה, כמו בדוגמה הבאה:
    // For a 64-bit ARM processor
    int my_counter __attribute__((aligned(8)));
  • כבר הקציתם שלוש נקודות צפייה או פחות. ב-Android Studio יש תמיכה בעד ארבע נקודות מעקב במכשירי יעד מסוג x86 או x86_64. יכול להיות שבמכשירים אחרים יהיה אפשר להגדיר פחות נקודות מעקב.

הערה: כשמבצעים ניפוי באגים באפליקציה באמצעות ABI של ARM‏ 32 ביט, הוספה של נקודת מעקב או העברת העכבר מעל משתנים בתוך הקוד כדי לבדוק את הערכים שלהם עלולה לגרום לקריסה. כפתרון זמני, אפשר לבצע ניפוי באגים באמצעות קבצים בינאריים של ARM‏ 64 ביט, x86 או x86_64. הבעיה הזו תיפתר בגרסה עתידית של Android Studio.

אם אתם עומדים בדרישות, תוכלו להוסיף נקודת מעקב באופן הבא:

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

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

    מגדירים את נקודת המעקב באמצעות האפשרויות הבאות:

    • מופעלת: מבטלים את הסימון של האפשרות הזו אם רוצים להגדיר ל-Android Studio להתעלם מנקודת המעקב עד לשינוי ההגדרה. ‫Android Studio שומר את נקודת המעקב כדי שתוכלו לגשת אליה מאוחר יותר.
    • השהיה: כברירת מחדל, מערכת Android משהה את תהליך האפליקציה כשמתבצעת גישה לבלוק זיכרון שהוקצה לנקודת מעקב. אם לא רוצים שההתנהגות הזו תתרחש, צריך לבטל את הסימון של האפשרות הזו. כך מוצגות אפשרויות נוספות שאפשר להשתמש בהן כדי להתאים אישית את ההתנהגות כשהמערכת מבצעת אינטראקציה עם נקודת המעקב: רישום הודעה במסוף והסרה כשההגעה לנקודה מתרחשת.
    • סוג הגישה: בוחרים אם האפליקציה צריכה להפעיל את נקודת המעקב כשמנסים לקרוא או לכתוב לבלוק הזיכרון שהמערכת מקצה למשתנה. כדי להפעיל את נקודת המעקב בפעולת קריאה או כתיבה, בוחרים באפשרות Any (כל פעולה).
  4. לוחצים על סיום.

כדי להציג את כל נקודות המעקב ולהגדיר את ההגדרות שלהן, לוחצים על View Breakpoints (הצגת נקודות עצירה) בחלון Debug (ניפוי באגים). מופיעה תיבת הדו-שיח Breakpoints, כמו שמוצג באיור 10.

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

אחרי שמוסיפים את נקודת המעקב, לוחצים על Resume Program בחלון Debug כדי להמשיך את התהליך של האפליקציה. כברירת מחדל, אם האפליקציה מנסה לגשת לבלוק זיכרון שהגדרתם בו נקודת מעקב, מערכת Android משעה את תהליך האפליקציה וסמל נקודת המעקב מופיע לצד שורת הקוד שהאפליקציה ביצעה לאחרונה, כמו שמוצג באיור 11.

איור 11. ‫Android Studio מציין את שורת הקוד שהאפליקציה מריצה ממש לפני הפעלת נקודת מעקב.

הצגה ושינוי של פורמט התצוגה של ערך המשאב

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

  1. ברשימת המשתנים, לוחצים לחיצה ימנית במקום כלשהו בשורת משאב כדי להציג את הרשימה.
  2. ברשימה, בוחרים באפשרות View as (תצוגה כ) ובוחרים את הפורמט שרוצים להשתמש בו.

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

    • Class: הצגת הגדרת הכיתה.
    • toString: פורמט מחרוזת לתצוגה.
    • אובייקט: הצגת ההגדרה של האובייקט (מופע של מחלקה).
    • מערך: הצגה בפורמט מערך.
    • חותמת זמן: תאריך ושעה בפורמט הבא: yyyy-mm-dd hh:mm:ss.
    • אוטומטי: Android Studio בוחר את הפורמט הכי טוב על סמך סוג הנתונים.
    • בינארי: הצגת ערך בינארי באמצעות אפסים ואחדות.
    • MeasureSpec: הערך שמועבר מההורה לצאצא שנבחר. ראו MeasureSpec.
    • הקסדצימלי: הצגה כערך הקסדצימלי.
    • Primitive: מוצג כערך מספרי באמצעות סוג נתונים פרימיטיבי.
    • מספר שלם: מוצג כערך מספרי מהסוג Integer.

כדי ליצור פורמט בהתאמה אישית:

  1. לוחצים לחיצה ימנית על ערך המשאב.
  2. בוחרים באפשרות הצגה בתור.
  3. בוחרים באפשרות יצירה.
  4. מוצגת תיבת הדו-שיח Java Data Type Renderers. פועלים לפי ההוראות במאמר בנושא Java Data type renderers.