Usar strace

Strace te permite ver las llamadas al sistema que realiza un proceso y lo que devuelven esas llamadas.

Compila strace

Para compilar Strace, ejecuta lo siguiente:

mmma -j6 external/strace

Adjuntar a un proceso en ejecución

El caso de uso más simple y común de strace es conectarlo a un proceso en ejecución, lo que puedes hacer con lo siguiente:

adb shell strace -f -p PID

La marca -f le indica a strace que se una a todos los subprocesos del proceso, además de los subprocesos nuevos que se generen más adelante.

Un proceso típico realiza muchas llamadas al sistema, por lo que te recomendamos que revises la página de man de strace para aprender a recopilar solo los datos que te interesan.

Usar en una app

Para usar strace en una app, haz lo siguiente:

  1. Configura el dispositivo para que puedas ejecutar strace. Debes tener permisos de root, inhabilitar SELinux y reiniciar el entorno de ejecución para quitar el filtro seccomp que, de lo contrario, impedirá que se ejecute strace:
    adb root
    adb shell setenforce 0
    adb shell stop
    adb shell start
    
  2. Configura un directorio de escritura pública para los registros de strace, ya que strace se ejecutará con el UID de la app:
    adb shell mkdir -m 777 /data/local/tmp/strace
    
  3. Elige el proceso para hacer el seguimiento y, luego, inícialo:
    adb shell setprop wrap.com.android.calendar '"logwrapper strace -f -o /data/local/tmp/strace/strace.com.android.calendar.txt"'
    
  4. Inicia el proceso de forma normal.

Cómo usar en el zigoto

Para usar strace en el zygote, corrige la línea init.rc relevante del zygote (requiere 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

Cómo obtener registros de strace durante el inicio de Android

Para obtener registros de strace durante el inicio de Android, realiza los siguientes cambios:

  • Dado que el nombre del proceso cambia de zygote a strace, es posible que el servicio determinado no se inicie debido a la falta de file_context de SELinux para strace. La solución es agregar una línea nueva para strace en system/sepolicy/private/file_contexts y copiar el contexto del archivo original. Ejemplo:
    /dev/socket/zygote      u:object_r:zygote_socket:s0
    + /system/bin/strace u:object_r:zygote_socket:s0
    
  • Agrega el parámetro kernel o bootconfig y, luego, inicia el dispositivo en el modo permisivo de SELinux. Para ello, agrega androidboot.selinux=permissive a BOARD_KERNEL_CMDLINE o a BOARD_BOOTCONFIG en Android 12 con la versión de kernel 5.10 o posterior. (Esta variable se convierte en de solo lectura en build/core/Makefile, pero siempre está disponible en /device/*/BoardConfig).

    Ejemplo para el dispositivo Pixel (sailfish) en /device/google/marlin/sailfish/BoardConfig.mk:
    - BOARD_KERNEL_CMDLINE := ....  androidboot.hardware=sailfish ...
    +BOARD_KERNEL_CMDLINE := ....  androidboot.hardware=sailfish ...  androidboot.selinux=permissive
    
    Después de realizar el cambio, compila y escribe en la memoria flash la imagen de inicio para que el dispositivo se inicie en modo permisivo.