будет принимать всю строку, игнорируя ведущие символы '
– #
',
хотя вы могли бы использовать при желании другую опцию, передав
DBUG_PUSH
лишь строку аргументов опций (если вы используете
getopt
, это
optarg
).
Управляющая строка состоит из набора опций и аргументов. Каждая группа опций и аргументов отделяется от других символом двоеточия. Каждая опция представлена одной буквой, а аргументы этой опции отделяются от нее запятыми. Например:
Идентифицирует процесс, выводящий каждую отладочную или трассировочную строку номером ID для этого процесса.
L
Помечает каждую строку вывода отладчика номером строки исходного файла, в котором находится осуществляющий вывод макрос.
о[,файл]
Перенаправляет поток вывода отладчика в указанный файл. Потоком вывода по умолчанию является
stderr
. Пустой список аргументов перенаправляет вывод в
stdout
.
t[,N]
Включает трассировку потока управления функций. Максимальная глубина вложения определяется
N
, по умолчанию используется 200.
Для завершения нашего обсуждения вот остальные макросы, определенные библиотекой
dbug
.
DBUG_EXECUTE(строка, код)
Этот макрос похож на
DBUG_PRINT
: первый аргумент является строкой, выбранной с помощью опции
d
, а второй — код для исполнения:
DBUG_EXECUTE("abort", abort);
DBUG_FILE
Это значение типа
FILE*
для использования с процедурами
<stdio.h>
.
Оно позволяет осуществлять собственный вывод в поток файла отладки.
DBUG_LONGJMP(jmp_buf env, int val)
Этот макрос заключает в оболочку вызов
longjmp
, принимая те же самые аргументы, так что библиотека
dbug
будет знать, когда вы сделали нелокальный переход.
DBUG_POP
Этот макрос выталкивает из стека один уровень сохраненного состояния отладки, созданный макросом
DBUG_PUSH
. Он довольно эзотерический; вы скорее всего не будете его использовать.
DBUG_SETJMP(jmp_buf env)
Этот макрос заключает в оболочку вызов
setjmp
, принимая те же самые аргументы. Он позволяет библиотеке
dbug
обрабатывать нелокальные переходы.
В другом воплощении, в первой начинающей компании, для которой мы работали [177] , мы использовали в своем продукте библиотеку
dbug
. Она была неоценимой при разработке, а опустив
– DDBUG
в конечной сборке, мы смогли построить готовую версию без других изменений исходного кода.
177
Хотя нам следовало бы усвоить свой урок после первой компании, мы перешли ко второй. С тех пор, как мы это выяснили, мы обычно избегаем начинающие компании. Ваша выгода, конечно, может меняться — Примеч. автора.
Чтобы извлечь максимальную выгоду от библиотеки
dbug
, нужно использовать ее последовательно, по всей программе. Это проще, если вы используете ее с начала проекта, но в качестве эксперимента мы обнаружили, что с помощью простого сценария
awk
мы смогли включить библиотеку в программу с 30 000 строк кода за несколько часов работы. Если вы можете позволить себе накладные расходы, лучше всего оставить ее в конечной сборке вашей программы, чтобы можно было ее отлаживать без необходимости предварительной перекомпиляции.
Мы нашли, что библиотека
dbug
является удачным дополнением к внешним отладчикам, таким, как GDB; она обеспечивает организованный и последовательный способ применения поддержки к коду С. Она также довольно элегантно сочетает многие из методик, которые мы ранее в данной главе очертили отдельно. Особенно полезна особенность динамической трассировки вызовов функций, и она доказывает свою бесценность в качестве помощи в изучении поведения программы, если вы незнакомы с ней.
15.5.2. Отладчики выделения памяти
Игнорируя такие проблемы, как плохой дизайн программы, для любого крупномасштабного практического приложения единственной сложной задачей программиста на С является управление динамической памятью (посредством
malloc
,
realloc
и
free
).
Этот факт подкреплен большим количеством инструментов, доступных для отладки динамической памяти. Имеется значительное перекрывание того, что предлагают данные утилиты. Например: