Depurar um teste com falha com um agente
Este guia mostra-lhe como fazer com que um agente use um depurador numa falha que as instruções de impressão não conseguem explicar.
A ferramenta debug conduz uma sessão real do Debug Adapter Protocol. Um frame parado responde a todas as perguntas sobre aquele momento de uma só vez — cada variável local, cada chamador e uma expressão avaliada no próprio âmbito do frame — enquanto uma instrução de impressão responde apenas à pergunta que pensou em fazer antes de executar.
Antes de começar
Secção intitulada “Antes de começar”A ferramenta permanece à superfície para que o agente possa perguntar porque é que nada é utilizável, em vez de adivinhar. Um adaptador só consegue realmente arrancar quando ambas as condições seguintes se verificam:
- um marcador de projeto no checkout, e
- o binário do adaptador a resolver.
Peça ao agente para verificar:
debug(op: "adapters")Responde com o que encontrou, ou explica que um adaptador precisa das duas metades.
| Linguagem | Adaptador | Marcador | Instalação |
|---|---|---|---|
| Dart / Flutter | dart debug_adapter |
pubspec.yaml |
Vem com o SDK — nada a fazer |
| Python | python3 -m debugpy.adapter |
pyproject.toml, setup.py, requirements.txt |
pip install debugpy |
| Rust / C / C++ | lldb-dap |
Cargo.toml, CMakeLists.txt |
Vem com o LLVM |
| Go | dlv dap |
go.mod |
go install github.com/go-delve/delve/cmd/dlv@latest |
Defina primeiro o ponto de interrupção e só depois inicie
Secção intitulada “Defina primeiro o ponto de interrupção e só depois inicie”A ordem é importante e a ferramenta impõe-a: os pontos de interrupção podem ser definidos antes de existir uma sessão, porque é essa a sequência que o protocolo exige.
Peça ao agente algo como:
A função
computeembin/main.dartdevolve o valor errado. Defina um ponto de interrupção na linha que atribuiproduct, inicie-o sob o depurador e diga-me o que são realmenteaeb.
Irá executar aproximadamente:
debug(op: "breakpoints", file: "bin/main.dart", lines: [7])debug(op: "launch", program: "bin/main.dart")O arranque indica onde parou:
Launched bin/main.dart on dart (session dart-1). Stopped: breakpoint. Use `stack` to see where.Leia o frame
Secção intitulada “Leia o frame”debug(op: "stack")→ #1 compute (bin/main.dart:7:3) #2 main (bin/main.dart:2:18)Depois entre nele:
debug(op: "scopes", frame_id: 1)→ Locals (reference 12)
debug(op: "variables", reference: 12)→ a (int) = 6 b (int) = 7 product (int) = 42Um objeto com filhos indica [expand: reference N] — mas só quando há genuinamente algo por trás dele, pelo que uma expansão que o agente não consegue usar nunca é oferecida.
Para algo que não seja visível como variável local:
debug(op: "evaluate", expression: "config.timeout.inSeconds", frame_id: 1)Avançar passo a passo
Secção intitulada “Avançar passo a passo”| O que pretende | Operação |
|---|---|
| Executar até à próxima paragem | continue |
| Linha seguinte, mesmo frame | step_over |
| Entrar na chamada | step_in |
| Sair para o chamador | step_out |
| Parar um programa em execução | pause |
Anexar a algo que já está em execução
Secção intitulada “Anexar a algo que já está em execução”Para um processo encravado, em vez de um que está a iniciar:
debug(op: "attach", port: 5858)Terminar
Secção intitulada “Terminar”debug(op: "terminate")Termine sempre a sessão. Um adaptador de depuração é dono de um processo parado que detém tudo o que esse processo detém — uma porta, um bloqueio, uma ligação a uma base de dados.
Saída limitada
Secção intitulada “Saída limitada”Uma expansão de variables sobre um grafo de objetos profundo é, por natureza, ilimitada — um único widget do Flutter alcança toda a árvore de elementos. Os filhos por âmbito estão limitados a 50, os valores a 400 caracteres e os frames de pilha a 30. Um resultado de ferramenta que enche a janela de contexto é uma ferramenta que acaba com a execução que estava a ajudar.
Relacionados
Secção intitulada “Relacionados”- Inteligência de código — porque é que um depurador, um compilador e um comparador estrutural respondem a perguntas diferentes
- Ferramentas de agente integradas — todas as operações de
debuge os respetivos argumentos - Diagnosticar um agente — quando o problema é o agente e não o código