/* ...оставшаяся часть кода... */
}
Теперь из GDB установите контрольную точку в debug_dummy()
, а затем запустите программу обычным способом:
(gdb) break debug_dummy /* Установить контрольную точку для фиктивной функции */
Breakpoint 1 at 0x8055885: file whizprog.c, line 3137.
(gdb) run /* Запуск программы */
По достижении контрольной точки для debug_dummy()
вы можете установить вторую контрольную точку для check_salary()
и продолжить исполнение:
(gdb) run /* Запуск программы */
Starting program: /home/arnold/whizprog
Breakpoint 1, debug_dummy() at whizprog.c, line 3137
3137 void debug_dummy(void) { return; } /* Достижение контрольной точки */
(gdb) break check_salary
/* Установить контрольную точку для интересующей функции */
Breakpoint 2 at 0x8057913: file whizprog.c, line 3140.
(gdb) cont
По достижении второй контрольной точки программа готова завершиться неудачей, и вы можете пошагово ее пройти, делая все необходимое для отслеживания проблемы.
Вместо использования фиксированной константы ('++count == 1426
') можно использовать глобальную переменную, которая устанавливается отладчиком в любое нужное вам значение. Это дает возможность избежать перекомпилирования программы
Для gawk
мы пошли на один шаг дальше и внесли возможность отладочной ловушки в язык, так что функция ловушки могла быть вызвана из программы awk
. При компилировании для отладки доступна специальная ничего не делающая функция stopme()
. Эта функция, в свою очередь, вызывает функцию С с тем же названием. Это позволяет нам поместить вызовы stopme()
в завершающуюся неудачей программу awk
непосредственно перед сбойным участком. Например, если gawk
выдает ошибочные результаты для программы awk
в 1200-й вводимой записи, мы можем добавить в программу awk
строку, подобную этой:
NR == 1198 { stopme() } # Остановиться для отладки, когда число записей == 1198
/* ...оставшаяся часть программы как ранее... */
Затем из GDB мы можем установить контрольную точку на функции С stopme()
и запустить программу awk
. Когда контрольная точка срабатывает, мы можем затем установить контрольные точки на другие части gawk
, где, как мы ожидаем, находится действительная проблема.
Методика функции-ловушки полезна сама по себе. Однако, возможность переместить ее на уровень приложения умножает ее полезность, и она сохранила нам бесчисленное число часов отладки при отслеживании непонятных проблем.
15.5. Отладочные инструменты
Помимо GDB и различных ловушек в исходном коде, которые вы используете для общей отладки, имеется ряд полезных пакетов, которые могут помочь обнаружить определенные разновидности проблем. Поскольку управление динамической памятью является в крупномасштабных программах такой трудной задачей, многие инструменты фокусируются на этой области, часто действуя в качестве замещающих malloc()
и free()
элементов
Имеются коммерческие инструменты, которые делают множество (или все) из тех вещей, что и описываемые нами программы, но не все они доступны для GNU/Linux, а многие довольно дороги. Все пакеты, обсуждающиеся в данном разделе, являются свободно доступными.
15.5.1. Библиотека dbug
— усовершенствованный printf()
Первым пакетом, который мы исследуем, является библиотека dbug
. Она основана на идее условно компилируемого отладочного кода, которую мы представили ранее в данной главе, но идет намного дальше, предоставляя сравнительно сложную трассировку времени исполнения и условный вывод отладки. Она реализует многие из описанных нами советов, избавляя вас от хлопот по собственной их реализации.
Библиотека dbug
, написанная Фредом Фишем (Fred Fish) в начале 1980-х, была с тех пор несколько усовершенствована. Теперь она явным образом является общим достоянием, поэтому ее можно использовать без всяких проблем как в свободном, так и частном программном обеспечении. Она доступна через архив FTP Фреда Фиша[175] как в виде сжатого файла tar, так и в виде архива ZIP. Документация хорошо резюмирует dbug
: