El NDK incluye una secuencia de comandos de shell denominada ndk-gdb
para iniciar una sesión de depuración nativa en la línea de comandos. Por su parte, los usuarios que prefieren usar una GUI deben leer la documentación sobre depuración en Android Studio.
Requisitos
Para que la depuración nativa de líneas de comandos funcione, debes cumplir los siguientes requisitos:
- Compila tu app con la secuencia de comandos
ndk-build
. La secuencia de comandosndk-gdb
no admite el uso del método heredadomake APP=<name>
para la compilación. - Habilita la depuración de apps en tu archivo
AndroidManifest.xml
incluyendo un elemento<application>
que establezca el atributoandroid:debuggable
entrue
. - Compila tu app para que se ejecute en Android 2.2 (API nivel 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 el 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
, ubícate en el directorio de la aplicación o en cualquier directorio debajo de él. Por ejemplo:
cd $PROJECT $NDK/ndk-gdb
En este caso, $PROJECT
apunta al directorio raíz de tu proyecto y $NDK
apunta a la ruta de instalación del NDK.
Cuando invocas a ndk-gdb
, esta configura la sesión para buscar tus archivos de origen y las versiones de símbolo y depuración de las bibliotecas nativas generadas. Cuando la adjuntas correctamente al proceso de tu app, 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 máquina anfitrión no contiene versiones de símbolo y depuración de esas bibliotecas en el dispositivo de destino. Puedes ignorar esos mensajes.
A continuación, ndk-gdb
muestra una solicitud de GDB normal.
Debes interactuar con ndk-gdb
de la misma manera que con GDB de GNU. Por ejemplo, puedes usar b <location>
para establecer interrupciones y c
(de "continuar") a fin de reanudar la ejecución. Para acceder a una lista completa de comandos, consulta el manual de GDB. Si prefieres usar el depurador LLDB, usa la opción --lldb
cuando invoques la secuencia de comandos ndk-gdb
.
Ten en cuenta que, cuando sales de la ventana de GDB, el proceso de la app 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. Estas son algunas de las comprobaciones que realiza:
- Comprueba que adb esté presente en tu ruta de acceso.
- Comprueba que la app esté declarada como depurable en el manifiesto.
- Comprueba 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 app que ya esté en ejecución y muestra un error si no encuentra ninguno. Sin embargo, puedes usar la opción --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
Si deseas 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.
Cuando se inicia ndk-gdb
con esta opción especificada, se inicia la primera actividad que se puede iniciar y que se indica en el manifiesto de tu app. Usa --launch=<name>
para iniciar la próxima actividad que se puede iniciar. Para descartar la lista de actividades que se pueden iniciar, ejecuta --launch-list
desde la línea de comandos.
Opción | Descripción> |
---|---|
--lldb |
Si se configura, la secuencia de comandos usará el depurador LLDB para la sesión en lugar de gdb. |
--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 |
--force |
De forma predeterminada, se anula ndk-gdb 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, que debes cerrar por separado. |
--start |
Cuando inicias |
--launch=<name> |
Esta opción es similar a |
--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. |
--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, |
--adb=<file> |
Esta opción especifica el ejecutable de la herramienta adb. Solo es necesaria si no configuraste tu ruta de acceso para que incluya ese ejecutable. |
-d -e -s <serial> |
Estas marcas son similares a los comandos adb con los mismos nombres. Configúralas si hay varios dispositivos o emuladores conectados a tu máquina anfitrión. Sus significados son los siguientes:
También puedes definir la variable de entorno |
--exec=<file> -x <file> |
Esta opción le indica a |
--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 una o varias marcas adicionales que se pasarán al sistema |
Nota: Las tres opciones finales de esta tabla son solo para la versión de ndk-gdb
para Python.
Compatibilidad con 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; adb ignora por completo 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.