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

ב-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.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

זיהוי אוטומטי
בוחרים בסוג הניפוי הזה אם רוצים ש-Android Studio יבחר אוטומטית את האפשרות הכי טובה לקוד שמנפים בו באגים. לדוגמה, אם יש לכם קוד C או C++ בפרויקט, Android Studio משתמש אוטומטית בסוג ניפוי הבאגים הכפול. אחרת, Android Studio משתמש בסוג הניפוי באגים Java-Only.
Java בלבד
בוחרים בסוג הניפוי הזה אם רוצים לנפות באגים רק בקוד שנכתב ב-Java או ב-Kotlin. המאפיין Java-Only debugger מתעלם מכל נקודות העצירה או ההשגחה שהגדרתם בקוד Native.
מותאמות בלבד (זמין רק עם קוד C/C++)
בוחרים בסוג הניפוי הזה אם רוצים להשתמש רק ב-LLDB כדי לנפות באגים בקוד. כשמשתמשים בסוג הניפוי הזה, התצוגה של סשן ניפוי הבאגים של Java לא זמינה. כברירת מחדל,‏ LLDB בודק רק את קוד Native ומתעלם מנקודות עצירה בקוד 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 וקוד Native. ‫Android Studio מצרף את מאתר הבאגים של Java ואת LLDB לתהליך של האפליקציה, כך שתוכלו לבדוק נקודות עצירה גם בקוד Java וגם בקוד Native בלי להפעיל מחדש את האפליקציה או לשנות את הגדרות הבאגים.

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

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

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

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

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

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

כדי לכתוב הודעות ביומן בקוד, משתמשים במחלקה 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) של שיטה
A method breakpoint (נקודת עצירה של method) משהה את ההרצה של האפליקציה כשנכנסים ל-method ספציפי או יוצאים ממנו. בזמן ההשהיה, אפשר לבדוק משתנים, להעריך ביטויים ואז להמשיך בהרצה שורה אחר שורה כדי לקבוע את הסיבות לשגיאות זמן הריצה. כשמגדירים נקודת עצירה בפונקציה קומפוזבילית, מאתר הבאגים מציג את הפרמטרים של הקומפוזבילית ואת הערך הדינמי שלהם, כדי לעזור לזהות אילו שינויים גרמו לרה-קומפוזיציה.
נקודת עצירה (breakpoint) בשדה
נקודת עצירה בשדה משהה את ההפעלה של האפליקציה כשהיא קוראת משדה ספציפי או כותבת בו.
נקודת עצירה (breakpoint) לחריג
נקודת עצירה לחריגה משהה את ההרצה של האפליקציה כשמופעלת חריגה.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

בדיקת משתנים

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    • 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.