Проверка отслеживаемой точки при работе программы */
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 можно с помощью следующих команд:
$ cd gdb/doc /* Перейти о подкаталог doc */
$ make refcard.ps /* Отформатировать справочную карточку */
Предполагается, что справочная карточка будет распечатана с двух сторон листа бумаги 8,5x11 дюймов [168] (размер «letter») в горизонтальном (landscape) формате. В ней на шести колонках предоставлена сводка наиболее полезных команд GDB. Мы рекомендуем распечатать ее и поместить под своей клавиатурой при работе с GDB.
168
Примерно 213x275 мм — Примеч. перев.
15.4. Программирование для отладки
Имеется множество методик для упрощения отладки исходного кода, от простых до сложных. В данном разделе мы рассмотрим ряд из них.
15.4.1. Код отладки времени компилирования
Несколько методик относятся к самому исходному коду.
15.4.1.1.
Использование отладочных макросов
Возможно, простейшей методикой времени компилирования является использование препроцессора для создания условно компилируемого кода. Например:
#ifdef DEBUG
fprintf(stderr, "myvar = %d\n", myvar);
fflush(stderr);
#endif /* DEBUG */
Добавление
– DDEBUG
к командной строке компилятора вызывает
fprintf
при выполнении программы.
Рекомендация: сообщения отладки посылайте в
stderr
, чтобы они не были потеряны в канале и чтобы их можно было перехватить при помощи перенаправления ввода/вывода. Убедитесь, что использовали
fflush
, чтобы сообщения были выведены как можно скорее
ЗАМЕЧАНИЕ. Идентификатор
DEBUG
, хотя он и очевидный, также часто злоупотребляется. Лучшей мыслью является использование специфического для вашей программы идентификатора, такого как
MYAPPDEBUG
. Можно даже использовать различные идентификаторы для отладки кода в различных частях программы, таких, как файловый ввод/вывод, верификация данных, управление памятью и т.д.
Разбрасывание больших количеств операторов
#ifdef
по всему коду быстро становится утомительным. Большое количество
#ifdef
скрывают также логику программы. Должен быть лучший способ, и в самом деле, часто используется методика с условным определением специального макроса для вывода:
/* МЕТОДИКА 1 --- обычно используемая, но не рекомендуемая, см. текст */
/* В заголовочном файле приложения: */ #ifdef MYAPPDEBUG