Отладчиком называется программа, которая выполняет внутри себя другую программу. Основное назначение отладчика - дать возможность пользователю в определенной степени осуществлять контроль за выполняемой программой, т.е. определять, что происходит в процессе ее выполнения. Наиболее известным отладчиком для Linux является программа GNU GDB, которая содержит множество полезных возможностей, но для простой отладки достаточно использовать лишь некоторые из них.
Когда вы запускаете программу, содержащую ошибки, обнаруживаемые лишь на стадии выполнения, возникают несколько вопросов, на которые вам нужно найти ответ:
Эти действия требуют, чтобы пользователь отладчика был в состоянии:
Программа GDB предоставляет все перечисленные возможности. Она называется отладчиком на уровне исходного текста, создавая иллюзию, что вы выполняете операторы C++ из вашей программы, а не машинный код, в который они действительно транслируются.
Для иллюстрации мы используем систему, которая компилирует программы на C++ в исполняемые файлы, содержащие машинный код. В результате этого процесса информация об оригинальном коде C++ теряется при трансляции. Отдельный оператор C++ обычно преобразуется в несколько машинных команд, а большинство имен локальных переменных просто теряется. Информация о именах переменных и операторах C++ в вашей исходной программе не является необходимой для ее выполнения. Поэтому, для правильной работы отладчика на уровне исходного текста, компилятор должен поместить в программу некоторую дополнительную информацию. Обычно ее добавляют к информации, используемой компоновщиком, в исполняемый файл.
Чтобы указать компилятору (gcc), что вы планируете отлаживать вашу программу, и
поэтому нуждаетесь в дополнительной информации, добавьте ключ -g в опции
компиляции и компоновки. Например, если ваша программа состоит из двух файлов
main.C и utils.C, можете откомпилировать ее командами:
gcc -c -g -Wall main.C
gcc -c -g -Wall utils.C
gcc -g -o myprog main.ob utils.o
или одной командой:
gcc -g -Wall -o myprog main.o utils.o
Обе последовательности команд приводят к созданию исполняемого файла myprog.
Чтобы выполнить полученную программу под управлением gdb, введите
gdb myprog
вы увидите командное приглашение GDB:
(gdb)
Это очень простой, но эффективный тексовый интерфейс отладчика. Его вполне достаточно, чтобы ознакомиться с основными командами gdb.
Когда GDB запускается, ваша программа в нем еще не выполняется; вы должны сами сообщить GDB, когда ее запустить. Как только программа приостанавливается в процессе выполнения, GDB ищет определенную строку исходной программы с вызовом определенной функции - либо строку в программе, где произошел останов, либо строку, содержащую вызов функции, в которой произошел останов, либо строку с вызовом функции и т.д. Далее используется термин ``текущее окно'', чтобы сослаться на точку останова.
Как только возникает командное приглашение, вы можете использовать следующие команды:
help command
выводит краткое описание команды GDB. Просто help
выдает список доступных
разделов справки;
run command-line-arguments
запускает Вашу программу с определенными аргументами командной строки. GDB
запоминает переданные аргументы, и простой перезапуск программы с помощью
run
приводит к использованию этих аргументов;
where
создает трассу - цепочку вызовов функций, произошедших до попадания программы в текущее место. Синонимом является команда bt;
up
перемещает текущее окно так, чтобы GDB анализировал место, из которого
произошел вызов данного окна. Очень часто Ваша программа может войти в
библиотечную функцию - такую, для которой не доступен исходный код,
например, в процедуру ввода-вывода. вам может понадобиться несколько команд
up
, чтобы перейти в точку программы, которая была выполнена последней;
down
производит эффект, обратный up;
print E
выводит значение E в текущем окне программы, где E является выражением C++ (обычно просто переменной). Каждый раз при использовании этой команды, GDB нумерует ее упоминание для будущих ссылок. Например:
(gdb) print A[i] $2 = -16
(gdb) print $2 + ML $3 = -9
сообщает нам, что величина A[i] в текущем окне равна -16, и что при добавлении этого значения к переменной ML получится -9;
quit
выход из GDB;
Ctrl-c
если программа запущена через оболочку shell, Ctrl-c немедленно прекращает ее выполнение. В GDB программа приостанавливается, пока ее выполнение не возобновится;
break place
установить точку останова; программа приостановится при ее достижении. Простейший способ - установить точку останова после входа в функцию, например:
(gdb) break MungeData Breakpoint 1 at 0x22a4:
file main.C, line 16.
Команда break main
остановит выполнение в начале программы.
вы можете установить точки останова на определенную строку исходного кода:
(gdb) break 19 Breakpoint 2 at 0x2290:
file main.C, line 19.
(gdb) break utils.C:55 Breakpoint 3 at 0x3778:
file utils.C, line 55.
Когда вы запустите программу и она достигнет точки останова, то увидите сообщение об этом и приглашение, например:
Breakpoint 1, MungeData (A=0x6110, N=7) at main.c:16
(gdb);
delete N
удаляет точку останова с номером N. Если опустить N, будут удалены все точки останова;
cont или continue
продолжает обычное выполнение программы;
step
выполняет текущую строку программы и останавливается на следующем операторе для выполнения;
next
похожа на step, однако, если текущая строка программы содержит вызов функции (так что step должен будет остановиться в начале функции), не входит в эту функцию, а выполняет ее и переходит на следующий оператор;
finish
выполняет команды next без остановки, пока не достигнет конца текущей функции.