- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Linux программирование в примерах - Арнольд Роббинс
Шрифт:
Интервал:
Закладка:
Оставшаяся часть программы заполнена функцией factorial():
1 #include <stdio.h>
2 #include "dbug.h"
3
4 int factorial (value)
5 register int value;
6 {
7 DBUG_ENTER("factorial");
8 DBUG_PRINT("find", ("find %d factorial", value));
9 if (value > 1) {
10 value *= factorial(value — 1);
11 }
12 DBUG_PRINT("result", ("result is %d", value));
13 DBUG_RETURN(value);
14 }
Когда программа откомпилирована и скомпонована вместе с библиотекой dbug, ее можно запустить обычным способом. По умолчанию, программа не создает вывод отладки. Но со включенной отладкой доступны различные виды вывода:
$ factorial 1 2 3 /* Обычный запуск, без отладки */
1
2
6
$ factorial -#t 1 2 3/* Вывести трассировку вызовов функций, обратите внимание на вложенность */
| >factorial
| <factorial
1 /* Обычный вывод в stdout */
| >factorial
| | >factorial
| | <factorial /* Вывод отладки в stderr */
| <factorial
2
| >factorial
| | >factorial
| | | >factorial
| | | <factorial
| | <factorial
| <factorial
6
<?func?
$ factorial -#d 1 2/* Показать отладочные сообщения DBUG_PRINT() */
?func?: args: argv[2] = 1
factorial: find: find 1 factorial
factorial: result: result is 1
1
?func?: args: argv[3] = 2
factorial: find: find 2 factorial
factorial: find: find 1 factorial
factorial: result: result is 1
factorial: result: result is 2
2
Опция -# управляет библиотекой dbug. Она «особая» в том смысле, что DBUG_PUSH() будет принимать всю строку, игнорируя ведущие символы '-#', хотя вы могли бы использовать при желании другую опцию, передав DBUG_PUSH() лишь строку аргументов опций (если вы используете getopt(), это optarg).
Управляющая строка состоит из набора опций и аргументов. Каждая группа опций и аргументов отделяется от других символом двоеточия. Каждая опция представлена одной буквой, а аргументы этой опции отделяются от нее запятыми. Например:
$ myprog -#d,mem,ipc:f,check_salary,check_start_date -f infile -o outfile
Опция d включает вывод DBUG_PRINT(), но лишь если первая строка аргумента является "mem" или "ipc". (Если аргументов нет, выводятся все сообщения DBUG_PRINT().) Сходным образом опция f ограничивает трассировку вызовов функций лишь указанными функциями, check_salary() и check_start_date().
Следующий список опций и аргументов воспроизведен из руководства библиотеки dbug. Квадратные скобки заключают необязательные аргументы. Мы включаем здесь лишь те, которые находим полезными; полный список см. в документации.
d [,ключевые слова]
Разрешает вывод от макросов с указанными ключевыми словами. Пустой список ключевых слов предполагает, что выбраны все ключевые слова.
F
Помечает каждую строку вывода отладки именем исходного файла, содержащего макрос, осуществляющий вывод.
i
Идентифицирует процесс, выводящий каждую отладочную или трассировочную строку номером 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 в конечной сборке, мы смогли построить готовую версию без других изменений исходного кода.
Чтобы извлечь максимальную выгоду от библиотеки dbug, нужно использовать ее последовательно, по всей программе. Это проще, если вы используете ее с начала проекта, но в качестве эксперимента мы обнаружили, что с помощью простого сценария awk мы смогли включить библиотеку в программу с 30 000 строк кода за несколько часов работы. Если вы можете позволить себе накладные расходы, лучше всего оставить ее в конечной сборке вашей программы, чтобы можно было ее отлаживать без необходимости предварительной перекомпиляции.
Мы нашли, что библиотека dbug является удачным дополнением к внешним отладчикам, таким, как GDB; она обеспечивает организованный и последовательный способ применения поддержки к коду С. Она также довольно элегантно сочетает многие из методик, которые мы ранее в данной главе очертили отдельно. Особенно полезна особенность динамической трассировки вызовов функций, и она доказывает свою бесценность в качестве помощи в изучении поведения программы, если вы незнакомы с ней.
15.5.2. Отладчики выделения памяти
Игнорируя такие проблемы, как плохой дизайн программы, для любого крупномасштабного практического приложения единственной сложной задачей программиста на С является управление динамической памятью (посредством malloc(), realloc() и free()).
Этот факт подкреплен большим количеством инструментов, доступных для отладки динамической памяти. Имеется значительное перекрывание того, что предлагают данные утилиты. Например:
• Обнаружение утечек памяти: память, которая выделяется, а затем становится недоступной.
• Обнаружение не освобождаемой памяти: память, которая выделяется, но никогда не освобождается. Не освобождаемая память не всегда является ошибкой, но определение таких случаев дает вам возможность проверить, что с ними все в порядке.
• Обнаружение неправильных освобождений: память, которая освобождается дважды, или функции free() передаются указатели, которые не были получены с помощью malloc().
• Обнаружение использования уже освобожденной памяти: память, которая освобождена, используется через висячий указатель.
• Обнаружение выхода за границы выделенной памяти: получение доступа или сохранение в память за пределами выделенной границы.
• Предупреждение об использовании неинициализированной памяти. (Многие компиляторы могут выдавать такие предупреждения.)
• Динамическая трассировка функций: когда появляется ошибочный доступ к памяти, вы получаете трассировку от того места, где память используется, до того места, где она была выделена.
• Управление инструментами посредством использования переменных окружения.
• Файлы журналов для необработанной отладочной информации, которая может быть обработана позже для создания полезных отчетов.
Некоторые утилиты просто записывают эти события. Другие организуют жуткое завершение программы приложения (посредством SIGSEGV), чтобы на код-нарушитель можно было точно указать из отладчика. Вдобавок, большинство спроектированы для работы вместе с GDB.
Некоторые инструменты требуют изменения исходного кода, такого, как вызов специальных функций или использование особого заголовочного файла, дополнительных #define и статической библиотеки. Другие работают посредством использования специального механизма библиотек общего пользования Linux/Unix для прозрачной установки себя в качестве заместителя стандартных библиотечных версий malloc() и free().

