Přeskočit na obsah

Laděte padající test s agentem

Tenhle návod ukáže, jak nechat agenta použít debugger na selhání, které příkazy print nevysvětlují.

Nástroj debug řídí skutečnou relaci Debug Adapter Protocol. Zastavený rámec odpoví najednou na každou otázku o tom okamžiku: každá lokální proměnná, každý volající a výraz vyhodnocený ve vlastním rozsahu rámce. Příkaz print odpoví jen na to, na co ses zeptal před během.

Nástroj zůstává na povrchu, aby se agent mohl zeptat, proč se nic nedá použít, a nemusel hádat. Adaptér se opravdu spustí, jen když platí obojí:

  • v checkoutu leží značka projektu a
  • najde se binárka adaptéru.

Požádej agenta, ať to ověří:

debug(op: "adapters")

Odpoví tím, co našel, nebo vysvětlí, že adaptér potřebuje obě poloviny.

Jazyk Adaptér Značka Instalace
Dart / Flutter dart debug_adapter pubspec.yaml Dodává se s SDK, nic se neinstaluje
Python python3 -m debugpy.adapter pyproject.toml, setup.py, requirements.txt pip install debugpy
Rust / C / C++ lldb-dap Cargo.toml, CMakeLists.txt Dodává se s LLVM
Go dlv dap go.mod go install github.com/go-delve/delve/cmd/dlv@latest

Nejdřív breakpoint, potom spuštění

Sekce “Nejdřív breakpoint, potom spuštění”

Na pořadí záleží a nástroj ho vynucuje: breakpointy jde nastavit před tím, než relace existuje, protože právě tohle pořadí protokol vyžaduje.

Požádej agenta třeba takhle:

Funkce compute v bin/main.dart vrací špatnou hodnotu. Nastav breakpoint na řádku, který přiřazuje product, spusť ji pod debuggerem a řekni mi, jaké a a b ve skutečnosti jsou.

Spustí zhruba tohle:

debug(op: "breakpoints", file: "bin/main.dart", lines: [7])
debug(op: "launch", program: "bin/main.dart")

Spuštění nahlásí, kde se zastavilo:

Launched bin/main.dart on dart (session dart-1). Stopped: breakpoint. Use `stack` to see where.
debug(op: "stack")
→ #1 compute (bin/main.dart:7:3)
#2 main (bin/main.dart:2:18)

Pak jdi dovnitř:

debug(op: "scopes", frame_id: 1)
→ Locals (reference 12)
debug(op: "variables", reference: 12)
→ a (int) = 6
b (int) = 7
product (int) = 42

Objekt s potomky hlásí [expand: reference N], ale jen když za ním opravdu něco je. Rozbalení, se kterým agent nic neudělá, se nikdy nenabídne.

Na to, co mezi lokálními proměnnými není:

debug(op: "evaluate", expression: "config.timeout.inSeconds", frame_id: 1)
Co chceš Operace
Běž k dalšímu zastavení continue
Další řádek, stejný rámec step_over
Dovnitř volání step_in
Ven k volajícímu step_out
Zastav běžící program pause

Připoj se k tomu, co už běží

Sekce “Připoj se k tomu, co už běží”

U zaseknutého procesu, který nespouštíš ty:

debug(op: "attach", port: 5858)
debug(op: "terminate")

Relaci vždycky ukonči. Adaptér debuggeru vlastní zastavený proces, který drží všechno, co ten proces drží: port, zámek, spojení s databází.

Rozbalení variables na hlubokém grafu objektů je ze své podstaty neomezené. Jeden widget Flutteru dosáhne na celý strom elementů. Potomků v jednom rozsahu je nejvýš 50, hodnoty mají nejvýš 400 znaků a rámců zásobníku nejvýš 30. Výsledek nástroje, který zaplní kontextové okno, ukončí běh, kterému měl pomáhat.