Depurar SDV

Este guia apresenta uma visão geral das ferramentas e técnicas essenciais para depurar serviços e aplicativos executados na plataforma SDV.

Conectar ao dispositivo

A principal ferramenta para se conectar e interagir com o dispositivo é o Android Debug Bridge (adb). Verifique se adb está no caminho do sistema.

Conectar usando a rede

Se o dispositivo estiver na mesma rede e você souber o endereço IP dele, será possível se conectar por Ethernet. Nosso sistema usa exclusivamente conexões de rede para o adb:

# Connect to the device using its IP address and default port
adb connect <device_ip_address>:5555

Conectar a vários dispositivos

Para gerenciar vários dispositivos em uma única estação de trabalho, conecte-se a eles usando endereços IP diferentes. Se você executar várias VMs em um único host, atribua portas diferentes a cada dispositivo. Isso requer a configuração do daemon do adb em cada dispositivo SDV para detectar uma porta exclusiva, por exemplo, 5555 para o primeiro dispositivo e 5556 para o segundo. Também é possível configurar o host para encaminhar essas portas para diferentes convidados:

# Connect to the first device
adb connect <device_1_ip_address>:5555

# Connect to a second device
adb connect <device_2_ip_address>:5555

# Connect to a second VM on first device on different port
adb connect <device_1_ip_address>:5556

# List all connected devices to verify
adb devices

Ao executar os comandos adb subsequentes, é possível segmentar um dispositivo específico usando a flag -s com o endereço completo (ip:port):

# Run a shell command on the second VM on first device in the above example
adb -s <device_1_ip_address>:5556 shell

Ver registros

Quando um serviço falha ou se comporta de maneira inesperada, verifique os registros primeiro.

Usar o logcat (registros do Android)

logcat exibe registros de serviços do sistema, agentes e pacotes de serviços:

# View all logs in real-time
adb logcat

# Filter logs by a specific tag (e.g., the name of your service)
adb logcat -s MyServiceTag

# Filter logs by priority (V: Verbose, D: Debug, I: Info, W: Warn, E: Error, F: Fatal)
# This shows only Error and Fatal messages for a specific tag
adb logcat MyServiceTag:E *:S

# Clear old logs before viewing new ones
adb logcat -c && adb logcat

# Show all logs and return
adb logcat -d

# Color logs by level
adb logcat -v color

# Show timestamps as time since boot
adb logcat -v monotonic

Usar dmesg (registros do kernel)

dmesg mostra registros do kernel do Linux. Isso é crucial para depurar o seguinte:

  • Problemas de hardware e driver
  • Kernel panics
  • Negações do SELinux (avc: denied), também exibidas no logcat
# View all kernel messages
adb shell dmesg

# Follow kernel messages in real-time
adb shell dmesg -w

Acessar registros no Cuttlefish

Ao executar em um dispositivo virtual Cuttlefish, é possível acessar diretamente os arquivos de registro do sistema de arquivos da máquina host. Isso é especialmente útil se adb não estiver disponível. Quando você inicia o Cuttlefish, ele gera todos os caminhos de depuração, e você também pode procurá-los usando cvd fleet para todas as instâncias em execução.

  • Logcat (registros do Android): cuttlefish/instances/cvd-1/logs/logcat
  • Registros do kernel:cuttlefish/instances/cvd-1/logs/kernel.log
  • Registros do inicializador do Cuttlefish:cuttlefish/instances/cvd-1/logs/launcher.log (útil para depurar o próprio ambiente do Cuttlefish)

É possível usar ferramentas de linha de comando padrão, como cat, less ou tail -f, para visualizar esses arquivos em tempo real.

Interagir com o shell e o sistema de arquivos

Acesse o shell para executar comandos diretamente no dispositivo, verificar o status do processo e navegar no sistema de arquivos:

# Open an interactive shell on the device
adb shell

# From within the shell, you can check running processes
ps -A

# Or check the status of a specific service managed by init
getprop init.svc.<service_name>

Realizar operações do sistema de arquivos

Use adb push e adb pull para mover arquivos entre a máquina host e o dispositivo. Use isso para implantar scripts de teste, atualizar a configuração ou recuperar crash dumps:

# Push a file from your computer to the device
adb push my_local_file.txt /data/local/tmp/

# Pull a file from the device to your computer
adb pull /data/tombstones/tombstone_00 .

Depurar aplicativos (C++/Rust)

É possível depurar aplicativos on-line ou off-line.

Usar o lldb para depuração em tempo real

Siga estas etapas para depurar um serviço em tempo real usando lldb (para anexar o depurador do Android Studio para Plataforma, consulte Depurar e testar e Depurar código da plataforma):

  1. Reinicie o adb com permissões raiz (necessárias para o encaminhamento de portas):

    adb root
    
  2. Se um binário tiver símbolos de depuração, envie uma versão não removida de out/target/product/[SDV_FLAVOR]/symbols/[PARTITION]/bin/[EXECUTABLE]. Por exemplo, para fazer upload de rpcagent de system_ext e sdv_core_cf, execute:

    adb push out/target/product/sdv_core_cf/symbols/system_ext/bin/rpcagent /data/local/tmp
    
  3. Conecte-se ao cliente LLDB usando o script de conveniência lldbclient.py:

    # Run and connect a binary on device, run on host:
    lldbclient.py -r /data/local/tmp/rpcagent
    
    # Connect to an existing process with PID 2759
    lldbclient.py -p 2759
    

    Esse script conecta o lldb remotamente. Para ver todas as flags disponíveis, execute lldbclient.py --help.

Analisar crash dumps (tombstones)

Quando um serviço falha, um arquivo tombstone é gerado em /data/tombstones/. O arquivo contém um stack trace, um mapa de memória e outras informações importantes.

Extraia o arquivo de tombstone e use uma ferramenta que reconheça símbolos (como lldb ou um script dedicado) para analisá-lo com a versão não removida do binário.

Analisar desempenho

O SDV é compatível com várias ferramentas para medições de desempenho.

Verificar o uso de CPU e memória

  • top: fornece uma visualização em tempo real dos processos em execução classificados pelo uso da CPU.

    adb shell top -m 10  # Show top 10 processes
    
  • procrank: fornece um detalhamento do uso da memória para um processo específico ou para todo o sistema.

    adb shell procrank
    

Usar dumpsys para o estado do serviço

dumpsys é uma ferramenta poderosa para consultar o estado interno de qualquer serviço do sistema Android.

# List all available services
adb shell dumpsys -l

# Dump the state of a specific service or agent
adb shell dumpsys <service_name>

Usar o torq para análise de desempenho

A torq é uma ferramenta de linha de comando que simplifica as tarefas de criação de perfil e rastreamento no Android. Ele permite executar o Simpleperf, o Perfetto e outras tarefas típicas durante a análise de desempenho do sistema.

Usar o Perfetto para rastreamento

O Perfetto é a ferramenta padrão para rastreamento em todo o sistema no Android. O Perfetto permite registrar eventos do sistema, pontos de rastreamento no nível do app e contadores de desempenho, além de visualizá-los em uma linha do tempo.

Etapas principais:

  1. Adicione pontos de trace no código C++ ou Rust:
    • C++:use o SDK do Perfetto com macros TRACE_EVENT.
    • Rust:use o crate tracing, que emite eventos do ATrace compatíveis com o Perfetto.
  2. Crie um arquivo de configuração textproto para especificar fontes de dados (por exemplo, ftrace, track_event), categorias e tags.
  3. Use o script record_android_trace (external/perfetto/tools/record_android_trace) com o arquivo de configuração para capturar o rastro do dispositivo.
  4. Abra o arquivo de trace gerado na interface da Web do Perfetto para analisar o comportamento do sistema, identificar gargalos e entender as interações de serviço.

Para instruções detalhadas sobre instrumentação, configuração e coleta, consulte Usar o rastreamento para receber insights sobre o desempenho do sistema.

Usar o Simpleperf para criação de perfil

O Simpleperf é uma ferramenta de linha de comando versátil para criação de perfil de desempenho no Android, semelhante ao perf do Linux.

Casos de uso comuns:

  • Criação de perfil de CPU: identifique as funções que consomem mais tempo de CPU.
  • Análise fora da CPU: analise por que as linhas de execução estão em suspensão ou bloqueadas.
  • Contadores de hardware: acesse contadores de desempenho de hardware.

Exemplos de comandos:

# Go to simpleperf scripts
cd system/extras/simpleperf/scripts

# Profile system for 20 seconds and record call graph
./app_profiler.py --system_wide -r "--call-graph fp --duration 20"

# Record a profile for a specific process (PID 1)
./app_profiler.py --pid 1 -r "--call-graph fp --duration 5"

# Pull the profile data
adb pull /data/local/tmp/perf.data .

# Generate a report with symbol resolution
./report_html.py --add_source_code --source_dirs $ANDROID_BUILD_TOP --add_disassembly -o report.html

O Simpleperf oferece muitos outros eventos e opções. Consulte o guia do Simpleperf para ver a documentação completa.

Negações do SELinux

Sintoma: o serviço não é iniciado, não acessa um arquivo ou não usa um recurso, e você vê uma mensagem avc: denied em dmesg ou logcat.

[ 123.456] avc: denied { read } for pid=789 comm="my_service" name="some_file" dev="sda1" ino=123 scontext=u:r:my_service_t:s0 tcontext=u:object_r:some_file_t:s0 tclass=file permissive=0

Depuração rápida (somente para desenvolvimento)

É possível desativar temporariamente a aplicação do SELinux para ver se o problema é resolvido. Isso confirma que o problema é causado por uma regra de política do SELinux ausente.

# Disabling SELinux requires root permission
adb root

# Set SELinux to permissive mode
adb shell setenforce 0

# Check the current mode (should return "Permissive")
adb shell getenforce

Correção: a ferramenta audit2allow da árvore de origem do Android na mensagem de negação. Isso gera a regra de política .te correta para adicionar à configuração do SELinux do dispositivo.