Отладка программ при помощи GDB

Всякий раз, когда ваша программа работает неверно (выдает неверный ответ, или ошибку во время исполнения программы), на помощь вам прийдет отладчик GDB (Gnu debugger). Он позволяет подробно изучить ход выполнения программы, исполняя ее пошагово и просматривая значения переменных.

Для использования GDB необходимо откомпилировать программу с ключом -g, например, c++ -g program.cpp. После этого необходимо запустить gdb, передав ему в качестве параметра имя отлаживаемого исполняемого файла: gdb a.out.

После приглашения (gdb) можно вводить различные команды. Многие команды можно сокращать до одной-двух букв. Можно использовать клавишу <Tab> для завершения имени команды, переменной или функции исходного года. Простое нажатие клавиши <Enter> без указания команды повторяет последнюю ранее введенную команду. Для завершения работы GDB введите команду quit (сокращается до q).

Для получения справки небходимо ввести команду help (h), для получения справки по командам того или иного раздела необходимо дать команду help с указанием имени раздела, например, help breakpoints для получения справки по командам, связанным с точками установки. Команда help без параметров выводит список всех разделов справки.

Исполнение программы

run (r) начинает исполнение программы до первой точки остановки или возникновения ошибки вроде Floating point exception или Segmentation fault. Для перенаправления ввода-вывода команды можно использовать команду run <input_file >output_file.

continue (c) продолжить выполнение программы до следующей точки остановки или ошибки.

step (s) Продолжить выполнение программы пока управление не достигнет следующей строки исходного текста. При этот происходит вход в функцию, то есть при вызове каждой функции программа также останавливается.

next (n) Работает аналогично команде step, но при этом функции вызываются без остановки.

finish Продолжить выполнение программы до возврата из текущей функции, напечатать возвращаемое значение.

Командам step и next можно передать числовой параметр, в этом случае это будет означать выполнение этой команды заданное число раз.

Исследование данных

print expr (p) Отобразить значение выражения expr. Допускается использование практически любого выражения языка C/C++, в том числе и вызовы функций. Например: p a, p sqrt(n), p (a&b)>>3.

Если имеется динамический массив (например, int * p=new int[10]), то при выводе его на экран (print p) будет напечатано значение указателя, то есть адрес в памяти компьютера. Если хочется вывести весь массив (или его часть), то необходимо воспользоваться оператором создания виртуального массива @, левый операнд которого - первый элемент запрашиваемого массива, а правый - длина желаемого массива. Например, print *p@10 или print p[0]@10.

Если необходимо отслеживать значение какого-либо выражения, то его можно добавить в список автоматического отображения, и тогда оно будет выводиться каждый раз при остановке программы.

display expr Добавить выражение expr к списку автоматического отображения. Каждое такое выражение получает свой номер.

delete display n Удалить выражение с номером n из списка автоматического отображения.

disable display n Отключить отбражение элемента с номером n из списка, не удаляя его.

enable display n Включить отображение элемента n из списка, отключенного ранее.

display Напечатать значения всех автоматически отображаемых выражений, как это происходит при остановке программы.

info display Вывести список автоматически отображаемых выражений.

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

Точки останова

В произвольном месте программы можно поставить точку останова, при достижении которой команда остановится. При этом можно исследовать значения переменных, продолжить выполнение программы при помощи команд c, s, n или выполнить другие команды GDB.

break n (b) Установить точку останова на строке исходного кода с номером n. Все точки останова имеют свои номера, определяемые при их установке.

break function Установить точку останова на функции function. Исполнение программы остановится при вызове этой функции. Распространенный пример: break main для того, чтобы можно было пошагово исполнять программу с самого начала.

tbreak ... Установка разовой точки останова. Работает аналогично break, но точка останова автоматически удаляется при достижении ее.

break ... if cond Установка условной точки останова. Выполнение останавливается на данной строке или функции, если выполнено условие cond. Пример: break 120 if a==15.

clear function или clear n Удалить точку останова на функции function или в строке с номером n.

delete диапазон (d) Удалить точки останова с номерами из указанного диапазона. Например, delete 1-5 или delete 4. Если диапазон не задан, удаляются все точки останова.

disable диапазон Отключить точки из заданного диапазона.

enable диапазон Включить точки из заданного диапазона.

enable once диапазон Точки из заданного диапазона включаются до первого срабатывания, после чего отключаются.

enable delete диапазон Точки из заданного диапазона включаются до первого срабатывания, после чего удаляются.

condition n cond Превращение точки останова с номером n в условную с условием cond.

condition n Превращение точки останова с номером n в безусловную.

info break Вывести информацию обо всех имеющихся точках останова.

Кроме того, можно устанавливать набор команд, которые будут выполнены при достижении точки останова, например, можно просмотреть или изменить значения переменных. Об этом рассказывается на странице 41 русской документации по GDB.

Если непонятно, в каком месте программы находится ошибка, то возможно в отладке помогут точки наблюдения. Точка наблюдения позволяет остановить программу в любом месте, когда изменяется заданное значение.

watch expr Установить точку наблюдения на выражении expr. Исполнение программы останавливается, когда значение expr сохраняется программой и его величина изменяется. Пример: watch a.

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

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

info watch Вывести информацию о всех точках наблюдения.

Просмотр исходного кода и стека программы

Для вывода исходного текста программы используется команда list (l) в различных вариантах:

list n Вывести строки исходного кода, вокруг строки с номером n.

list function Вывести начало кода функции function.

list n,m Вывести строки с номерами от n до m.

list n, Вывесть строки, начиная с n.

list ,m Вывести строки до номера m.

list Вывести еще немного строк. По умолчанию выводится 10 следующих строк, после ранее выведенных. Это значение можно изменить командой set listsize число.

Когда программа остановила свою работу, прежде всего необходимо узнать, где это произошло и как она туда попала. Особенно это полезно при отладке run-time ошибок.

Всякий раз, когда вызывается функция, информация о вызове сохраняется в стеке. Информация сохраняется в блоке данных, называемом кадром стека.

where Вывести содержимое стека.

frame n Переключиться в кадр с номером n. При этом можно просматривать значения локальных переменных в контексте этого кадра.

up n Переместиться по стеку вверх на n кадров. По умолчанию n равно 1.

down n Переместиться по стеку вниз на n кадров.

info frame Вывести информацию о текущем кадре.

info args Вывести информацию об аргументах текущего кадра.

info locals Вывести информацию о всех локальных переменных текущего кадра.