Usa Strace

Strace consente di visualizzare le chiamate di sistema effettuate da un processo e il relativo ritorno.

Crea strace

Per compilare strace, esegui il seguente comando:

mmma -j6 external/strace

Eseguire il collegamento a un processo in esecuzione

Il caso d'uso più semplice e più comune per lo strace è collegarlo a un processo in esecuzione, cosa che puoi fare con:

adb shell strace -f -p PID

Il flag -f indica a strace di collegarsi a tutti i thread nel processo, oltre a eventuali nuovi thread generati in un secondo momento.

Un processo tipico esegue molte chiamate di sistema, quindi ti consigliamo di consultare la pagina di manuali di strace per scoprire come raccogliere solo i dati che ti interessano.

Utilizzo in un'app

Per usare Strace su un'app:

  1. Configura il dispositivo in modo da poter eseguire strace. Devi avere i privilegi di root, disattivare SELinux e riavviare il runtime per rimuovere il filtro seccomp che altrimenti impedirebbe l'esecuzione di strace:
    adb root
    adb shell setenforce 0
    adb shell stop
    adb shell start
    
  2. Configura una directory con accesso in scrittura per tutti per i log di strace, perché strace verrà eseguito con l'UID dell'app:
    adb shell mkdir -m 777 /data/local/tmp/strace
    
  3. Scegli il processo da tracciare e avvialo:
    adb shell setprop wrap.com.android.calendar '"logwrapper strace -f -o /data/local/tmp/strace/strace.com.android.calendar.txt"'
    
  4. Avvia normalmente la procedura.

Utilizzo su zygote

Per utilizzare strace su zygote, correggi la riga init.rc zygote pertinente (richiede 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

Ottenere i log di strace durante l'avvio di Android

Per ottenere i log di strace durante l'avvio di Android, apporta le seguenti modifiche:

  • Poiché il nome del processo cambia da zygote a strace, il servizio specificato potrebbe non avviarsi a causa della mancanza di file_context SELinux per strace. La soluzione è aggiungere una nuova riga per strace in system/sepolicy/private/file_contexts e copiare il contesto del file originale. Esempio:
    /dev/socket/zygote      u:object_r:zygote_socket:s0
    + /system/bin/strace u:object_r:zygote_socket:s0
    
  • Aggiungi il parametro kernel o bootconfig, quindi avvia il dispositivo in modalità permissiva SELinux. Per farlo, puoi aggiungere androidboot.selinux=permissive a BOARD_KERNEL_CMDLINE o a BOARD_BOOTCONFIG in Android 12 con kernel 5.10 o versioni successive. Questa variabile diventa di sola lettura in build/core/Makefile, ma è sempre disponibile in /device/*/BoardConfig.

    Esempio per il dispositivo Pixel (sailfish) in /device/google/marlin/sailfish/BoardConfig.mk:
    - BOARD_KERNEL_CMDLINE := ....  androidboot.hardware=sailfish ...
    +BOARD_KERNEL_CMDLINE := ....  androidboot.hardware=sailfish ...  androidboot.selinux=permissive
    
    Dopo aver apportato la modifica, compila e esegui il flashing dell'immagine di avvio e il dispositivo verrà avviato in modalità permissiva.