Книга: Программирование для Linux. Профессиональный подход
1.4.2. Запуск отладчика
1.4.2. Запуск отладчика
Отладчик gdb
запускается следующим образом:
% gdb reciprocal
После запуска появится строка приглашения такого вида:
(gdb)
В первую очередь необходимо запустить программу под отладчиком. Для этого введите команду run
и требуемые аргументы. Попробуем вызвать программу без аргументов:
(gdb) run
Starting program: reciprocal
Program received signal SIGSEGV, Segmentation fault.
__strtol_internal (nptr=0x0, endptr=0x0, base=10, group=0)
at strtol.c:287
287 strtol.c: No such file or directory.
(gdb)
Проблема заключается в том, что в функции main()
не предусмотрены средства контроля ошибок. Программа ожидает наличия аргумента, а в данном случае его нет. Получение сигнала SIGSEGV
означает крах программы. Отладчик определяет, что причина краха находится в функции __strtol_internal()
. Эта функция является частью стандартной библиотеки, но ее исходный файл отсутствует. Вот почему появляется сообщение "No such file or directory". С помощью команды where
можно просмотреть содержимое стека:
(gdb) where
#0 __strtol_internal (nptr=0x0, endptr=0x0, base=10, group=0)
at strtol.c:287
#1 0x40096fb6 in atoi (nptr=0x0) at ../stdlib/stdlib.h:251
#2 0x804863e in main (argc=1, argv=0xbffff5e4) at main.c:8
Как нетрудно заметить, функция main()
вызвала функцию atoi()
, передав ей нулевой указатель, что и стало причиной ошибки.
С помощью команды up
можно подняться но стеку на два уровня, дойдя до функции main()
:
(gdb) up 2
#2 0x804863е in main (argc=1, argv=0xbffff5e4) at main.c:8
8 i = atoi(argv[1]);
Заметьте, что отладчик нашел исходный файл main.c
и отобразил строку, где располагается ошибочный вызов функции. Узнать значение нужной локальной переменной позволяет команда print
:
(gdb) print argv[1]
$2 = 0x0
Это подтверждает нашу догадку о том, что причина ошибки — передача функции atoi()
указателя NULL
.
Установка контрольной точки осуществляется посредством команды break
:
(gdb) break main
Breakpoint 1 at 0x804862e: file main.c, line 8.
В данном случае контрольная точка размещена в первой строке функции main()
. Давайте теперь заново запустим программу, передав ей один аргумент:
(gdb) run 7
Starting program: reciprocal 7
Breakpoint 1, main (argc=2, argv=0xbffff5e4) at main.c:8
8 i = atoi(argv[1]);
Как видите, отладчик остановился на контрольной точке- Перейти на следующую строку можно с помощью команды next
:
(gdb) next
9 printf("The reciprocal of %d is %gn", i,
reciprocal(i));
Если требуется узнать, что происходит внутри функции reciprocal()
, воспользуйтесь командой step
:
(gdb) step
reciprocal (i=7) at reciprocal.cpp:6
6 assert(i != 0);
Иногда удобнее запускать отладчик gdb
непосредственно из редактора Emacs, а не из командной строки. Для этого следует ввести в редакторе команду M-x gdb
. Когда отладчик останавливается в контрольной точке, редактор Emacs автоматически открывает соответствующий исходный файл. Не правда ли. проще разобраться в происходящем, глядя на весь файл, а не на одну его строку?
- Активизация отладчика
- Команды отладчика
- Запуск gdb
- Запуск InterBase-сервера
- Практическая работа 53. Запуск Access. Работа с объектами базы данных
- Одновременный запуск нескольких копий сервера (multi-instancing)
- Запуск Access. Открытие учебной базы данных Борей
- Способы «запуска» слухов
- Запуск сценариев на удаленных машинах. Контроль за ходом выполнения таких сценариев
- Как ускорить запуск программ?
- Как сделать, чтобы при запуске Windows автоматически открывались папки, с которыми я работал в прошлый раз?
- Могу ли я изменить или отключить звуки, которые проигрываются при запуске Windows, щелчке кнопкой мыши на папке и т. д.?