- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Linux программирование в примерах - Арнольд Роббинс
Шрифт:
Интервал:
Закладка:
Если вы забыли указать в командной строке имена файлов, для сообщения GDB имени исполняемого файла можно использовать 'file исполняемый-файл', а для имени файла дампа — 'core-file имя-файла-дампа'.
При наличии дампа ядра GDB указывает место завершения программы. Следующая программа, ch15-abort.c, делает несколько вложенных вызовов функций, а затем намеренно завершается посредством abort(), чтобы создать дамп ядра:
/* ch15-abort.c --- создает дамп ядра */
#include <stdio.h>
#include <stdlib.h>
/* recurse --- создание нескольких вызовов функций */
void recurse(void)
{
static int i;
if (++i == 3)
abort();
else
recurse();
}
int main(int argc, char **argv)
{
recurse();
}
Вот небольшой сеанс GDB с этой программой:
$ gcc -g ch15-abort.c -o ch15-abort /* Компилировать без -O */
$ ch15-abort /* Запустить программу */
Aborted (core dumped) /* Она печально завершается */
$ gdb ch15-abort core.4124 /* Запустить для нее GDB */
GNU gdb 5.3
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU
General Public License, and you are
welcome to change it and/or distribute copies of it
under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
Core was generated by 'ch15-abort'.
Program terminated with signal 6, Aborted.
Reading symbols from /lib/i686/libc.so.6...done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x42028ccl in kill() from /lib/i686/libc.so.6
(gdb) where /* Вывести трассировку стека */
#0 0x42028cc1 in kill() from /lib/i686/libc.so.6
#1 0x42028ac8 in raise() from /lib/i686/libc.so.6
#2 0x4202a019 in abort() from /lib/1686/libc.so.6
#3 0x08048342 in recurse() at ch15-abort.c:13
/* <-- Нам нужно исследовать здесь */
#4 0x08048347 in recurse() at ch15-abort.с:15
#5 0x08048347 in recurse() at ch15-abort.c:15
#6 0x0804835f in main (argc=1, argv=0xbffff8f4) at ch15-abort.c:20
#7 0x420158d4 in __libc_start_main() from /lib/i686/libc.so.6
Команда where выводит трассировку стека, то есть список всех вызванных функций, начиная с самых недавних. Обратите внимание, что имеется три вызова функции recurse(). Команда bt, означающая 'back trace' (обратная трассировка), является другим названием для where; ее легче набирать.
Вызов каждой функции в стеке называется фреймом. Этот термин пришел из области компиляторов, в которой параметры, локальные переменные и адреса возврата каждой функции, сгруппированные в стеке, называются фреймом стека. Команда frame GDB дает вам возможность исследовать определенный фрейм. В данном случае нам нужен фрейм 3. Это последний вызов recurse(), который вызвал abort():
(gdb) frame 3 /* Переместиться в фрейм 3 */
#3 0x08048342 in recurse() at ch15-abort.с:13
13 abort(); /* GDB выводит в фрейме положение в исходном коде */
(gdb) list /* Показать несколько строк исходного кода */
8 void recurse(void)
9 {
10 static int i;
11
12 if (++i == 3)
13 abort();
14 else
15 recurse();
16 }
17
(gdb) /* Нажатие ENTER повторяет последнюю команду */
18 int main(int argc, char **argv)
19 {
20 recurse();
21 }
(gdb) quit /* Выйти из отладчика (пока) */
Как показано, нажатие ENTER повторяет последнюю команду, в данном случае list, для отображения строк исходного кода. Это простой способ прохождения исходного кода.
Для редактирования командной строки GDB использует библиотеку readline, поэтому для повторения и редактирования ранее введенных команд можно использовать команды Emacs или vi. Оболочка Bash использует ту же самую библиотеку, поэтому если вам более знакомо редактирование командной строки в приглашении оболочки, GDB работает таким же образом. Эта особенность дает возможность избежать утомительного ручного ввода.
15.3.2. Установка контрольных точек, пошаговое выполнение и отслеживаемые точки
Часто при ошибках программ создается дамп ядра. Первым шагом является использование GDB с файлом core для определения процедуры, в которой произошло завершение программы. Если оригинальный двоичный файл не был откомпилирован для отладки (т.е. без -g), все, что может сообщить GDB, это имя функции, но больше никаких деталей.
Следующим шагом является перекомпилирование программы с возможностью отладки и без оптимизации, а также проверка того, что она все еще содержит ошибку. Предположив, что это так, можно запустить программу под контролем отладчика и установить контрольную точку в процедуре, вызывающей ошибку.
Контрольная точка (breakpoint) является точкой, в которой исполнение должно прерваться, остановиться. Контрольные точки можно установить по имени функции, номеру строки исходного файла, файлу исходного файла совместно с номером строки, а также другими способами.
После установки контрольной точки программа запускается с использованием команды run, за которой могут следовать аргументы командной строки, которые должны быть переданы отлаживаемой программе. (GDB удобным образом запоминает за вас аргументы; если нужно снова запустить программу с начала, все что нужно — это напечатать лишь саму команду run, и GDB запустит новую копию с теми же аргументами, как и ранее). Вот короткий сеанс с использованием gawk:
$ gdb gawk /* Запуск GDB для gawk */
GNU gdb 5.3
...
(gdb) break do_print /* Прерывание в do_print */
Breakpoint 1 at 0x805a36a: file builtin.c, line 1504.
(gdb) run 'BEGIN { print "hello, world" }' /* Запуск программы */
Starting program: /home/arnold/Gnu/gawk/gawk-3.1.3/gawk 'BEGIN { print "hello, world" }'
Breakpoint 1, do_print (tree=0x8095290) at builtin.c:1504
1504 struct redirect *rp = NULL; /* Исполнение достигает контрольной точки */
(gdb) list /* Показать исходный код */
1499
1500 void
1501 do_print(register NODE *tree)
1502 {
1503 register NODE **t;
1504 struct redirect *rp = NULL;
1505 register FILE *fp;
1506 int numnodes, i;
1507 NODE *save;
1508 NODE *tval;
По достижении контрольной точки вы проходите программу в пошаговом режиме. Это означает, что GDB разрешает программе исполнять лишь по одному оператору исходного кода за раз. GDB выводит строку, которую собирается выполнить, и выводит приглашение. Чтобы выполнить оператор, используется команда next:
(gdb) next /* Выполнить текущий оператор (строка 1504 выше) */
1510 fp = redirect_to_fp(tree->rnode, &rp); /* GDB выводит следующий оператор */
(gdb) /* Нажмите ENTER для его выполнения и перехода к следующему */
1511 if (fp == NULL)
(gdb) /* снова ENTER */
1519 save = tree = tree->lnode; (gdb) /* И снова */
1520 for (numnodes = 0; tree != NULL; tree = tree->rnode)
Команда step является альтернативной командой для пошагового исполнения. Между next и step есть важное различие, next выполняет следующий оператор. Если этот оператор содержит вызов функции, эта функция вызывается и возвращается до того, как GDB вернет себе управление от работающей программы.
С другой стороны, когда вы используете с содержащим вызов функции оператором step, GDB входит в вызываемую функцию, позволяя вам продолжить пошаговое исполнение (или трассировку) программы. Если оператор не содержит вызов функции, step аналогична next.
ЗАМЕЧАНИЕ. Легко забыть, какая команда была использована, и продолжать нажимать ENTER для выполнения последующих операторов. Если вы используете step, вы случайно можете войти в библиотечную функцию, такую как strlen() или printf(), с которой на самом деле не хотите возиться. В таком случае можно использовать команду finish, которая вызывает исполнение программы до возврата из текущей функции
Вывести содержимое памяти можно с использованием команды print. GDB распознает синтаксис выражений С, что упрощает и делает естественным проверку структур, на которые ссылаются указатели:
(gdb) print *save /* Вывести структуру, на которую указывает save */
$1 = {sub = {nodep = {l = {lptr = 0x8095250, param_name = 0x8095250 "pRtb",
l1 = 134828624}, r = {rptr = 0x0, pptr = 0, preg = 0x0,
hd = 0x0, av = 0x0, r_ent =0}, x = {extra = 0x0, x1 = 0,
param_list = 0x0},
name = 0x0, number = 1, reflags = 0}, val = {

