Usar strace

O Strace permite conferir as chamadas do sistema que um processo faz e o que elas retornam.

Criar strace

Para criar o strace, execute o seguinte:

mmma -j6 external/strace

Anexar a um processo em execução

O caso de uso mais simples e comum de strace é anexá-lo a um processo em execução, o que pode ser feito com:

adb shell strace -f -p PID

A flag -f instrui o strace a se conectar a todas as linhas de execução no processo, além de novas linhas de execução geradas mais tarde.

Um processo típico faz muitas chamadas de sistema. Por isso, é recomendável consultar a página de manual do strace para saber como coletar apenas os dados de seu interesse.

Usar em um app

Para usar o strace em um app:

  1. Configure o dispositivo para executar o strace. É necessário ter acesso root, desativar o SELinux e reiniciar o ambiente de execução para remover o filtro seccomp, que impede a execução do strace:
    adb root
    adb shell setenforce 0
    adb shell stop
    adb shell start
    
  2. Configure um diretório gravável globalmente para logs de strace, porque o strace será executado no UID do app:
    adb shell mkdir -m 777 /data/local/tmp/strace
    
  3. Escolha o processo a ser rastreado e inicie-o:
    adb shell setprop wrap.com.android.calendar '"logwrapper strace -f -o /data/local/tmp/strace/strace.com.android.calendar.txt"'
    
  4. Inicie o processo normalmente.

Uso no zigoto

Para usar o strace no zigoto, corrija a linha init.rc relevante do zigoto (requer 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

Receber registros de strace durante a inicialização do Android

Para acessar os registros de strace durante a inicialização do Android, faça as seguintes mudanças:

  • Como o nome do processo muda de zygote para strace, o serviço fornecido pode não ser iniciado devido à ausência do SELinux file_context para strace. A solução é adicionar uma nova linha para strace em system/sepolicy/private/file_contexts e copiar o contexto do arquivo original. Exemplo:
    /dev/socket/zygote      u:object_r:zygote_socket:s0
    + /system/bin/strace u:object_r:zygote_socket:s0
    
  • Adicione o parâmetro do kernel ou do bootconfig e inicialize o dispositivo no modo permissivo do SELinux. Para fazer isso, adicione androidboot.selinux=permissive a BOARD_KERNEL_CMDLINE ou a BOARD_BOOTCONFIG no Android 12 com a versão 5.10 ou mais recente do kernel. Essa variável se torna somente leitura em build/core/Makefile, mas está sempre disponível em /device/*/BoardConfig.

    Exemplo para o dispositivo Pixel (sailfish) em /device/google/marlin/sailfish/BoardConfig.mk:
    - BOARD_KERNEL_CMDLINE := ....  androidboot.hardware=sailfish ...
    +BOARD_KERNEL_CMDLINE := ....  androidboot.hardware=sailfish ...  androidboot.selinux=permissive
    
    Depois de fazer a mudança, crie e transfira a imagem de inicialização. O dispositivo será inicializado no modo permissivo.