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

Отображения путей и «исходник не найден»

Симптом: отладчик останавливается, в стеке есть фреймы, но исходник не показан — либо открывается не тот файл, либо точки останова вообще не привязываются.

У всего этого одна общая причина: отладчик и отлаживаемое расходятся в путях.

Почему так выходит

Адаптер сообщает тот путь, с которым код был скомпилирован или выполнен. Если такого пути на вашей машине нет, открывать нечего.

Ситуация Сообщённый путь Ваш путь
PHP в Docker /app/src/Controller.php /home/me/project/src/Controller.php
Собрано в контейнере /build/src/main.rs /home/me/project/src/main.rs
Отладка на другой машине /opt/app/main.go /home/me/project/main.go

Перевод работает и в обратную сторону: точки останова, поставленные по вашим путям, должны уйти как пути, известные отлаживаемой программе. Без отображения они никогда не совпадут — поэтому «точки не привязываются» и «исходника нет» это одна и та же ошибка.

Как чинить для PHP

[profiles.docker.launch_arguments]
pathMappings = { "/app" = "${root}" }

Читается как путь в контейнере = путь на хосте.

Левую часть не угадывайте, а спросите:

docker compose exec php pwd
docker compose exec php ls /app

и сверьте с монтированием в docker-compose.yml:

volumes:
  - .:/app          # хост . -> контейнер /app

Правая часть тома — это путь контейнера, и он же левая часть отображения.

Несколько монтирований требуют нескольких отображений

pathMappings = { "/app" = "${root}", "/vendor-src" = "${root}/vendor" }

Выигрывает самый длинный совпавший префикс, порядок не важен.

Как чинить для других адаптеров

У других адаптеров свой ключ, передаваемый через launch_arguments без изменений. Например, у CodeLLDB:

[profiles.remote.launch_arguments]
sourceMap = { "/build" = "${root}" }

Точное имя ищите в документации адаптера.

Как читать симптомы

Симптом На что указывает
Исходника нет вовсе сообщённого пути локально не существует — отображения нет
Номер строки верный, файл не тот префикс отображён не в тот каталог
Большинство файлов работает, один каталог нет второе монтирование без отображения
Точки останова не привязываются то же расхождение, вид с другой стороны
Исходник есть у библиотечного кода, но не у вашего ваш код переехал после сборки

Когда никакого контейнера нет

Если всё работает локально, а исходника всё равно нет, скорее всего у фрейма его и не бывает:

  • стандартная библиотека, собранная без отладочной информации;
  • зависимость, исходников которой нет на этой машине;
  • код, перемещённый или переименованный после сборки бинарника.

Фрейм при этом остаётся выбираемым, и переменные могут быть доступны — см. Стек вызовов.

Для Rust и C/C++ последний случай лечится пересборкой после переезда каталога проекта: пути зашиваются в бинарник во время сборки.

Как проверить, что починилось

  1. Запустите сессию и остановитесь где-нибудь.
  2. В панели исходника должен быть ваш файл по вашему пути.
  3. В панели Breakpoints кружки должны стать залитыми, а не приглушёнными.

Если точки привязываются, а исходника всё ещё нет, значит отображение верно для направления точек останова и неверно для направления отображения — перепроверьте обе стороны на опечатку.