Usa 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

Cómo adjuntar el depurador a un proceso en ejecución

El caso de uso más sencillo y común de strace es adjuntarlo a un servicio en ejecución proceso, el cual puedes hacer con lo siguiente:

adb shell strace -f -p PID

La marca -f le indica a strace que se adjunte a todos los subprocesos del completo, y cualquier subproceso nuevo generado más adelante.

En un proceso típico se realizan muchas llamadas al sistema. página del manual de strace para aprender a recopilar solo los datos que realmente 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 que admita escritura pública para los registros de strace, ya que este se ejecutará en el UID de la aplicación:
    adb shell mkdir -m 777 /data/local/tmp/strace
    
  3. Elige el proceso que quieres rastrear 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.

Usar en Zygote

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 que falta 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 kernel o el parámetro 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.