שימוש ב-strace

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

איך יוצרים strace

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

mmma -j6 external/strace

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

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

adb shell strace -f -p PID

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

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

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

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

  1. מגדירים את המכשיר כך שאפשר יהיה להריץ את strace. צריך להיות משתמש root, להשבית את SELinux ולהפעיל מחדש את זמן הריצה כדי להסיר את מסנן seccomp, אחרת אי אפשר להפעיל את strace:
    adb root
    adb shell setenforce 0
    adb shell stop
    adb shell start
    
  2. מגדירים ספרייה עם הרשאת כתיבה לכל המשתמשים ליומני strace, כי strace יפעל תחת uid של האפליקציה:
    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
    
    אחרי שמבצעים את השינוי, יוצרים וצובים את תמונת האתחול והמכשיר יאתחל במצב הרשאה.