שימוש ב-strace

Strace מאפשר לכם לראות את קריאות המערכת שתהליך מבצע ואת מה שקריאות המערכת האלה מחזירות.

Build strace

כדי ליצור את strace, מריצים את הפקודה הבאה:

mmma -j6 external/strace

צירוף לתהליך שפועל

תרחיש השימוש הכי פשוט ונפוץ ב-strace הוא צירוף שלו לתהליך שפועל, ואפשר לעשות את זה באמצעות הפקודה:

adb shell strace -f -p PID

הדגל -f אומר ל-strace להצמיד את עצמו לכל השרשורים בתהליך, וגם לכל שרשור חדש שנוצר מאוחר יותר.

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

שימוש באפליקציה

כדי להשתמש ב-strace באפליקציה:

  1. מגדירים את המכשיר כך שאפשר יהיה להריץ את strace. כדי להסיר את מסנן seccomp שמונע את ההפעלה של strace, צריך להיות משתמש root, להשבית את SELinux ולהפעיל מחדש את זמן הריצה:
    adb root
    adb shell setenforce 0
    adb shell stop
    adb shell start
    
  2. מגדירים ספרייה עם הרשאות כתיבה לכל העולם עבור יומני strace, כי strace יפעל תחת מזהה המשתמש של האפליקציה:
    adb shell mkdir -m 777 /data/local/tmp/strace
    
  3. בוחרים את התהליך שרוצים לעקוב אחריו ומפעילים אותו:
    adb shell setprop wrap.com.android.calendar '"logwrapper strace -f -o /data/local/tmp/strace/strace.com.android.calendar.txt"'
    
  4. מפעילים את התהליך כרגיל.

שימוש ב-zygote

כדי להשתמש ב-strace ב-zygote, צריך לתקן את השורה הרלוונטית של init.rc zygote (נדרש adb shell setenforce 0):

cd system/core/
patch -p1 <<EOF
--- a/rootdir/init.zygote32.rc
+++ b/rootdir/init.zygote32.rc
@@ -1,4 +1,4 @@
-service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
+service zygote /system/bin/strace -o /data/local/tmp/zygote.strace /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
     class main
     socket zygote stream 660 root system
     onrestart write /sys/android_power/request_state wake
EOF

קבלת יומני strace במהלך האתחול של Android

כדי לקבל יומני strace במהלך אתחול של Android, מבצעים את השינויים הבאים:

  • מכיוון ששם התהליך משתנה מ-zygote ל-strace, יכול להיות שהשירות שצוין לא יופעל בגלל חוסר ב-SELinux file_context עבור strace. הפתרון הוא להוסיף שורה חדשה ל-strace ב-system/sepolicy/private/file_contexts ולהעתיק את ההקשר המקורי של הקובץ. דוגמה:
    /dev/socket/zygote      u:object_r:zygote_socket:s0
    + /system/bin/strace u:object_r:zygote_socket:s0
    
  • מוסיפים פרמטר של ליבת המערכת או של bootconfig, ואז מפעילים את המכשיר במצב הרשאה של SELinux. כדי לעשות את זה, מוסיפים androidboot.selinux=permissiveל-BOARD_KERNEL_CMDLINE או ל-BOARD_BOOTCONFIG ב-Android מגרסה 12 עם ליבה בגרסה 5.10 ומעלה. (המשתנה הזה הופך לקריאה בלבד ב-build/core/Makefile, אבל הוא תמיד זמין ב-/device/*/BoardConfig).

    דוגמה למכשיר Pixel‏ (sailfish) ב-/device/google/marlin/sailfish/BoardConfig.mk:
    - BOARD_KERNEL_CMDLINE := ....  androidboot.hardware=sailfish ...
    +BOARD_KERNEL_CMDLINE := ....  androidboot.hardware=sailfish ...  androidboot.selinux=permissive
    
    אחרי שמבצעים את השינוי, יוצרים וצורבים את תמונת האתחול והמכשיר יאתחל במצב הרשאה.