Ejecutar y depurar

.graphoos/run.toml en el proyecto describe qué ejecutar. Ejecutar y depurar desde la paleta (palette.run_and_debug) lista sus entradas; elige una para ejecutarla en el panel del terminal, o para depurarla si nombra un depurador.

[[configs]]
name = "check"
# El tipo de depurador: déjalo fuera para solo ejecutar el programa.
type = "lldb"
program = "${workspace}/target/debug/check"
args = ["--verbose"]
cwd = "${workspace}"

[configs.env]
RUST_LOG = "debug"

# Se ejecuta antes de cada lanzamiento.
[configs.prelaunch]
program = "cargo"
args = ["build"]

Abrir run.toml desde Ejecutar y depurar lo crea con una plantilla comentada si el proyecto no tiene ninguno. ${workspace} se expande a la raíz del proyecto.

Los puntos de interrupción se ponen y se quitan con F9 en la línea del cursor (o con Poner o quitar punto de ruptura en la paleta, porque macOS se reserva F9 salvo que las teclas de función estén configuradas para comportarse como tales), y haciendo clic en el margen a la izquierda de los números de línea.

Puntos de interrupción condicionales y puntos de registro

A un punto de interrupción puesto en el margen se le puede dar algo más que una línea, desde la paleta, actuando sobre el de la línea del cursor:

  • Depurar: condición del punto de ruptura: una expresión que el depurador evalúa; solo se detiene cuando es verdadera (x > 3).
  • Depurar: número de pasadas del punto de ruptura: 5, >= 3, % 2: se detiene solo en esas pasadas.
  • Depurar: convertir el punto de ruptura en punto de registro: un mensaje que se imprime en lugar de detenerse, con {expression} interpolado por el adaptador.

Cada uno se abre con lo que tiene ahora el punto de interrupción, para poder editarlo, y una respuesta vacía lo borra (un punto de registro vuelve a ser un punto de interrupción normal). El cambio llega al momento a una sesión en marcha. Lo que el depurador haga con cada uno es cosa del adaptador: codelldb, debugpy y Node admiten los tres.

La consola de depuración

La sección Consola de depuración del panel de depuración muestra lo que escribe el programa cuando su adaptador lo manda allí ("console": "internalConsole" de Python, un attach), sus errores en rojo, y lo que dice el propio adaptador, atenuado; cada sesión empieza con su nombre. Guarda las últimas 5.000 líneas y sigue a la más nueva.

También es la REPL: Depurar: evaluar una expresión en la paleta —o la última fila de la consola, › Evaluar una expresión…— envía lo que escribas al adaptador en el marco en el que está detenida la sesión; la expresión y su respuesta, con su tipo (42 (int)), quedan en la consola una debajo de otra. Si no hay nada detenido, lo dice en lugar de fallar en silencio.

Valores donde se ha detenido el programa

En una parada, los valores de las variables del marco se muestran al final de las líneas donde aparecen, desde un poco por encima de la parada hasta ella (total = 6, n = 3). Desaparecen cuando el programa continúa, y en cuanto se edita el fichero.

Excepciones

El adaptador dice en qué excepciones puede detenerse —debugpy: Raised, Uncaught, User Uncaught; js-debug: Caught y Uncaught— y aparecen arriba de Puntos de interrupción con una casilla cada una, marcadas como el adaptador las quiere por defecto. Un cambio se aplica al momento a la sesión en marcha y se guarda para la siguiente sesión del mismo tipo de depurador. Una configuración puede elegirlas ella misma:

exception-filters = ["raised", "uncaught"]

Adjuntarse a un programa en marcha

request = "attach" se une a un programa que ya se está ejecutando en vez de arrancar uno. Lo que el adaptador necesita para encontrarlo va en [configs.adapter], con el nombre que le da el adaptador:

[[configs]]
name = "attach to the server"
type = "debugpy"
request = "attach"

[configs.adapter]
connect = { host = "127.0.0.1", port = 5678 }

[configs.adapter] vale también para un lanzamiento: sus claves llegan al adaptador tal cual, por encima de lo que rellena GraphoOS (justMyCode, stopOnEntry, console…). Una sesión sin terminal propio —un attach, o una salida enviada a la consola de depuración— aparece en Procesos y se maneja como las demás.

launch.json

El .vscode/launch.json de un proyecto se lee tal cual: sus configuraciones aparecen en Ejecutar y depurar junto a las de run.toml, y un compound arranca a la vez las configuraciones que nombra. Los tipos de VS Code pasan a ser el depurador que ejecuta GraphoOS (python → debugpy, node → pwa-node, cppdbg/codelldb → lldb), ${workspaceFolder} es ${workspace}, y cada clave para la que GraphoOS no tiene campo va al adaptador.

Vigilar expresiones

Depurar: vigilar una expresión la añade a la sección Vigiladas del panel de Depuración, donde se vuelve a evaluar en cada parada, con su tipo; cuando no se puede evaluar en ese marco, se muestra el motivo en rojo en lugar de un valor. La × de una fila deja de vigilarla, y Depurar: dejar de vigilar todo vacía la lista. Si no hay nada detenido, los valores se quedan como estaban, y lo dicen, en lugar de quedarse en blanco.

Cambiar una variable

Hacer doble clic en una variable de la sección Variables pide su nuevo valor, con el actual listo para escribir encima, y lo envía al adaptador (setVariable). La fila muestra entonces el valor tal como lo tiene el depurador, que no siempre es el texto que se escribió, y las expresiones vigiladas se vuelven a evaluar por si dependían de ella. Un adaptador que rechaza el cambio dice por qué.

Tareas de compilación y problemas

Ejecutar y depurar en la paleta lista, después de las configuraciones de .graphoos/run.toml, las tareas que sugieren los ficheros del proyecto: cargo build / test / run / check / clippy a partir de un Cargo.toml, cada script de un package.json (npm run …, o pnpm / yarn cuando está su fichero de bloqueo), los objetivos de un Makefile, gradle build / test / assemble (./gradlew cuando existe), go build / test / vet y pytest. Cada una se ejecuta en un terminal como cualquier configuración de ejecución.

Ejecutar la tarea de compilación (⌘⇧B / Ctrl+Shift+B) y Ejecutar la tarea de pruebas (en la paleta) ejecutan la primera tarea cuyo nombre diga build o test; una configuración de run.toml con ese nombre gana a las detectadas.

Cuando termina una tarea, su salida pasa por los detectores de problemas (rustc, tsc, gcc/clang, go, javac, trazas de Python, eslint) y cada error y cada aviso aparece en el panel Problemas bajo su fichero, con la línea en la que hacer clic; un mensaje dice cuántos hubo. La siguiente ejecución los sustituye; los diagnósticos propios de los servidores de lenguaje no se tocan.

Depuración

GraphoOS habla el Debug Adapter Protocol. El panel de Depuración (barra izquierda) muestra la pila de llamadas, las variables y el proceso; la barra de herramientas continúa, pasa por encima, entra y sale, reinicia y detiene; los puntos de interrupción se ponen desde el margen (con un clic), y el type de la configuración de ejecución elige el adaptador.

El adaptador de un type lo registra un plugin (register_debugger_type en la API de plugins): el plugin nombra el programa que lo implementa. Los plugins de Rust y de C/C++ registran lldb: buscan codelldb, después lldb-dap (el adaptador de LLVM: brew install llvm, las herramientas de línea de comandos de Xcode, o el paquete lldb de tu distribución), o el programa indicado en su ajuste debuggerPath. El plugin de Python registra debugpy, que se ejecuta como python -m debugpy.adapter con el intérprete de su ajuste pythonPath o el python3 del PATH, y solo si ese intérprete tiene de verdad debugpy (pip install debugpy). La línea del registro del plugin dice cuándo no se encontró ninguno.

[[configs]]
name = "python: the tests"
type = "debugpy"
program = "${workspace}/run_tests.py"
cwd = "${workspace}"

En macOS, la primera sesión de depuración pide Developer Tools Access (una contraseña o Touch ID que pide el sistema): permite al adaptador tomar el control del proceso, y después se recuerda.

Depurar en un equipo remoto funciona igual: el adaptador se ejecuta junto al proxy.

Fuente: docs/es/debugging.md