(gdb) /* Нажмите ENTER для его выполнения и перехода к следующему */
1511 if (fp == NULL)
(gdb) /* снова ENTER */
1519 save = tree = tree->lnode; (gdb) /* И снова */
1520 for (numnodes = 0; tree != NULL; tree = tree->rnode)
Команда
step
является альтернативной командой для пошагового
исполнения. Между
next
и
step
есть важное различие,
next
выполняет следующий оператор. Если этот оператор содержит вызов функции, эта функция вызывается и возвращается до того, как GDB вернет себе управление от работающей программы.
С другой стороны, когда вы используете с содержащим вызов функции оператором
step
, GDB входит в вызываемую функцию, позволяя вам продолжить пошаговое исполнение (или трассировку) программы. Если оператор не содержит вызов функции,
step
аналогична
next
.
ЗАМЕЧАНИЕ. Легко забыть, какая команда была использована, и продолжать нажимать ENTER для выполнения последующих операторов. Если вы используете
step
, вы случайно можете войти в библиотечную функцию, такую как
strlen
или
printf
, с которой на самом деле не хотите возиться. В таком случае можно использовать команду
finish
, которая вызывает исполнение программы до возврата из текущей функции
Вывести содержимое памяти можно с использованием команды
print
. GDB распознает синтаксис выражений С, что упрощает и делает естественным проверку структур, на которые ссылаются указатели:
(gdb) print *save /* Вывести структуру, на которую указывает save */
idx = 0}, hash = {next = 0x8095250, name = 0x0, length = 0, value = 0x0,
ref = 1}}, type = Node_expression_list, flags = 1}
В заключение, команда
cont
(continue — продолжить) дает возможность продолжить выполнение программы. Она будет выполняться до следующей контрольной точки или до нормального завершения, если других контрольных точек нет. Этот пример продолжается с того места, на котором остановился предыдущий:
1520 for (numnodes = 0; tree != NULL; tree = tree->rnode)
(gdb) cont /* Продолжить *!
Continuing.
hello, world
Program exited normally. /* Сообщение от GDB */
(gdb) quit /* Выйти из отладчика */
Отслеживаемая точка (watchpoint) подобна контрольной точке, но используется для данных, а не для кода. Отслеживаемые точки устанавливаются для переменной (или поля структуры или объединения или элемента массива), при их изменении GDB посылает уведомления. GDB проверяет значение отслеживаемой точки по мере пошагового
исполнения программы и останавливается при изменении значения. Например, переменная
do_lint_old
в
gawk
равна true, когда была использована опция
– -lint_old
. Эта переменная устанавливается в true функцией
getopt_long
. (Мы рассмотрели
getopt_long
в разделе 2.1.2 «Длинные опции GNU»). В файле
main.c
программы
gawk
:
int do_lint_old = FALSE;
/* предупредить о материале, не имевшейся в V7 awk */
...
static const struct option optab[] = {
...
{ "lint-old", no_argument, &do_lint_old, 1 },
...
};
Вот пример сеанса, показывающего отслеживаемую точку в действии:
$ gdb gawk /* Запустить GDB с gawk */
GNU gdb 5.3
...
(gdb) watch do_lint_old
/* Установить отслеживаемую точку для переменной */
Hardware watchpoint 1: do_lint_old
(gdb) run --lint-old 'BEGIN { print "hello, world" }'
/* Проверка отслеживаемой точки при работе программы */
Hardware watchpoint 1: do_lint_old
Hardware watchpoint 1: do_lint_old
Old value = 0 /* Отслеживаемая точка останавливает программу */
New value = 1
0x420c4219 in _getopt_internal from /lib/i686/libc.so.6
(gdb) where /* Трассировка стека */
#0 0x420c4219 in _getopt_internal from /lib/i686/libc.so.6
#1 0x420c4e83 in getopt_long from /lib/i686/libc.so.6
#2 0x080683a1 in main (argc=3, argv=0xbffff8a4) at main.c:293
#3 0x420158d4 in __libc_start_main from /lib/i686/libc.so.6
(gdb) quit /* На данный момент мы закончили */
The program is running. Exit anyway? (y or n) y /* Да */
GDB может делать гораздо больше, чем мы здесь показали. Хотя руководство GDB большое, его стоит прочесть целиком хотя бы один раз, чтобы ознакомиться с его командами и возможностями. После этого, возможно, будет достаточно просмотреть файл
NEWS
в каждом новом дистрибутиве GDB, чтобы узнать, что нового или что изменилось.
Стоит также распечатать справочную карточку GDB, которая поставляется в дистрибутиве GDB в файле
gdb/doc/refcard.tex
. Создать печатную версию справочной карточки для PostScript после извлечения исходника и запуска configure можно с помощью следующих команд: