Когда ваша программа остановилась, первое, что вам нужно знать -- где она остановилась, и как она туда попала.
Каждый раз, когда ваша программа производит вызов функции, о нем создается определенная информация. Она включает положение вызова в вашей программе, параметры вызова и локальные переменные вызываемой функции. Информация сохраняется в блоке данных, называемом кадром стека. Кадры стека размещаются в области памяти, называемой стеком вызовов.
Команды GDB для исследования стека позволяют вам увидеть всю эту информацию при остановке вашей программы.
Один из кадров стека является выбранным, и многие команды GDB неявно относятся к нему. В частности, когда вы запрашиваете у GDB значение переменной вашей программы, это значение находится в выбранном кадре. Для выбора интересующего вас кадра существуют специальные команды GDB. См. раздел 6.3 Выбор кадра.
Когда ваша программа останавливается, GDB автоматически
выбирает текущий выполняющийся кадр и выдает его краткое описание,
аналогично команде frame
(см. раздел 6.4 Информация о кадре стека).
Cтек вызовов разделен на непрерывные участки, называемые кадрами стека, или кадрами для краткости; каждый кадр является данными, связанными с одним вызовом одной функции. Кадр содержит аргументы, переданные функции, ее локальные переменные и адрес, с которого она выполняется.
Когда ваша программа стартует, стек содержит только один кадр -- для
функции main
. Он называется начальным или внешним
кадром. Каждый
раз при вызове функции создается новый кадр. При каждом выходе
из функции кадр вызова этой функции уничтожается. Если функция
является рекурсивной, для нее может существовать множество кадров. Кадр
для функции, исполняемой в данный момент, называется внутренним
кадром. Это кадр, созданный самым последним из всех существующих кадров стека.
Внутри вашей программы кадры стека идентифицируются своим адресом. Кадр стека состоит из множества байт, каждый из которых имеет свой собственный адрес; каждый тип компьютеров имеет свой способ для выбора одного байта, чей адрес служит адресом кадра. Обычно, пока выполнение происходит в данном кадре, этот адрес содержится в регистре, называемом регистром указателя кадра.
GDB присваивает номера всем существующим кадрам стека, начиная с нуля для внутреннего кадра, единицу -- вызвавшему его кадру, и так далее. В действительности, эти номера не существуют в вашей программе; они назначаются GDB, чтобы предоставить вам способ различать кадры стека в командах GDB.
Некоторые компиляторы позволяют компилировать функции так, чтобы они выполнялись без создания кадров стека. (Например, ключ gcc `-fomit-frame-pointer' создает функции без кадра.) Это иногда делается с часто используемыми библиотечными функциями, чтобы сэкономить время, требуемое для установки кадра. GDB имеет ограниченные возможности для обработки таких вызовов. Если вызов внутренней функции происходит без создания кадра стека, GDB, тем не менее, описывает его так, как если бы он имел отдельный кадр, который имеет, как обычно, номер 0, позволяя корректно трассировать цепочку вызовов функций. Однако, GDB не имеет средств для работы с функциями без кадра в другом месте стека.
frame арг
frame
позволяет вам перемещаться от одного кадра стека
к другому и распечатывать выбранный вами кадр. Арг может быть либо
адресом кадра, либо его номером. Без аргумента, frame
выводит текущий кадр стека.
select-frame
select-frame
позволяет вам перемещаться от одного кадра
стека к другому без его распечатки. Это "тихая" версия frame
.
Цепочка вызовов предоставляет собой информацию о том, как ваша программа оказалась там, где она есть. Она отображает по одной строке для каждого кадра, начиная с текущего выполняющегося кадра (кадра 0), за которым следует кадр, из которого он был вызван (кадр 1), и далее вверх по стеку.
backtrace
bt
backtrace n
bt n
backtrace -n
bt -n
where
и info stack
(сокращенно info
s
) -- дополнительные синонимы для backtrace
.
Каждая строка в цепочке вызовов показывает номер кадра и имя функции.
Счетчик команд также показывается, если только вы не используете
set print address off
. Цепочка вызовов также показывает имя
исходного файла, номер строки и аргументы функции. Значение счетчика
команд опускается, если он указывает на начало кода для данной строки.
Ниже приведен пример цепочки вызовов. Она была получена командой `bt 3', так что она показывает три внутренних кадра.
#0 m4_traceon (obs=0x24eb0, argc=1, argv=0x2b8c8) at builtin.c:993 #1 0x6e38 in expand_macro (sym=0x2b600) at macro.c:242 #2 0x6840 in expand_token (obs=0x0, t=177664, td=0xf7fffb08) at macro.c:71 (More stack frames follow...)
Информация о нулевом кадре не начинается со значения счетчика команд,
что указывает на то, что ваша программа остановилась в начале кода для
строки 993
файла builtin.c
.
Большинство команд для исследования стека и других данных в вашей программе применяются выбранному в данный момент кадру. Здесь приведены команды для выбора кадра стека; все они завершаются выводом краткого описания выбранного кадра стека.
frame n
f n
main
.
frame адрес
f адрес
frame
для выбора произвольного
кадра необходимо указать два адреса: указатель кадра и указатель вершины
стека.
В архитектурах MIPS и Alpha требуется два адреса: указатель
вершины стека и указатель команд.
В архитектуре 29k требуется три адреса: указатель вершины
стека регистров, указатель команд и указатель вершины стека памяти.
up n
down n
down
как do
.
Все эти команды заканчиваются выводом двух строк, описывающих кадр. Первая строка показывает номер кадра, имя функции, аргументы, имя исходного файла и номер выполняемой строки в этом кадре. Вторая строка показывает содержимое этой строки исходного текста.
Например:
(gdb) up #1 0x22f0 in main (argc=1, argv=0xf7fffbf4, env=0xf7fffbfc) at env.c:10 10 read_input_file (argv[i]);
После такого вывода, команда list
без аргументов выводит десять
строк, расположенных вокруг точки выполнения в кадре.
См. раздел 7.1 Вывод строк исходного текста.
up-silently n
down-silently n
up
и down
соответственно,
отличаясь от них тем, что делают свою работу "тихо", не отображая новый
кадр. Они предназначены для использования в основном в
командных сценариях GDB, где вывод может быть ненужным и
отвлекающим.
Существуют несколько других команд для вывода информации о выбранном кадре стека.
frame
f
f
. С аргументом, эта команда
используется для выбора кадра стека.
См. раздел 6.3 Выбор кадра.
info frame
info f
info frame адрес
info f адрес
frame
(для некоторых архитектур
не один, а несколько).
См. раздел 6.3 Выбор кадра.
info args
info locals
info catch
up
, down
или
frame
); затем наберите info catch
.
См. раздел 5.1.3 Установка точек перехвата.