במדריך הזה מופיעה סקירה כללית של הכלים והטכניקות החיוניים לניפוי באגים בשירותים ובאפליקציות שפועלים בפלטפורמת SDV.
התחברות למכשיר
הכלי העיקרי להתחברות למכשיר ולאינטראקציה איתו הוא ממשק הגישור של Android (ADB). מוודאים ש-adb נמצא בנתיב של המערכת.
התחברות באמצעות הרשת
אם המכשיר נמצא באותה רשת ואתם יודעים את כתובת ה-IP שלו, אתם יכולים להתחבר באמצעות אתרנט. המערכת שלנו משתמשת בחיבורי רשת רק עבור adb:
# Connect to the device using its IP address and default port
adb connect <device_ip_address>:5555
חיבור לכמה מכשירים
כדי לנהל כמה מכשירים מתחנת עבודה אחת, אפשר להתחבר אליהם באמצעות כתובות IP שונות. אם מריצים כמה מכונות וירטואליות במארח יחיד, צריך להקצות יציאות שונות לכל מכשיר. לשם כך צריך להגדיר את דמון adb בכל מכשיר SDV להאזנה ביציאה ייחודית, למשל 5555 למכשיר הראשון ו-5556 למכשיר השני. אפשר גם להגדיר את המארח להעביר את היציאות האלה לאורחים שונים:
# Connect to the first device
adb connect <device_1_ip_address>:5555
# Connect to a second device
adb connect <device_2_ip_address>:5555
# Connect to a second VM on first device on different port
adb connect <device_1_ip_address>:5556
# List all connected devices to verify
adb devices
כשמריצים פקודות adb נוספות, אפשר לטרגט מכשיר ספציפי באמצעות הדגל -s עם הכתובת המלאה שלו (ip:port):
# Run a shell command on the second VM on first device in the above example
adb -s <device_1_ip_address>:5556 shell
צפייה ביומנים
אם שירות נכשל או מתנהג בצורה לא צפויה, כדאי קודם לבדוק את היומנים.
שימוש ב-logcat (יומני Android)
logcat מציג יומנים משירותי מערכת, מסוכנים ומחבילות שירות:
# View all logs in real-time
adb logcat
# Filter logs by a specific tag (e.g., the name of your service)
adb logcat -s MyServiceTag
# Filter logs by priority (V: Verbose, D: Debug, I: Info, W: Warn, E: Error, F: Fatal)
# This shows only Error and Fatal messages for a specific tag
adb logcat MyServiceTag:E *:S
# Clear old logs before viewing new ones
adb logcat -c && adb logcat
# Show all logs and return
adb logcat -d
# Color logs by level
adb logcat -v color
# Show timestamps as time since boot
adb logcat -v monotonic
שימוש ב-dmesg (יומני ליבה)
dmesg מציג יומנים מליבת Linux. זה חשוב לניפוי הבאגים של הפעולות הבאות:
- בעיות בחומרה ובדרייברים
- תגובה לשגיאת ליבה קריטית
- דחיות של SELinux (
avc: denied) – מוצגות גם ב-logcat
# View all kernel messages
adb shell dmesg
# Follow kernel messages in real-time
adb shell dmesg -w
יומני גישה ב-Cuttlefish
כשמריצים במכשיר וירטואלי של Cuttlefish, אפשר לגשת ישירות לקובצי היומן ממערכת הקבצים של המכונה המארחת. האפשרות הזו שימושית במיוחד אם adb לא זמין. כשמפעילים את Cuttlefish, הוא מציג את כל נתיבי הניפוי באגים, ואפשר גם לחפש אותם באמצעות cvd fleet לכל המופעים הפועלים.
- Logcat (יומני Android):
cuttlefish/instances/cvd-1/logs/logcat - יומני ליבה:
cuttlefish/instances/cvd-1/logs/kernel.log - יומנים של Cuttlefish Launcher:
cuttlefish/instances/cvd-1/logs/launcher.log(שימושי לניפוי באגים בסביבת Cuttlefish עצמה)
אפשר להשתמש בכלי שורת פקודה רגילים כמו cat, less או tail -f כדי לראות את הקבצים האלה בזמן אמת.
אינטראקציה עם המעטפת ומערכת הקבצים
קבלת גישת Shell כדי להריץ פקודות ישירות במכשיר, בדיקת סטטוס התהליך וניווט במערכת הקבצים:
# Open an interactive shell on the device
adb shell
# From within the shell, you can check running processes
ps -A
# Or check the status of a specific service managed by init
getprop init.svc.<service_name>
ביצוע פעולות במערכת הקבצים
משתמשים ב-adb push וב-adb pull כדי להעביר קבצים בין המחשב המארח לבין המכשיר. אפשר להשתמש בזה כדי לפרוס סקריפטים לבדיקה, לעדכן את ההגדרות או לאחזר קובצי dump של קריסות:
# Push a file from your computer to the device
adb push my_local_file.txt /data/local/tmp/
# Pull a file from the device to your computer
adb pull /data/tombstones/tombstone_00 .
ניפוי באגים באפליקציות (C++/Rust)
אפשר לבצע ניפוי באגים באפליקציות אונליין או אופליין.
שימוש ב-lldb לניפוי באגים בזמן אמת
lldb הוא כלי ניפוי הבאגים שמוגדר כברירת מחדל ב-Android Studio, ולרוב הוא מועדף לפיתוח מודרני של C++ ו-Rust.
מבצעים את שלבי ההגדרה הבאים:
מפעילים מחדש את adb כדי לאפשר הרשאות root (נדרש להעברה). אפשר להשתמש באפשרות הזו כדי להגדיר העברה ליציאה אחרת. במארח, מריצים את הפקודה:
adb rootאם קובץ בינארי מכיל סמלים לניפוי באגים, צריך לשלוח גרסה לא מופשטת. אפשר למצוא את הגרסה הלא מצונזרת בכתובת
out/target/product/[SDV_FLAVOR]/symbols/[PARTITION]/bin/[EXECUTABLE]. לדוגמה, כדי להעלות אתrpcagentמ-system_extומ-sdv_core_cf, מריצים:adb push out/target/product/sdv_core_cf/symbols/system_ext/bin/rpcagent /data/local/tmpהגרסה הלא-מצומצמת נמצאת עכשיו ב
/data/local/tmp.מתחברים ללקוח LLDB באמצעות סקריפט הנוחות
lldbclient.py:# Run and connect a binary on device, run on host: lldbclient.py -r /data/local/tmp/rpcagent # Connect to an existing process with PID 2759 lldbclient.py -p 2759הסקריפט הזה מתחבר ל-lldb מרחוק. כדי לראות את כל הדגלים הזמינים, מריצים את הפקודה
lldbclient.py. כדי לחבר את סביבת הפיתוח המשולבת (IDE) ל-lldb, צריך לעיין בתיעוד של סביבת הפיתוח המשולבת.
ניתוח קובצי dump של קריסות (tombstones)
כששירות קורס, נוצר קובץ tombstone ב-/data/tombstones/.
הקובץ מכיל דוח קריסות, מפת זיכרון ומידע חשוב אחר.
מושכים את קובץ ה-tombstone ואז משתמשים בכלי שמודע לסמלים (כמו lldb או סקריפט ייעודי) כדי לנתח אותו עם הגרסה הלא מוסרת של הקובץ הבינארי.
ניתוח הביצועים
SDV תומך בכמה כלים למדידת ביצועים.
בדיקת השימוש במעבד (CPU) ובזיכרון
top: מספק תצוגה בזמן אמת של תהליכים שפועלים, ממוינים לפי השימוש ב-CPU.adb shell top -m 10 # Show top 10 processes
procrank: מספק פירוט של השימוש בזיכרון לתהליך ספציפי או לכל המערכת.adb shell procrank
שימוש ב-dumpsys למצב השירות
dumpsys הוא כלי רב עוצמה לשאילתות לגבי המצב הפנימי של כל שירות במערכת Android.
# List all available services
adb shell dumpsys -l
# Dump the state of a specific service or agent
adb shell dumpsys <service_name>
שימוש ב-Torq לניתוח ביצועים
torq הוא כלי שורת פקודה שמפשט את משימות הפרופיל והמעקב ב-Android. הוא מאפשר להריץ את Simpleperf, Perfetto ומשימות אופייניות אחרות במהלך ניתוח ביצועי המערכת.
שימוש ב-Perfetto למעקב
Perfetto הוא הכלי הסטנדרטי למעקב בכל המערכת ב-Android. Perfetto מאפשר לכם להקליט אירועים במערכת, נקודות מעקב ברמת האפליקציה ומוני ביצועים, ולהציג אותם בציר זמן.
השלבים העיקריים:
- מוסיפים נקודות מעקב לקוד C++ או Rust:
- C++: שימוש ב-Perfetto SDK עם פקודות מאקרו
TRACE_EVENT. - Rust: משתמשים ב-
tracingcrate, שפולט אירועי ATrace שתואמים ל-Perfetto.
- C++: שימוש ב-Perfetto SDK עם פקודות מאקרו
- יוצרים קובץ הגדרה מסוג textproto כדי לציין מקורות נתונים (לדוגמה,
ftrace,track_event), קטגוריות ותגים. - משתמשים בסקריפט
record_android_trace(external/perfetto/tools/record_android_trace) עם קובץ ההגדרות כדי לתעד את נתוני המעקב מהמכשיר. - פותחים את קובץ המעקב שנוצר בממשק המשתמש האינטרנטי של Perfetto כדי לנתח את התנהגות המערכת, לזהות צווארי בקבוק ולהבין את האינטראקציות בין השירותים.
הוראות מפורטות לגבי מכשור, הגדרה ואיסוף זמינות במאמר שימוש במעקב כדי לקבל תובנות לגבי ביצועי המערכת.
שימוש ב-Simpleperf ליצירת פרופילים
Simpleperf הוא כלי רב-תכליתי לשורת הפקודה ליצירת פרופיל ביצועים ב-Android, בדומה ל-perf ב-Linux.
תרחישים נפוצים לדוגמה:
- התאמה לפרופיל של יחידת העיבוד המרכזית (CPU): זיהוי פונקציות שצורכות את רוב הזמן של יחידת העיבוד המרכזית.
- ניתוח מחוץ ל-CPU: ניתוח הסיבות לכך ששרשורים נמצאים במצב שינה או חסימה.
- מונים של חומרה: גישה למוני ביצועים של חומרה.
פקודות לדוגמה:
# Go to simpleperf scripts
cd system/extras/simpleperf/scripts
# Profile system for 20 seconds and record call graph
./app_profiler.py --system_wide -r "--call-graph fp --duration 20"
# Record a profile for a specific process (PID 1)
./app_profiler.py --pid 1 -r "--call-graph fp --duration 5"
# Pull the profile data
adb pull /data/local/tmp/perf.data .
# Generate a report with symbol resolution
./report_html.py --add_source_code --source_dirs $ANDROID_BUILD_TOP --add_disassembly -o report.html
ל-Simpleperf יש עוד הרבה אירועים ואפשרויות. במדריך Simpleperf יש תיעוד מקיף.
דחיות של SELinux
תיאור הבעיה: השירות לא מופעל, אין גישה לקובץ או לא ניתן להשתמש ביכולת מסוימת, ומופיעה הודעה avc: denied ב-dmesg או ב-logcat.
[ 123.456] avc: denied { read } for pid=789 comm="my_service" name="some_file" dev="sda1" ino=123 scontext=u:r:my_service_t:s0 tcontext=u:object_r:some_file_t:s0 tclass=file permissive=0
ניפוי באגים מהיר (לפיתוח בלבד)
אפשר להשבית באופן זמני את האכיפה של SELinux כדי לבדוק אם הבעיה נפתרה. ההודעה הזו מאשרת שהבעיה נובעת מכלל מדיניות SELinux חסר.
# Disabling SELinux requires root permission
adb root
# Set SELinux to permissive mode
adb shell setenforce 0
# Check the current mode (should return "Permissive")
adb shell getenforce
תיקון: כדאי להשתמש בכלי audit2allow מעץ המקור של Android בהודעת הדחייה. כך נוצר כלל המדיניות .te הנכון שצריך להוסיף להגדרת SELinux של המכשיר.