Чтение онлайн

на главную - закладки

Жанры

Linux: Полное руководство

Аллен Питер В.

Шрифт:

Просмотрите листинг программы. Программа не делает ничего подозрительного — она всего лишь в цикле do обнуляет все элементы массива — сначала нулевой элемент a[0] становится нулем, потом первый, второй и так далее.

Попробуйте запустить программу, и вы увидите сообщение: Segmentation fault. В чем же причина? Попробуем выяснить ее с помощью отладчика gdb. Запустите отладчик с параметром test (это имя нашего исполняемого файла):

$ gdb test

В отладчике gdb введем команду run для запуска программы. И что мы видим? Что программа получила сигнал SIGSEGV, то есть имеет место ошибка Segmentation fault. Эта ошибка произошла в строке 12: a[i]=0. Но что может быть опасного в этом операторе? Ошибка Segmentation fault может произойти по нескольким причинам, одной из которых является выход за пределы массива. Проверим это: введите команду print i.

Команда print выводит значение указанной переменной (или выражения). Ого! Оказывается, мы пытаемся обнулить не нулевой элемент массива, а 715910728-ой! Почему же так произошло? Может быть, это gdb нагло врет и вместо значения переменной i выводит непонятно что? Для проверки на

лживость введите команду print developer, которая выведет на экран значение переменной developer. С переменной developer все нормально — ее значение «Denis» (рис. 22.1).

Рис. 22.1. Сессия gdb

Так что же произошло? Так как переменная i не является глобальной, ее значение не обнуляется при запуске программы. Чтобы избежать подобной ошибки, нужно инициализировать переменную при объявлении:

int i = 0;

Вот мы и нашли ошибку!

Что же еще можно сделать с помощью gdb? Можно установить breakpoint, то есть точку останова, прерывающую выполнение программы в указанном месте. Это нужно для того, чтобы проследить состояние некоторых переменных и/или стека программы перед запуском какой-нибудь функции или же для пошаговой трассировки программы. Для пошаговой трассировки программы установите точку останова для функции main:

break main

Для установки точки останова на другую функцию введите команду break и в качестве аргумента укажите имя функции. Теперь запустите программу на выполнение (команда run). Команде run можно передать также аргументы, с которыми должна запускаться программа, например, run /home/denis/report.txt.

Когда отладчик достигнет точки останова, он приостановит выполнение программы и будет ждать ваших инструкций. Затем введите команду next для выполнения следующей строки. Команда next — это команда трассировки «над» функцией, то есть оператор вызова функции будет выполнен за один шаг. Команда step используется для пошаговой трассировки функций. Если вы хотите продолжить нормальное выполнение программы после точки останова, введите команду с.

Для отображения стека программы предназначена команда bt (backtrace). Команда list используется для отображения исходного текста программы (рис. 22.2).

Рис. 22.2. Команда list

Естественно, весь текст программы не поместится на экране, поэтому отладчик отобразит только его часть. Чтобы еще раз не вводить команду list, просто нажмите Enter, и gdb выполнит предыдущую команду.

Команда help предназначена для отображения справки по командам отладчика, а программа quit — для выхода из него.

Возможности программы gdb этим не ограничиваются. Отладчик gdb — это очень мощная программа, и я советую вам почаще использовать команду help — узнаете много полезного для себя.

Если вам удобнее использовать графический интерфейс, чем символьный, вы можете воспользоваться одним из интерфейсов к программе gdb. Один из них — KDbg. Все, что мы только что проделали с помощью команд отладчика gdb, вы можете сделать, используя меню интерфейса KDbg (рис. 22.3).

Рис. 22.3. Программа KDbg

Программа KDbg понравилась мне еще тем, что позволяет удобно просматривать регистры, потоки, память, стек и прочее, имеющее непосредственное отношение к процессу отладки. Однако имейте в виду, что интерфейс KDbg сильно ограничивает возможности отладки, потому что позволяет выполнять лишь базовые функции.

Существуют и другие оболочки для отладчика gdb, например, DDD. Эта оболочка обладает чуть большими возможностями, чем KDbg, но все же она является лишь надстройкой над gdb. Оболочек много, a gdb — один. Вы можете выбрать оболочку на свой вкус, а я вообще предпочитаю gdb без всяких оболочек.

Рис. 22.4. Оболочка DDD

22.4. Трассировка системных вызовов

Вы когда-нибудь задумывались о том, какие системные вызовы использует наша программа во время своего выполнения? Если да, то этот пункт как раз для вас. Возможно, пока он только удовлетворит ваше любопытство, но через некоторое время эта информация станет вам по-настоящему необходима.

Проследить, какие системные вызовы использует наша программа, позволяет программа strace. Для ее установки нужно установить пакет strace.

Формат вызова команды strace следующий:

strace [-dffhiqrtttTvxx] [-acolumn] [-eexpr] ... [-ofile] [-ppid] ... [-sstrsize] [-uusername] [command | arg ...]]

Ключи программы перечислены в таблице 22.3.

Ключи командной строки strace Таблица 22.3

Ключ Назначение
– с Подсчитывать время, затраченное на каждый вызов и обработку ошибок. В конце трассировки будет представлен подробный отчет
– d Выводить отладочные сообщения самой программы strace
на стандартный вывод ошибки
– f Трассировать дочерние процессы, созданные уже трассируемыми процессами
– ff Данная опция применятся только вместе с опцией -o имя_файла. Каждый трассируемый процесс будет записан в файл имя_файла.pid
– F Следовать вызовам vfork. Данную опцию нельзя использовать вместе с опцией -f
– h Вывести справку
– i Выводить указатель инструкции во время системного вызова
– q «Тихий режим». Подавляет вывод некоторых сообщений
– r Выводить относительную метку времени для каждого вызова
– t Перед каждой строкой выводить текущее время
– tt То же, что и -t, но будут выводиться также микросекунды
– T Показывать время, потраченное на системный вызов (то есть разницу между временем запуска и временем завершения вызова). Для каждого вызова
– v Получение дополнительной информации
– V Вывести номер версии strace
– X Выводить не-ASCII строки в шестнадцатеричном формате
– XX Выводить все строки в шестнадцатеричном формате
– a столбец Выровнять возвращаемые вызовами значения в указанном столбце (по умолчанию 40)
– e выражение Позволяет задать отслеживаемые события. За более подробной информацией обратитесь к справочной системе
– e trace=набор Определить набор отслеживаемых вызовов. Например, trace=open,close,read,write
– e trace=file Будут отслеживаться только вызовы для работы с файлами (open, stat, chmod, unlink и т.д.)
– e trace=process Отслеживаются вызовы для работы с процессами (fork, exec, wait и др.)
– e trace=network Отслеживаются сетевые вызовы
– e trace=signal Отслеживаются вызовы для работы с сигналами
– e trace=ipc Отслеживаются IPC-вызовы
– e abbrev=набор Сокращает вывод каждого члена структуры. Например, abbrev=all или abbrev=none
– e verbose=набор Различать структуры различных системных вызовов, по умолчанию verbose=all
– e raw=set Выводит не декодированные значения аргументов системных вызовов. Данный аргумент полезен, если вы не доверяете декодированию или хотите знать точное числовое представление аргумента
– e signal=набор Определяет набор трассируемых сигналов. По умолчанию signal=all. Вы можете использовать восклицательный знак для отрицания, например, signal=!SIGIO означает, что сигнал SIGIO не будет трассирован
– e read=набор Выполнять полный шестнадцатиричный и ASCII-дамп всех прочитанных вызовом read данных. Например, чтобы видеть все данные, поступающие через дескрипторы 2 и 7, введите read=2,7
– e write=набор То же, что и -e read, но только для записи
– o имя_файла Перенаправить вывод программы в указанный файл. Данный файл будет полезен для дальнейшего анализа трассировки
– p pid Присоединиться к процессу с PID=pid и начать трассировку
– s размер Установить максимальный размер строки (по умолчанию 32). Имена файлов не рассматриваются как строки, поэтому всегда будут напечатаны полностью
– S критерий Сортирует вывод гистограммы, которая выводится опцией -с, по заданному критерию: time (время), calls (вызовы), name (имя) и nothing (без сортировки)
– u имя_пользователя Запустить программу от имени указанного пользователя. Эта опция будет полезной, если вы, зарегистрировавшись как root, будете проверять корректность работы программы, если бы она была запущена под другим пользователем

Вы даже не можете себе представить, какие системные вызовы использует такая маленькая программка:

Листинг 22.2. Файл prog.с

#include <stdio.h>

int main {

 printf("Hello\n");

 return 0;

}

Откомпилируйте эту программу (

gcc -o prog prog.c
) и запустите strace:

$ strace prog

Вы увидите следующий вывод:

Поделиться:
Популярные книги

Удержать 13-го

Уолш Хлоя
Любовные романы:
остросюжетные любовные романы
эро литература
зарубежные любовные романы
5.00
рейтинг книги
Удержать 13-го

Душелов. Том 3

Faded Emory
3. Внутренние демоны
Фантастика:
альтернативная история
аниме
фэнтези
ранобэ
хентай
5.00
рейтинг книги
Душелов. Том 3

Слово мастера

Лисина Александра
11. Гибрид
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Слово мастера

Слова сияния

Сандерсон Брендон
2. Архив штормсвета
Фантастика:
фэнтези
8.71
рейтинг книги
Слова сияния

Кодекс Крови. Книга ХIII

Борзых М.
13. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХIII

Шайтан Иван 5

Тен Эдуард
5. Шайтан Иван
Фантастика:
попаданцы
альтернативная история
историческое фэнтези
5.00
рейтинг книги
Шайтан Иван 5

Санек

Седой Василий
1. Санек
Фантастика:
попаданцы
альтернативная история
4.00
рейтинг книги
Санек

Третий

INDIGO
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий

Локки 7. Потомок бога

Решетов Евгений Валерьевич
7. Локки
Фантастика:
аниме
эпическая фантастика
фэнтези
5.00
рейтинг книги
Локки 7. Потомок бога

Император Пограничья 8

Астахов Евгений Евгеньевич
8. Император Пограничья
Фантастика:
городское фэнтези
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Император Пограничья 8

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Поход

Валериев Игорь
4. Ермак
Фантастика:
боевая фантастика
альтернативная история
6.25
рейтинг книги
Поход

Барон ломает правила

Ренгач Евгений
11. Закон сильного
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Барон ломает правила

Локки 2. Потомок бога

Решетов Евгений Валерьевич
2. Локки
Фантастика:
городское фэнтези
аниме
попаданцы
5.00
рейтинг книги
Локки 2. Потомок бога