ndk-gdb

O NDK inclui um script de shell chamado ndk-gdb para iniciar uma sessão de depuração nativa da linha de comando. Os usuários que preferem usar uma GUI precisam ler a documentação sobre depuração no Android Studio.

Requisitos

Para que a depuração nativa da linha de comando funcione, estes requisitos precisam ser atendidos:

  • Crie seu app usando o script ndk-build. O script ndk-gdb não é compatível com o uso do métodomake APP=<name> legado para criar.
  • Ative a depuração do app no arquivo AndroidManifest.xml, incluindo um elemento <application> que defina o atributo android:debuggable como true.
  • Crie seu app para ser executado no Android 2.2 (API do Android de nível 8) ou versões mais recentes.
  • Depure em um dispositivo ou emulador que execute o Android 2.2 ou versões mais recentes. Para fins de depuração, o nível da API selecionado que você declara no arquivo AndroidManifest.xml não é importante.
  • Desenvolva seu app em um shell do Unix. No Windows, use Cygwin ou a implementação Python experimental de ndk-gdb-py (links em inglês).
  • Use o GNU Make 3.81 ou versão mais recente.

Uso

Para invocar o script ndk-gdb, mude para o diretório do app ou qualquer diretório dentro dele. Exemplo:

cd $PROJECT
$NDK/ndk-gdb

Nesse exemplo, $PROJECT aponta para o diretório raiz do seu projeto, e $NDK aponta para o caminho de instalação do NDK.

Quando você invoca ndk-gdb, ele configura a sessão para buscar arquivos de origem e versões de símbolo/depuração das suas bibliotecas nativas geradas. Depois de anexado ao processo do app, o ndk-gdb produz uma longa série de mensagens de erro notificando que não foi possível encontrar diversas bibliotecas do sistema. Isso é normal, porque a máquina host não contém versões de símbolo/depuração dessas bibliotecas no dispositivo de destino. Você pode ignorar totalmente essas mensagens.

Em seguida, ndk-gdb exibe uma solicitação normal do GDB.

A interação com ndk-gdb ocorre da mesma forma que com o GDB GNU. Por exemplo, é possível usar b <location> para definir pontos de interrupção e c (de "continuar") para retomar a execução. Para ver uma lista completa de comandos, consulte o manual do GDB (link em inglês). Se você preferir usar o LLDB Debugger (link em inglês), use a opção --lldb ao invocar o script ndk-gdb.

Quando você sai da solicitação do GDB, o processo do app que está sendo depurado é interrompido. Esse comportamento é uma limitação do GDB.

ndk-gdb processa muitas condições de erro e exibe uma mensagem de erro informativa se encontra algum problema. Essas verificações incluem garantir que as condições a seguir sejam atendidas:

  • Verifica se o adb está no seu caminho.
  • Verifica se o app está declarado como depurável no manifesto.
  • Verifica, no dispositivo, se o app instalado com o mesmo nome de pacote também é depurável.

Por padrão, ndk-gdb busca um processo de app já em execução e exibe um erro caso não encontre um. No entanto, você pode usar a opção --start ou --launch=<name> para iniciar automaticamente sua atividade antes da sessão de depuração. Para saber mais, consulte Opções.

Opções

Para ver uma lista completa de opções, digite ndk-gdb --help na linha de comando. A Tabela 1 mostra várias das opções mais comumente usadas, com descrições breves.

Tabela 1. Opções comuns de ndk-gdb e as descrições delas.

Iniciar ndk-gdb com essa opção especificada inicializa a primeira atividade inicializável listada no manifesto do seu app. Use --launch=<name> para iniciar a próxima atividade inicializável. Para fazer o despejo da lista de atividades inicializáveis, execute --launch-list na linha de comando.

Opção Descrição>
--lldb

Se definida, o script usará o LLDB Debugger para a sessão em vez do GDB.

--verbose

Essa opção manda o sistema de compilação gerar informações detalhadas sobre a configuração da sessão de depuração nativa. Ela é necessária somente para problemas de depuração quando o depurador não consegue se conectar ao app e as mensagens de erro que ndk-gdb exibe não são suficientes.

--force Por padrão, ndk-gdb faz o cancelamento se descobre que há outra sessão de depuração nativa em execução no mesmo dispositivo. Essa opção encerra e substitui a outra sessão por uma nova. Observe que essa opção não encerra o app em depuração, que você precisa encerrar separadamente.
--start

Por padrão, quando você inicia o ndk-gdb, ele tenta se conectar a uma instância já em execução do seu app no dispositivo de destino. É possível modificar esse comportamento padrão usando --start para inicializar o app explicitamente no dispositivo antes da sessão de depuração.

--launch=<name>

Essa opção é parecida com --start, mas permite iniciar uma atividade específica pelo app. Esse recurso só é útil se o manifesto tiver definido diversas atividades inicializáveis.

--launch-list

Essa opção conveniente gera uma lista com todos os nomes de atividades inicializáveis encontradas no manifesto do app. --start usa o primeiro nome da atividade.

--project=<path> Essa opção especifica o diretório do projeto do app. Ela é útil se você quiser inicializar o script sem precisar acessar primeiro o diretório do projeto.
--port=<port>

Por padrão, ndk-gdb usa a porta TCP 5039 local para se comunicar com o app que está depurando no dispositivo de destino. Usar uma porta diferente permite depurar nativamente programas em execução em diferentes dispositivos ou emuladores conectados à mesma máquina host.

--adb=<file>

Essa opção especifica a ferramenta adb executável. Ela só é necessária se você não tiver definido o caminho para incluir esse executável.

  • -d
  • -e
  • -s <serial>
  • Essas sinalizações são parecidas com os comandos adb de mesmo nome. Ative essas sinalizações se houver vários dispositivos ou emuladores conectados à máquina host. As funções deles são as seguintes:

    -d
    Conectar-se a um único dispositivo físico.
    -e
    Conectar-se a um único dispositivo de emulação.
    -s <serial>
    Conectar-se a um dispositivo ou emulador específico. Aqui, <serial> é o nome do dispositivo conforme listado pelo comando adb devices.

    Como alternativa, você pode configurar a variável de ambiente ADB_SERIAL para listar um dispositivo específico, sem precisar de nenhuma opção especial.

  • --exec=<file>
  • -x <file>
  • Essa opção manda o ndk-gdb executar os comandos de inicialização do GDB encontrados em <file> após a conexão com o processo em depuração. Esse é um recurso útil se você quer fazer algo repetidas vezes, como configurar uma lista de pontos de interrupção e depois retomar a execução automaticamente.

    --nowait

    Impede a pausa do código em Java até o GDB se conectar. Transmitir essa opção pode fazer com que o depurador perca os pontos de interrupção iniciais.

    --tui -t

    Ativa a interface de texto do usuário, se houver.

    --gnumake-flag=<flag>

    Essa opção é uma sinalização extra (ou sinalizações) que será transmitida ao sistema do ndk-build ao consultá-lo quanto a informações do projeto. É possível usar diversas instâncias dessa opção no mesmo comando.

    Observação: as três últimas opções nessa tabela são apenas para a versão Python de ndk-gdb.

    Compatibilidade com linha de execução

    Se o app for executado em uma plataforma anterior ao Android 2.3 (API de nível 9), o ndk-gdb não conseguirá depurar linhas de execução nativas da forma correta. O depurador só pode depurar a linha de execução principal, e o adb ignora completamente a execução das outras linhas.

    Se você colocar um ponto de interrupção em uma função executada em uma linha de execução que não seja a principal, o programa será fechado e o GDB exibirá a seguinte mensagem:

    Program terminated with signal SIGTRAP, Trace/breakpoint trap.
          The program no longer exists.