#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" }' /* Запуск программы */
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 выводит строку, которую собирается выполнить, и выводит приглашение. Чтобы выполнить оператор, используется команда