Отладка C++ в GDB: короткая инструкция для новичка
За полчаса научитесь запускать программу под GDB, ставить точки останова, смотреть значения переменных и ловить падение по сегфолту — без чтения многостраничного мануала.

К концу этой инструкции вы сможете запустить программу на C++ под отладчиком GDB, остановить её в нужной строке, посмотреть значения переменных и найти место, где программа падает с Segmentation fault. На всё уйдёт минут 30, если компилятор и отладчик уже стоят. Всё показано для GCC (g++) и GDB под Linux; на macOS и Windows отладчик может отличаться — об этом в конце.
Что нужно иметь до начала
Проверьте, что у вас установлены компилятор и отладчик. В терминале выполните две команды:
g++ --version
gdb --version
Обе должны вывести номер версии. Если пишет command not found:
- Ubuntu/Debian:
sudo apt install g++ gdb - Fedora:
sudo dnf install gcc-c++ gdb - macOS: там по умолчанию Clang и отладчик
lldb, а не GDB — команды будут другими (см. последний раздел)
Дальше нужен любой файл с кодом на C++. Возьмём заведомо сломанный пример, чтобы было что искать.
Шаг 1. Соберите программу с отладочной информацией
Ключевой момент, который пропускают новички: без флага -g отладчик не покажет ни имён переменных, ни номеров строк — только голые адреса. Создайте файл main.cpp:
#include <iostream>
#include <vector>
int sum_first_n(const std::vector<int>& data, int n) {
int result = 0;
for (int i = 0; i <= n; ++i) { // ошибка: должно быть i < n
result += data[i];
}
return result;
}
int main() {
std::vector<int> numbers = {10, 20, 30};
int total = sum_first_n(numbers, 3);
std::cout << "Сумма: " << total << std::endl;
return 0;
}
Соберите с отладочной информацией и без оптимизаций:
g++ -g -O0 main.cpp -o app
Проверка: рядом появился исполняемый файл app. Флаг -O0 отключает оптимизации — с ними компилятор переставляет и выкидывает строки, и пошаговая отладка начинает «прыгать».
Почему -g обязателен
Флаг -g кладёт в бинарник таблицу с именами переменных, номерами строк и типами. Именно её читает GDB, чтобы показать вам result, а не 0x7fff.... Один флаг — и вместо гадания по адресам вы видите свой код.
Шаг 2. Запустите под GDB и поймайте падение
Если запустить ./app напрямую, вы в лучшем случае увидите Segmentation fault и ничего больше. Запустите под отладчиком:
gdb ./app
Появится приглашение (gdb). Наберите run и нажмите Enter:
(gdb) run
Программа отработает и, если упадёт, GDB остановится на месте падения и покажет строку. Чтобы понять, откуда пришли в эту строку, наберите:
(gdb) backtrace
Проверка: вы увидите стек вызовов — цепочку функций от main до места ошибки, с номерами строк. Самый верхний кадр (#0) — там, где рвануло.
Шаг 3. Поставьте точку останова и пройдите по шагам
Точка останова (breakpoint) — место, где выполнение замрёт и отдаст управление вам. Поставим её на функцию:
(gdb) break sum_first_n
(gdb) run
Можно ставить и по номеру строки: break main.cpp:7. После run программа остановится на входе в функцию. Дальше — команды движения:
next(илиn) — следующая строка, не заходя внутрь вызовов;step(илиs) — следующая строка, заходя внутрь вызванной функции;continue(илиc) — продолжить до следующей точки останова;finish— доработать текущую функцию и вернуться к вызывающей.
Проверка: после каждого next GDB печатает номер и текст следующей строки. Вы буквально идёте по коду построчно.
Шаг 4. Посмотрите значения переменных
Остановившись внутри цикла, смотрите, что происходит:
(gdb) print i
(gdb) print result
(gdb) print data
(gdb) print data.size()
Команда print (или p) выводит значение. У контейнеров STL можно вызывать методы прямо из GDB — data.size() вернёт 3. Чтобы не печатать одно и то же каждый шаг, повесьте переменную на постоянный показ:
(gdb) display i
(gdb) display result
Проверка: теперь после каждого шага GDB сам печатает i и result. Пройдите цикл до i = 3 — на этой итерации data[3] лезет за границы вектора из трёх элементов. Вот она, причина падения.
Отладчик не находит ошибку за вас. Он показывает, что происходило на самом деле, а не то, что вы думали, будто написали. Разница между этими двумя картинами — и есть баг.
Шпаргалка по командам
| Команда | Короткая форма | Что делает |
|---|---|---|
| run | r | Запустить программу |
| break <место> | b | Точка останова на функции или строке |
| next | n | Шаг, не заходя в вызовы |
| step | s | Шаг с заходом внутрь функции |
| continue | c | Продолжить до следующего breakpoint |
| print <выр> | p | Показать значение переменной или выражения |
| backtrace | bt | Стек вызовов |
| info locals | — | Все локальные переменные текущего кадра |
| quit | q | Выйти из GDB |
Если не получилось
- «No symbol table is loaded. Use the "file" command.» — вы забыли собрать с
-g. Пересоберите:g++ -g -O0 main.cpp -o app. - При
nextотладчик перескакивает строки или значения переменных показаны как<optimized out>— включены оптимизации. Добавьте-O0, уберите-O2/-O3. - «During startup program exited with code 127» — исполняемый файл не собрался или указан неверный путь. Проверьте, что
./appсуществует и запускается сам по себе. - Программа падает, но
backtraceпоказывает??вместо имён — не хватает отладочных символов у библиотек или снова забыт-g. Для своего кода достаточно пересборки с флагом. - GDB на старте пишет предупреждение про ptrace или permission denied — на некоторых системах отладка чужих процессов ограничена. Свою программу, запущенную через
gdb ./app, это обычно не затрагивает.
Что дальше
Первое, что стоит добавить к рабочему циклу — санитайзеры. Соберите программу с -fsanitize=address -g и запустите: AddressSanitizer поймает выход за границы массива и покажет точную строку без ручного прохода по циклу. Для многопоточного кода есть -fsanitize=thread.
Когда командная строка станет тесной, переходите на графическую оболочку: режим gdb -tui показывает код и точку останова прямо в терминале, а VS Code с расширением C/C++ даёт привычную кнопочную отладку поверх того же GDB. Условные точки останова (break main.cpp:8 if i == 3) и точки на изменение переменной (watch result) — следующий уровень, к ним стоит вернуться, когда освоите базовые команды из шпаргалки.
Инфографика для маркетплейса: Три главных преимущества товара короткими фразами, выноски в безопасной зоне превью, точный размер площадки.
Спросить за 60 ₽Источники: Debugging with GDB — официальная документация GNU, GCC: Options for Debugging Your Program (-g, -O)
Частые вопросы
А если у меня Clang вместо GCC?
Как отлаживать под Windows?
Программа падает только в релизной сборке, а под отладчиком работает. Что делать?
Можно ли отладить программу, которая уже запущена и зависла?
GDB печатает вектор как непонятную структуру вместо элементов. Как посмотреть содержимое?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.