Отладчик

Флаг -g (или --отладка) встраивает в объектный файл настоящую DWARF-отладочную информацию через LLVM DebugInfoBuilder — тот же самый механизм, которым пользуется clang для C/C++. Никакого собственного, отдельного инструмента отладки при этом не появляется — запускается уже установленный lldb или gdb, как для любой другой скомпилированной программы:

запустить программа.код -g -c
lldb ./программа
# (b программа.код:10   — точка останова по номеру строки
#  run                  — запустить
#  next / step          — шаг с обходом/входом в вызовы
#  bt                   — стек вызовов
#  continue)

Работает без каких-либо ограничений:

  • Точки останова по номеру строки (b файл.код:N) — для любой функции

и метода программы, включая тело параллельно ... конец.

  • Пошаговое выполнение (next/step/continue).
  • Полноценный стек вызовов (bt) с настоящими именами функций/методов

«Сферы» на каждом уровне.

  • Просмотр исходного кода прямо в отладчике (строка -> N перед

текущей позицией).

✅ Проверено напрямую в этой среде разработки: и lldb (18.1.3), и gdb (15.1) корректно останавливаются на нужной строке, шагают по коду и строят стек вызовов через несколько функций подряд, включая переход из потока параллельно обратно в породившую его функцию. Каждый собранный с -g объектный файл дополнительно прогоняется через opt -passes=verify в рамках тестирования — эта проверка поймала (и позволила исправить) два реальных бага в самой генерации debug-info, прежде чем они попали бы к пользователю языка (см. подробности и то, как именно они проявлялись, в ИСТОРИЯ_РАЗРАБОТКИ.md).

⚠️ Честно осталось на будущее (не реализовано в этой версии): просмотр значений локальных переменных ПО ИМЕНИ (print х, frame variable) пока не поддержан — компилятор не описывает точный DWARF-тип для локальных переменных и параметров. Причина не в лени, а в объёме: для этого понадобилось бы построить полноценное DWARF-описание (DIType) для КАЖДОГО типа языка — не только целое/ дробное/верно, но и текст (показывать как C-строку или как сырой указатель?), пользовательские структуры (с именами и типами полей, включая вложенные и рекурсивные поля), Список из T/Словарь из К и З (обобщённые контейнеры) и контракты (толстые указатели {данные, vtable}) — то есть отдельная, довольно большая по объёму работа, а не расширение уже сделанного. lldb/gdb всё равно способны показать сырые байты по известному адресу (x/8xb $rsp+...), просто не «красиво», по имени переменной с типом «Сферы».

На macOS дополнительно нужен шаг dsymutil после сборки — формат Mach-O, в отличие от Linux/ELF, не встраивает debug-info прямо в исполняемый файл, оставляя её в .o; dsymutil собирает из неё отдельный .dSYM-бандл, без которого lldb на Mac не найдёт номера строк. Компилятор делает это автоматически при -g на macOS (см. слинковать_исполняемый_файл в src/main.rs) — ⚠️ этот шаг физически не тестировался (песочница для разработки компилятора — Linux, без доступа к macOS); сам механизм — стандартный, документированный Apple инструмент, но перепроверить его на реальном Mac ещё стоит.