Отладить падающий тест с агентом
Это руководство показывает, как заставить агента воспользоваться отладчиком для ошибки, которую не объясняют операторы print.
Инструмент debug управляет настоящей сессией Debug Adapter Protocol. Остановленный кадр отвечает сразу на все вопросы об этом моменте — каждая локальная переменная, каждый вызывающий и выражение, вычисленное в собственной области видимости кадра, — тогда как оператор print отвечает лишь на тот вопрос, который вы догадались задать до запуска.
Прежде чем начать
Заголовок раздела «Прежде чем начать»Инструмент остаётся на поверхности, чтобы агент мог спросить, почему ничего не работает, а не гадать. Адаптер действительно может запуститься, только когда выполняются оба условия:
- маркер проекта в рабочей копии и
- бинарник адаптера резолвится.
Попросите агента проверить:
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. Результат инструмента, заполняющий окно контекста, — это инструмент, который завершает запуск, которому помогал.
См. также
Заголовок раздела «См. также»- Интеллект кода — почему отладчик, компилятор и сопоставитель отвечают на разные вопросы
- Встроенные инструменты агента — каждая операция и аргумент
debug - Диагностировать агента — когда проблема в агенте, а не в коде