Книга: Программирование для 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 автоматически открывает соответствующий исходный файл. Не правда ли. проще разобраться в происходящем, глядя на весь файл, а не на одну его строку?

Оглавление книги


Генерация: 0.980. Запросов К БД/Cache: 4 / 0
поделиться
Вверх Вниз