ndk-gdb

El NDK incluye una secuencia de comandos de shell denominada ndk-gdb para iniciar fácilmente una sesión de depuración nativa de secuencias de comandos. Los usuarios que prefieren usar una GUI deben leer la documentación sobre depuración en Android Studio en su lugar.

Requisitos

Para que la depuración nativa de líneas de comandos funcione, debes cumplir los siguientes requisitos:

  • Compila la aplicación con la secuencia de comandos ndk-build. La secuencia de comandos ndk-gdb no admite el uso del método heredado make APP=<name> para la compilación.
  • Habilita la depuración de aplicaciones en tu archivo AndroidManifest.xml incluyendo un elemento <application> que establezca el atributo android:debuggable en true.
  • Compila tu app para que se ejecute en Android 2.2 (nivel de Android API 8) o versiones posteriores.
  • Realiza la depuración en un dispositivo o emulador con Android 2.2 o versiones posteriores. Para la depuración, el nivel de API de destino que declaras en tu archivo AndroidManifest.xml no tiene importancia.
  • Desarrolla tu app en un shell Unix. En Windows, usa Cygwin o la implementación experimental ndk-gdb-py de Python.
  • Usa GNU Make 3.81 o versiones posteriores.

Uso

Para invocar la secuencia de comandos ndk-gdb, realiza un cambio al directorio de la aplicación o a cualquier directorio de ella. Por ejemplo:

    cd $PROJECT
    $NDK/ndk-gdb
    

Aquí, $PROJECT apunta al directorio raíz de tu proyecto y $NDK apunta a la ruta de instalación del NDK.

Cuando invocas ndk-gdb, configura la sesión para buscar tus archivos de origen y las versiones de símbolo y depuración de tus bibliotecas nativas generadas. Cuando la adjuntas correctamente al proceso de tu aplicación, ndk-gdb genera una larga serie de mensajes de error donde indica que no puede encontrar varias bibliotecas del sistema. Esto es normal, ya que tu equipo host no contiene versiones de símbolo y depuración de esas bibliotecas en tu dispositivo de destino. Puedes ignorar esos mensajes.

A continuación, ndk-gdb muestra una solicitud de GDB normal.

Puedes interactuar con ndk-gdb tal como lo harías con GDB para GNU. Por ejemplo, puedes usar b <location> para configurar interrupciones y c (de "continuar") para reanudar la ejecución. Para acceder a una lista completa de comandos, consulta el manual de GDB.

Ten en cuenta que cuando sales de la solicitud de GDB, el proceso de la aplicación que depuras se detiene. Este comportamiento es una limitación de gdb.

ndk-gdb controla muchas condiciones de error y muestra un mensaje de error informativo si encuentra un problema. Esas comprobaciones incluyen verificar que se cumplan las siguientes condiciones:

  • Comprobación de que ADB esté presente en tu ruta de acceso.
  • Comprobación de que tu aplicación esté declarada como depurable en su manifiesto.
  • Comprobación de que, en el dispositivo, la aplicación instalada con el mismo nombre de paquete también sea depurable.

De forma predeterminada, ndk-gdb busca un proceso de la aplicación que ya esté en ejecución y muestra un error si no encuentra ninguno. No obstante, puedes usar las opciones --start o --launch=<name> para iniciar automáticamente tu actividad antes de la sesión de depuración. Para obtener más información, consulta Opciones.

Opciones

Para ver una lista completa de opciones, escribe ndk-gdb --help en la línea de comandos. En la tabla 1, se muestran algunas de las más empleadas, junto con descripciones breves.

Tabla 1. Opciones de ndk-gdb comunes y sus descripciones.

Al iniciar ndk-gdb con esta opción especificada, se inicia la primera actividad que se puede iniciar indicada en el manifiesto de tu aplicación. Usa --launch=<name> para iniciar la siguiente actividad que se pueda iniciar. Para descartar la lista de actividades que pueden iniciarse, ejecuta --launch-list desde la línea de comandos.

Opción Descripción>
--verbose

Esta opción indica al sistema de compilación que imprima información detallada sobre la configuración de la sesión de depuración nativa. Esto solo es necesario para depurar problemas cuando el depurador no puede conectarse con la app y los mensajes de error que muestra ndk-gdb no son suficientes.

--force De forma predeterminada, ndk-gdb se anula si detecta otra sesión de depuración nativa en ejecución en el mismo dispositivo. Esta opción cierra la otra sesión y la reemplaza por una nueva. Ten en cuenta que no cierra la app que se está depurando, la cual debes cerrar por separado.
--start

Cuando inicias ndk-gdb, de forma predeterminada intenta adjuntarse a una instancia de ejecución existente de tu app en el dispositivo de destino. Puedes anular este comportamiento predeterminado usando --start para iniciar explícitamente la aplicación en el dispositivo de destino antes de la sesión de depuración.

--launch=<name>

Esta opción es similar a --start, con la excepción de que te permite iniciar una actividad específica desde tu aplicación. Esta función solo es útil si tu manifiesto define varias actividades que se pueden iniciar.

--launch-list

Esta opción conveniente imprime la lista de todos los nombres de las actividades que se pueden iniciar del manifiesto de tu app. --start usa el nombre de la primera actividad.

--project=<path> Esta opción especifica el directorio del proyecto de la app. Resulta útil si quieres iniciar la secuencia de comandos sin tener que realizar primero un cambio al directorio del proyecto.
--port=<port>

De forma predeterminada, ndk-gdb usa el puerto local TCP 5039 para comunicarse con la app que depura en el dispositivo de destino. El uso de un puerto diferente te permite depurar de forma nativa programas que estén en ejecución en otros dispositivos o emuladores conectados al mismo equipo host.

--adb=<file>

Esta opción especifica el ejecutable de la herramienta adb. Solo es necesaria si no has configurado tu ruta de acceso para que incluya ese ejecutable.

  • -d
  • -e
  • -s <serial>
  • Estos indicadores son similares a los comandos adb con los mismos nombres. Configura estos indicadores si hay varios dispositivos o emuladores conectados a tu equipo host. Sus significados son los siguientes:

    -d
    Establece conexión con un solo dispositivo físico.
    -e
    Establece conexión con un solo dispositivo emulador.
    -s <serial>
    Establece conexión con un dispositivo o emulador específico. Aquí, <serial> es el nombre del dispositivo tal como lo indica el comando adb devices.

    También puedes definir la variable de entorno ADB_SERIAL para indicar un dispositivo determinado, sin la necesidad de usar una opción específica.

  • --exec=<file>
  • -x <file>
  • Esta opción indica a ndk-gdb que ejecute los comandos de inicialización de GDB que se encuentran en <file> después de conectarse con el proceso que depura. Esta función es útil si quieres realizar algo de forma repetida, como configurar una lista de interrupciones y luego reanudar la ejecución automáticamente.

    --nowait

    Inhabilita el pausado del código Java hasta que GDB se conecte. Pasar esta opción puede hacer que el depurador omita interrupciones anteriores.

    --tui -t

    Habilita la interfaz textual del usuario, si se encuentra disponible.

    --gnumake-flag=<flag>

    Esta opción representa uno o varios indicadores adicionales que se pasarán al sistema ndk-build cuando se le solicite información del proyecto. Puedes usar varias instancias de esta opción en el mismo comando.

    Nota: Las tres opciones finales de esta tabla son solo para la versión de ndk-gdb de Python.

    Admisión de subprocesos

    Si tu app se ejecuta en una plataforma anterior a Android 2.3 (nivel de API 9), ndk-gdb no puede depurar correctamente subprocesos nativos. El depurador solo puede depurar el subproceso principal; abd ignora completamente la ejecución de otros subprocesos.

    Si colocas una interrupción en una función ejecutada en un subproceso que no es el principal, el programa se cierra y GDB muestra el siguiente mensaje:

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