Перейти до вмісту

Налагодити тест, що падає, з агентом

Цей посібник показує, як змусити агента скористатися налагоджувачем для збою, який оператори друку не пояснюють.

Інструмент debug керує справжньою сесією Debug Adapter Protocol. Зупинений кадр відповідає одразу на всі питання про цю мить — кожну локальну змінну, кожен виклик і вираз, обчислений у власній області видимості кадру, — тоді як оператор друку відповідає лише на те питання, яке ви здогадалися поставити до запуску.

Інструмент лишається на поверхні, щоб агент міг спитати, чому нічого не працює, а не здогадуватися. Адаптер насправді може запуститися лише тоді, коли виконуються обидві умови:

  • маркер проєкту в чекауті, і
  • бінарник адаптера резолвиться.

Попросіть агента перевірити:

debug(op: "adapters")

Він відповість тим, що знайшов, або пояснить, що адаптеру потрібні обидві половини.

Мова Адаптер Маркер Встановлення
Dart / Flutter dart debug_adapter pubspec.yaml Постачається із SDK — нічого не треба
Python python3 -m debugpy.adapter pyproject.toml, setup.py, requirements.txt pip install debugpy
Rust / C / C++ lldb-dap Cargo.toml, CMakeLists.txt Постачається з LLVM
Go dlv dap go.mod go install github.com/go-delve/delve/cmd/dlv@latest

Спершу поставте точку зупину, потім запускайте

Розділ із назвою «Спершу поставте точку зупину, потім запускайте»

Порядок важливий, і інструмент його дотримується: точки зупину можна ставити до появи сесії, бо саме такої послідовності вимагає протокол.

Попросіть агента приблизно так:

Функція compute у bin/main.dart повертає неправильне значення. Постав точку зупину на рядку, який присвоює product, запусти його під налагоджувачем і скажи, чому насправді дорівнюють a і b.

Він виконає приблизно таке:

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

Запуск повідомляє, де він зупинився:

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)

Потім загляньте всередину:

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

Об’єкт із дочірніми елементами повідомляє [expand: reference N] — але лише коли за ним справді щось є, тож розгортання, яким агент не зможе скористатися, ніколи не пропонують.

Для всього, що не видно як локальну змінну:

debug(op: "evaluate", expression: "config.timeout.inSeconds", frame_id: 1)
Чого ви хочете Операція
Виконати до наступної зупинки continue
Наступний рядок, той самий кадр step_over
Усередину виклику step_in
Назовні, до викликача step_out
Зупинити програму, що виконується pause

Для завислого процесу, а не того, який ви запускаєте:

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

Завжди завершуйте сесію. Налагоджувальний адаптер володіє зупиненим процесом, який тримає все, що тримає цей процес — порт, блокування, з’єднання з базою даних.

Розгортання variables на глибокому графі об’єктів за своєю природою необмежене — один віджет Flutter дістає до всього дерева елементів. Кількість дочірніх елементів на область видимості обмежено 50, значень — 400 символами, а кадрів стека — 30. Результат інструмента, який заповнює контекстне вікно, — це інструмент, який обриває запуск, якому допомагав.