Usa depuradores

En esta página, se detalla el uso de LLDB para el desarrollo de SO. Para el desarrollo de apps, consulta Cómo depurar tu app, en el que se explica cómo usar la GUI de Android Studio (basada en LLDB).

GDB ya no se admite ni se proporciona. Si cambias de GDB a LLDB, lo mejor es que primero leas el Instructivo de LLDB. Si eres un usuario experto de GDB, el mapa de comandos de GDB a LLDB es muy útil durante la transición.

Requisitos previos

Para usar un depurador, haz lo siguiente:

  • Configura el entorno de compilación con el comando envsetup.sh habitual.
  • Ejecuta el mismo comando lunch que usaste cuando compilaste. Ten en cuenta que el elemento de almuerzo debe coincidir exactamente con el dispositivo que estás depurando. Si el elemento de almuerzo no coincide con el dispositivo conectado, recibirás un error del siguiente formato: You used the wrong lunch: TARGET_PRODUCT (aosp_arm64) does not match attached device (xyzabc)
  • Conecta el dispositivo a la máquina.

Para obtener más ayuda con la configuración de tu entorno, consulta Configura el entorno.

Cómo depurar un objeto binario

Para depurar un objeto binario que compilaste en tu máquina, primero deberás copiarlo en el dispositivo y, luego, iniciar el depurador. Por ejemplo:

adb push test.exe /data/local/tmp/test.exe
lldbclient.py --port 5038 -r /data/local/tmp/test.exe

Cómo depurar apps o procesos en ejecución

Para conectarte a una app en ejecución o a un daemon nativo, usa lldbclient.py con un PID. Por ejemplo, para depurar el proceso con el PID 1234, ejecuta lo siguiente en el host:

lldbclient.py -p 1234

La secuencia de comandos configura el reenvío de puertos, inicia el stub de depuración remota apropiado en el dispositivo, inicia el depurador en el host, lo configura para encontrar símbolos y lo conecta al stub de depuración remota.

Cómo depurar el inicio del proceso nativo

Para depurar un proceso a medida que se inicia, usa lldbclient.py con la opción -r. Por ejemplo, para depurar ls /bin, ejecuta lo siguiente en el host:

lldbclient.py -r /system/bin/ls /bin

Luego, ingresa continue en el mensaje del depurador.

Cómo depurar el inicio de la app

A veces, deseas depurar una app a medida que se inicia, por ejemplo, cuando se produce una falla y deseas analizar el código para ver qué sucedió antes de la falla. Adjuntar funciona en algunos casos, pero en otros es imposible porque la app falla antes de que puedas adjuntar. El enfoque logwrapper (que se usa para strace) no siempre funciona porque es posible que la app no tenga permisos para abrir un puerto, y lldbserver hereda esa restricción.

Para depurar el inicio de la app, usa las opciones para desarrolladores en Configuración para indicarle a la app que espere a que se adjunte un depurador de Java:

  1. Ve a Configuración > Opciones para desarrolladores > Seleccionar app de depuración, elige tu app de la lista y, luego, haz clic en Esperar al depurador.
  2. Inicia la app desde el selector o usa la línea de comandos para ejecutarla:
    adb shell am start -a android.intent.action.MAIN -n APP_NAME/.APP_ACTIVITY
    
  3. Espera a que se cargue la app y aparezca un diálogo que te indique que la app está esperando un depurador.
  4. Conecta lldbserver/lldbclient de forma normal, establece puntos de interrupción y, luego, continúa con el proceso.

Para permitir que se ejecute la app, adjunta un depurador de Java Debug Wire Protocol (JDWP), como Java Debugger (jdb):

adb forward tcp:12345 jdwp:XXX  # (Where XXX is the PID
of the debugged process.)
jdb -attach localhost:12345

Cómo depurar apps o procesos que fallan

Si deseas que debuggerd suspenda los procesos fallidos para que puedas adjuntar un depurador, establece la propiedad adecuada:

  • Después de Android 11
    adb shell setprop debug.debuggerd.wait_for_debugger true
    
  • Android 11 y versiones anteriores
    adb shell setprop debug.debuggerd.wait_for_gdb true
    
  • Android 6.0 Marshmallow y versiones anteriores
    adb shell setprop debug.db.uid 999999
    

Al final del resultado habitual de falla, debuggerd proporciona instrucciones de copia y pegado en logcat que muestran cómo conectar el depurador al proceso con falla.

Cómo depurar con VS Code

LLDB admite la depuración de código de plataforma en Visual Studio Code. Puedes usar el frontend del depurador de VS Code en lugar de la interfaz de la CLI de LLDB para controlar y depurar el código nativo que se ejecuta en los dispositivos.

Antes de usar VS Code para la depuración, instala la extensión CodeLLDB.

Para depurar código con VS Code, haz lo siguiente:

  1. Asegúrate de que estén presentes todos los artefactos de compilación (como los símbolos) necesarios para ejecutar lldbclient.py o lldbclient.py.
  2. En VS Code, presiona Ctrl + Mayúsculas + P para ejecutar un comando, busca Debug: Add Configuration… y, luego, selecciona LLDB. Se abrirá un archivo launch.json y se agregará un nuevo objeto JSON a una lista.
  3. Reemplaza la configuración del depurador agregada recientemente por dos líneas de comentario: // #lldbclient-generated-begin y // #lldbclient-generated-end, de modo que la lista de configuración se vea de la siguiente manera:
    "configurations": [
        // #lldbclient-generated-begin
        // #lldbclient-generated-end
    ]

    lldbclient.py usa estos comentarios para detectar dónde escribir la configuración. Si hay otros elementos en la lista, agrega las líneas de comentario al final después de las otras configuraciones.

  4. Ejecuta el siguiente comando en la terminal en la que ejecutaste envsetup.sh y lunch:
    lldbclient.py --setup-forwarding vscode-lldb \
          --vscode-launch-file LAUNCH_JSON_PATH \
          ANY_OTHER_FLAGS -p pid | -n proc-name | -r ...

    lldbclient.py escribe la configuración generada en launch.json y sigue ejecutándose. Esto es esperable. No finalices el programa lldbclient.py. Si omites --vscode-launch-file, la secuencia de comandos imprimirá el fragmento JSON que deberás copiar y pegar en launch.json de forma manual.

    La marca -r debe ser la última si está presente debido a la forma en que la herramienta analiza las marcas.

  5. Abre la barra lateral Run and Debug. La configuración nueva debería aparecer en la lista del depurador. Presiona Iniciar depuración (F5). El depurador debería conectarse después de 10 a 30 segundos.

    Si la configuración nueva no apareció en la vista Run and Debug, vuelve a cargar la ventana para actualizar la lista del depurador. Presiona Ctrl + Mayúsculas + P y escribe reload window.

  6. Cuando termines de depurar, ve a la terminal que ejecuta lldbclient.py y presiona Intro para finalizar el programa lldbclient.py. Las ejecuciones posteriores de la secuencia de comandos generarían la configuración entre los comentarios #lldbclient-generated y reemplazarían el contenido anterior, por lo que no es necesario quitarlos de forma manual.

Para agregar propiedades personalizadas a la configuración de lanzamiento generada, puedes usar la marca --vscode-launch-props. Por ejemplo:

lldbclient.py --setup-forwarding vscode-lldb \
    --vscode-launch-props \
    '{"initCommands" : ["script print(\"Hello\")"], "preLaunchTask" : "Build"}' \
    ...
Las propiedades de ejemplo harían que VS Code ejecute una tarea llamada Build antes de la depuración y adjunte un nuevo paso de inicialización de depuración a los pasos que genera la secuencia de comandos. Puedes encontrar una descripción general de las propiedades disponibles en la documentación de VS Code y en el manual del usuario de la extensión CodeLLDB.