Перейти к содержанию

Точки останова не срабатывают

Симптом: сессия стартует, программа отрабатывает целиком, и ничего не останавливается.

Сначала: что ответил адаптер?

Откройте панель Breakpoints — Ctrl+B. У каждой точки есть кружок:

Кружок Состояние Что означает
Залитый verified адаптер принял — проблема в другом месте
Жёлтое кольцо rejected адаптер отказал
Приглушённое кольцо pending ответа ещё нет

Один этот значок делит задачу пополам.

Точка отклонена (жёлтое кольцо)

Адаптер отказался её привязывать. Причины по убыванию вероятности:

Строка неисполняемая. Пустая строка, комментарий, объявление, закрывающая скобка. Перейдите на строку, которая что-то делает.

Код вырезан оптимизатором. У заинлайненных функций и удалённых веток нет кода, на котором можно остановиться. Пересоберите без оптимизации:

  • Rust: debug-сборка, а не --release;
  • C / C++: -g -O0;
  • Go: если перебивали сборку, оставьте -gcflags=all=-N -l.

Нет отладочной информации. Бинарник без символов или зависимость, собранная без них, точку останова удержать не могут.

Точка в состоянии pending (приглушённое кольцо)

Ответ не пришёл. Проблема это или нет, зависит от языка:

  • PHP: до первого запроса это нормально. Набор в окне виден, но пока Xdebug не подключился, спросить про него некого. Отправьте запрос.
  • Все остальные: если состояние держится после старта сессии, значит адаптер не отвечает — см. Адаптер не запускается.

Учтите ещё, что адаптер вправе сдвинуть точку на соседнюю строку. Тогда запрошенная строка подтверждения не получает и остаётся pending, хотя точка останова действительно существует строкой-двумя ниже.

Точка verified, но не срабатывает

Адаптер её принял, значит вопрос теперь к вашей программе, а не к отладчику.

Код не выполняется. Самый частый ответ и самый нежеланный. Поставьте точку на первую строку main или на функцию, которая вызывает эту, и двигайтесь вперёд.

Код выполняет второй процесс. Это легко упустить:

  • Django, Flask, uvicorn с автоперезагрузчиком порождают воркер, к которому отладчик не прицеплен — добавьте --noreload или его аналог;
  • очередь задач или пул воркеров выполняет код вообще в другом месте.

Запрос завершился до начала отладки (PHP). Xdebug подключается в начале запроса, и уже идущий запрос задним числом не отладить. Отправьте новый.

Команда PHP-теста превысила время ожидания. Для :DebugTest через Docker Bugsaur ждёт 30 секунд подключения контейнера к Xdebug. Если GUI сообщает, что Docker недоступен или завис, проверьте, что запущен Docker Desktop/OrbStack, затем посмотрите состояние контейнеров командой docker compose ps и попробуйте выполнить команду теста вручную. Если testCommand завершается с ошибкой, в сообщении GUI также показываются точная команда, exit status и полученный вывод Docker/Compose.

Условие никогда не истинно. Условная точка с выражением, которое никогда не становится истинным, ведёт себя ровно как неработающая. Уберите условие временно и проверьте.

Запуск теста проигнорировал сохранённые точки. :DebugTest и --test-at используют только точки текущего запроса — так задумано. Ставьте точку в этой же сессии.

Явный --break заменил набор. --break не дополняет сохранённый набор, а перебивает его целиком.

Останавливается, но переменных нет

Другая задача с тем же корнем: у фрейма нет отладочной информации.

Причина Что делать
Release-сборка или оптимизация пересоберите в debug
Фрейм принадлежит библиотеке или рантайму выберите в стеке свой собственный фрейм
Rust --release debug-сборка
Go со своей сборкой оставьте -gcflags=all=-N -l

Чек-лист

□ Кружок залитый, жёлтый или приглушённый?
□ Строка исполняемая?
□ Сборка без оптимизации?
□ Код вообще выполняется — срабатывает ли точка в main?
□ Нет ли второго процесса (автоперезагрузчик, воркер)?
□ Не висит ли условие, которое никогда не истинно?
□ Это не запуск теста, который игнорирует сохранённые точки?
□ Не заменил ли --break сохранённый набор?