Utilizzare strace

Strace consente di visualizzare le chiamate di sistema effettuate da un processo e i valori restituiti da queste chiamate.

Creare strace

Per creare strace, esegui il comando seguente:

mmma -j6 external/strace

Collegare a un processo in esecuzione

Il caso d'uso più semplice e comune di 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 del processo, nonché a tutti i nuovi thread generati in un secondo momento.

Un processo tipico effettua molte chiamate di sistema, quindi ti consigliamo di consultare la pagina man di strace per scoprire come raccogliere solo i dati di tuo interesse.

Utilizzare su un'app

Per utilizzare strace su un'app:

  1. Configura il dispositivo in modo da poter eseguire strace. Devi essere 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 autorizzazioni di 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 di cui eseguire la traccia e avvialo:
    adb shell setprop wrap.com.android.calendar '"logwrapper strace -f -o /data/local/tmp/strace/strace.com.android.calendar.txt"'
    
  4. Avvia il processo normalmente.

Utilizzare su zygote

Per utilizzare strace su zygote, correggi la riga zygote init.rc 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 essere avviato a causa del file_context SELinux mancante per strace. La soluzione consiste nell'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 del kernel o di bootconfig, quindi avvia il dispositivo in modalità permissiva SELinux. Puoi farlo aggiungendo androidboot.selinux=permissive a BOARD_KERNEL_CMDLINE o a BOARD_BOOTCONFIG in Android 12 con la versione kernel 5.10 o 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, crea ed esegui il flashing dell'immagine di avvio e il dispositivo verrà avviato in modalità permissiva.