Для исследования данных в вашей программе обычно используется
команда print
(сокращенно p
) или ее синоним
inspect
. Она вычисляет и выводит значение выражения, записанного
на том же языке, что и ваша программа (см. раздел 9. Использование GDB с различными языками программирования).
print выраж
print /f выраж
print
print /f
Команда x
позволяет исследовать данные на более низком уровне. Она
исследует данные в памяти по указанному адресу и выводит их в
указанном формате. См. раздел 8.5 Исследование памяти.
Если вас интересует информация о типах или о том, как объявлены
поля структуры или класса, используйте команду ptype выраж
вместо print
. См. раздел 10. Исследование таблицы символов.
print
и многие другие команды GDB принимают в качестве
параметра выражение и вычисляют его значение. В выражении GDB
допустимо использование любого типа констант, переменных или операторов,
определенных в используемом вами языке программирования, включая
условные выражения, вызовы функций, приведение типов и строковые
постоянные. К сожалению, исключением являются символы, определенные
командами препроцессора #define
.
GDB поддерживает константы-массивы в выражениях, введенных
пользователем. Синтаксис следующий: {элемент,
элемент...}. Например, вы можете использовать команду
print {1, 2, 3}
, чтобы создать в памяти массив,
который будет доступен в программе так же, как выделенный функцией
malloc
.
По причине широкого распространения Си, большинство выражений в примерах этого руководства написаны на Си. См. раздел 9. Использование GDB с различными языками программирования, для информации об использовании выражений в других языках.
В этом разделе мы обсуждаем операторы, которые вы можете использовать в выражениях GDB независимо от используемого вами языка программирования.
Приведения типов поддерживается во всех языках, а не только в Си, так как бывает очень полезно преобразовать число в указатель, чтобы исследовать структуру, расположенную по этому адресу в памяти.
GDB поддерживает эти операторы, в дополнении к следующим, являющимися общими для языков программирования:
@
::
{тип} адрес
Чаще всего в качестве выражения используется имя переменной вашей программы.
Переменные в выражениях трактуются в контексте выбранного кадра стека (см. раздел 6.3 Выбор кадра); они могут быть либо
либо
Это означает, что в функции
foo (a) int a; { bar (a); { int b = test (); bar (b); } }
вы можете исследовать и использовать переменную a
всякий раз,
когда ваша программа выполняется в пределах функции foo
, но
переменную b
можно использовать или исследовать только тогда,
когда ваша программа выполняется внутри блока, в котором она объявлена.
Есть исключение: вы можете ссылаться на переменную или функцию, областью видимости которой является единственный исходный файл, даже если точка текущего выполнения в нем не находится. Допускается существование нескольких переменных или функций с одинаковым именем (в различных исходных файлах). Если это так, обращение к этому имени приводит к непредсказуемым результатам. Если хотите, вы можете указать статическую переменную в конкретной функции или в файле, используя двойное двоеточие:
файл::переменная функция::переменная
Здесь файл или функция -- название контекста для статической
переменной. В первом случае вы можете использовать кавычки, чтобы
GDB рассматривал имя файла как одно слово; например, чтобы вывести
глобальное значение переменной x
, определенной в `f2.c':
(gdb) p 'f2.c'::x
Такое использование `::' крайне редко конфликтует с похожим использованием той же записи в Си++. GDB также поддерживает использование оператора определения области видимости Си++ в выражениях.
Предупреждение: В некоторых случаях, в определенной точке функции (сразу после входа в новую область видимости и непосредственно перед выходом из нее) может показаться, что локальная переменная имеет неверное значение.
Вы можете столкнуться с этой проблемой при пошаговом выполнении по одной машинной инструкции. Она возникает из-за того, что на большинстве машин процедура установки кадра стека (включая определения локальных переменных) занимает более одной инструкции; если вы производите пошаговое выполнение по одной машинной инструкции, может показаться, что переменная имеет неверное значение, пока кадр стека не будет полностью построен. При выходе, для уничтожения кадра стека обычно также требуется более одной инструкции; после начала пошагового выполнения этой группы инструкций определения локальных переменных могут пропасть.
Это также может случиться, когда компилятор делает значительную оптимизацию. Чтобы быть уверенным, что вы всегда видите точные значения, отключите всю оптимизацию при компиляции.
Другой возможный эффект оптимизации компилятора заключается в уничтожении неиспользуемых переменных или в присвоении переменных регистрам (а не адресам памяти). В зависимости от поддержки таких ситуаций, предоставляемой форматом отладочной информации, который использует компилятор, GDB может не вывести значения таких локальных переменных. Если это происходит, GDB выведет сообщение, подобное этому:
No symbol "foo" in current context.
Для решения таких проблем или перекомпилируйте программу без оптимизации, или используйте другой формат отладочной информации, если компилятор поддерживает несколько таких форматов. Например GCC, компилятор GNU Си/Си++, обычно поддерживает ключ `-gstabs'. `-gstabs' создает отладочную информацию в формате, являющимся развитием таких форматов, как COFF. У вас может быть возможность использовать DWARF2 (`-gdwarf-2'), который тоже является эффективной формой представления отладочной информации. Смотрите раздел `Ключи для отладки вашей программы или GNU CC' в Использование GNU CC, для дополнительной информации.
Часто бывает полезным вывести несколько объектов одного типа, расположенных в памяти последовательно; часть массива или динамический массив, для которого в программе существует только указатель.
Вы можете это сделать, обращаясь к непрерывному участку памяти как к искусственному массиву, используя бинарный оператор `@'. Левым операндом для `@' должен быть первый элемент желаемого массива, и он должен быть индивидуальным объектом. Правым операндом должна быть длина массива. Результатом операции будет массив, все элементы которого имеют тот же тип, что и левый аргумент. Первым элементом массива является левый аргумент; второй элемент формируется из байтов памяти, непосредственно следующих за байтами, содержащими первый элемент, и так далее. Например, если в программе есть строка
int *array = (int *) malloc (len * sizeof (int));
то вы можете вывести содержимое array
с помощью
p *array@len
Левый операнд операции `@' должен находиться в памяти. Значения массивов, полученных операцией `@', при индексации ведут себя точно так же, как и другие массивы, и приводятся к указателям при использовании в выражениях. Искусственные массивы чаще всего появляются в выражениях через историю значений (см. раздел 8.8 История значений), после вывода одного из них.
Другой способ создания искусственного массива -- использование приведения типов. Оно заново интерпретирует значение так, как если бы оно было массивом. Значение не обязано находиться в памяти.
(gdb) p/x (short[2])0x12345678 $1 = {0x1234, 0x5678}
Если вы опускаете длину массива (как в `(тип[])значение'), GDB для удобства вычисляет его размер для заполнения значениями (как `sizeof(значение)/sizeof(тип)':
(gdb) p/x (short[])0x12345678 $2 = {0x1234, 0x5678}
Иногда механизма искусственных массивов бывает недостаточно;
в сравнительно сложных структурах данных интересующие нас элементы могут
не быть смежными -- например, если вас интересуют значения указателей в
массиве. Одно из удачных решений этой проблемы -- использование
вспомогательной переменной (см. раздел 8.9 Вспомогательные переменные) в качестве счетчика в выражении, выводящем
первое интересующее нас значение, а затем повторять это выражение
нажатием RET. Предположим, например, у вас есть массив
dtab
указателей на структуры, и вас интересуют значения полей
fv
в каждой структуре. Ниже приведен пример ваших возможных действий:
set $i = 0 p dtab[$i++]->fv RET RET ...
По умолчанию, GDB печатает значение в соответствии с его типом. Это не всегда отвечает вашему желанию. Например, вы можете захотеть вывести число в шестнадцатеричной записи или указатель в десятичной. Или вы можете захотеть просмотреть данные по некоторому адресу в памяти в виде строки знаков или в виде инструкций. Для этого при выводе значения задайте формат вывода.
Простейшим применением форматов вывода является форматирование вывода
уже вычисленного выражения. Чтобы сделать это, начните параметры
команды print
с косой черты и символа формата. Поддерживаются
следующие символы формата:
x
d
u
o
t
a
(gdb) p/a 0x54320 $3 = 0x54320 <_initialize_vx+396>
c
f
Например, чтобы вывести счетчик программы в шестнадцатеричном виде (см. раздел 8.10 Регистры), введите
p/x $pc
Обратите внимание, что перед косой чертой не требуется пробела, потому что имена команд в GDB не могут содержать косую черту.
Чтобы вывести последнее значение из истории значений в другом
формате, вы можете воспользоваться командой print
лишь с указанием
формата и без выражения. Например, `p/x' выведет последнее
значение в шестнадцатеричной форме.
Вы можете использовать команду x
(от слова "examine") для
исследования памяти в одном из нескольких форматов, независимо от типов
данных вашей программы.
x/nfu адрес
x адрес
x
x
.
n, f и u -- необязательные параметры, определяющие, сколько памяти отобразить и в каком формате; адрес -- это выражение, задающее адрес, с которого вы хотите начать отображение памяти. Если вы используете значения по умолчанию для nfu, то вам не нужно вводить косую черту `/'. Некоторые команды устанавливают удобные значения по умолчанию для адреса.
print
, `s' (строка, оканчивающаяся нулем), или `i'
(машинная инструкция). Первоначально, значением по умолчанию
установлено `x' (шестнадцатеричная форма). Значение по умолчанию
изменяется каждый раз, когда вы используете либо x
, либо
print
.
b
h
w
g
x
,
этот размер становится размером по умолчанию при последующем использовании
x
. (Для форматов `s' и `i' размер единицы измерений
игнорируется и обычно не пишется.)
info breakpoints
(в адрес последней выведенной точки останова), info line
(в
начальный адрес строки) и print
(если вы используете эту
команду для отображения значения из памяти).
Например, `x/3uh 0x54320' -- запрос на вывод трех полуслов
(h
) памяти в формате беззнаковых десятичных целых (`u'),
начиная с адреса 0x54320
. `x/4xw $sp' выводит четыре слова
(`w') памяти, расположенные над указателем стека (здесь `$sp';
см. раздел 8.10 Регистры), в шестнадцатеричном виде (`x').
Так как все буквы, обозначающие размер единиц измерения, отличаются от букв, определяющих форматы вывода, вы не должны запоминать, формат или размер единиц измерений указывается раньше; это можно делать в любом порядке. Спецификации вывода `4xw' и `4wx' означают в точности одно и то же. (Однако, число n должно быть первым; `wx4' не сработает.)
Хотя размер единицы измерения u игнорируется для форматов `s'
и `i', вы, тем не менее, можете воспользоваться счетчиком повторений
n; например, `3i' указывает, что вы хотите вывести три
машинные инструкции, включая любые операнды. Команда disassemble
предоставляет альтернативный способ исследования машинных инструкций;
смотрите раздел 7.4 Исходный текст и машинный код.
Все значения по умолчанию для аргументов команды x
разработаны
таким образом, чтобы облегчить продолжение сканирования памяти с
минимальными конкретизациями при очередном использовании x
. Например,
после того, как вы просмотрели три машинные инструкции с помощью
`x/3i адрес', вы можете просмотреть следующие семь, используя
просто `x/7'. Если вы повторяете команду x
нажатием
RET, число повторений n остается прежним; другие параметры
берутся по умолчанию, как для последовательных использований x
.
Адреса и их содержимое, выводимые командой x
, не сохраняются в
истории значений, так как они мешали бы.
Вместо этого,
GDB делает их доступными для последующего использования в
выражениях как значения вспомогательных переменных $_
и
$__
. После команды x
, последний исследованный адрес
доступен для использования в выражениях во вспомогательной переменной
$_
. Содержимое этого адреса, исследованное только что, доступно во
вспомогательной переменной $__
.
Если команде x
задан счетчик повторений, адрес и его содержимое
сохраняются из последнего выведенного элемента памяти; это не то же
самое, что последний выведенный адрес, если в последней строке вывода
были отображены несколько элементов.
Если вам необходимо часто выводить значение какого-либо выражения (чтобы увидеть, как оно меняется), вы можете добавить его в список автоматического отображения, чтобы GDB выводил его значение каждый раз при остановке вашей программы. Каждому выражению, добавленному в список, присваивается идентификационный номер; чтобы удалить выражение из списка, вы указываете этот номер. Автоматическое отображение выглядит следующим образом:
2: foo = 38 3: bar[5] = (struct hack *) 0x3804
Это отображение показывает номера элементов, выражения и их текущие
значения. Как и при отображении, запрашиваемом вручную с помощью x
или print
, вы можете указать предпочитаемый формат вывода;
фактически, display
выбирает между print
и x
в зависимости от того, насколько детально задана
спецификация формата: x
используется, если вы указываете размер
элемента или один из двух форматов (`i' и s
), которые
поддерживаются только x
; в остальных случаях применяется print
.
display выраж
display
не повторяется, если вы повторно нажимаете
RET после ее использования.
display/формат выраж
display/формат адрес
Например, команда `display/i $pc' может быть полезна, чтобы при каждой остановке видеть машинную инструкцию, которая будет выполняться следующей (`$pc' -- это общее обозначение счетчика программы; см. раздел 8.10 Регистры).
undisplay номера...
delete display номера...
undisplay
не повторяется при последующем нажатии RET.
(Иначе вы сразу получили бы сообщение об ошибке `No display number
...'.)
disable display номера...
enable display номера...
display
info display
Если отображаемое выражение обращается к локальным переменным, оно
не имеет смысла вне того лексического контекста, для которого оно
устанавливалось. Такое выражения отключается, как только выполнение
входит в контекст, где одна из его переменных становится неопределенной.
Например, если вы дадите команду display last_char
, находясь
внутри функции с аргументом last_char
, GDB будет
отображать этот аргумент, пока программа останавливается внутри этой
функции. Как только она остановится где-то еще -- где нет переменной
last_char
-- отображение будет отключено автоматически. Вы
можете снова включить его при следующей остановке программы там, где
last_char
будет вновь иметь смысл.
GDB предоставляет следующие способы управления выводом массивов, структур и символов.
Данные параметры полезны при отладке программ на любом языке:
set print address
set print address on
on
. Например, вот как выглядит отображение кадра
стека с установленным set print address on
:
(gdb) f #0 set_quotes (lq=0x34c78 "<<", rq=0x34c88 ">>") at input.c:530 530 if (lquote != def_lquote)
set print address off
set print address
off
:
(gdb) set print addr off (gdb) f #0 set_quotes (lq="<<", rq=">>") at input.c:530 530 if (lquote != def_lquote)Вы можете использовать `set print address off', чтобы удалить все машинно-зависимые отображения из интерфейса GDB. Например, с
print address off
, вы должны получить одинаковый текст для
цепочек вызовов на всех машинах, независимо от того, включают они
указатели в качестве аргументов или нет.
show print address
При выводе адреса в символьной форме, GDB обычно выводит ближайший
предшествующий символ плюс смещение. Если этот символ не определяет
адрес однозначно (например, это имя, областью действия которого является
один исходный файл), вам может потребоваться дать пояснения. Один из
способов это сделать -- с помощью info line
; например,
`info line *0x4537'. Альтернативный способ заключается в том, чтобы
GDB выводил имя исходного файла и номер строки при выводе
символьного адреса:
set print symbol-filename on
set print symbol-filename off
show print symbol-filename
Другая ситуация, в которой полезно показывать имена файлов и номера строк, возникает при дисассемблировании кода; GDB показывает вам номер строки и исходный файл, которые соответствуют каждой инструкции.
Вы также можете захотеть видеть символьную форму только в том случае, если выводимый адрес достаточно близок к ближайшему предшествующему символу:
set print max-symbolic-offset макс-смещение
show print max-symbolic-offset
Если у вас есть указатель, и вы не знаете, на что он указывает,
попробуйте `set print symbol-filename on'. Затем вы можете определить
название и исходный файл переменной, на которую он указывает, используя
`p/a указатель'. Это интерпретирует адрес в символьной
форме. Например, здесь GDB показывает, что переменная
ptt
указывает на другую переменную t
, определенную в файле
`hi2.c':
(gdb) set print symbol-filename on (gdb) p/a ptt $4 = 0xe008 <t in hi2.c>
Предупреждение: Для указателей, ссылающихся на локальные переменные, `p/a' не показывает символьное имя и имя файла, которому принадлежит объект ссылки, даже если установлен соответствующий параметр
set print
.
Другие установки управляют выводом объектов различных типов:
set print array
set print array on
set print array off
show print array
set print elements число-элементов
set print
elements
число элементов. Это ограничение также действует при
отображении строк. Когда GDB стартует, этот предел принимается
равным 200. Установка число-элементов в ноль означает, что вывод
не ограничен.
show print elements
set print null-stop
set print pretty on
$1 = { next = 0x0, flags = { sweet = 1, sour = 1 }, meat = 0x54 "Pork" }
set print pretty off
$1 = {next = 0x0, flags = {sweet = 1, sour = 1}, \ meat = 0x54 "Pork"}Этот формат устанавливается по умолчанию.
show print pretty
set print sevenbit-strings on
\
nnn.
Эта установка очень удобна, если вы работаете на английском (ASCII)
и используете старший бит знаков как маркер или "мета"-бит.
set print sevenbit-strings off
show print sevenbit-strings
set print union on
set print union off
show print union
typedef enum {Tree, Bug} Species; typedef enum {Big_tree, Acorn, Seedling} Tree_forms; typedef enum {Caterpillar, Cocoon, Butterfly} Bug_forms; struct thing { Species it; union { Tree_forms tree; Bug_forms bug; } form; }; struct thing foo = {Tree, {Acorn}};с установленным
set print union on
, команда `p foo' выведет
$1 = {it = Tree, form = {tree = Acorn, bug = Cocoon}}а с установленным
set print union off
, эта же команда выведет
$1 = {it = Tree, form = {...}}
Следующие установки представляют интерес при отладке программ на Си++:
set print demangle
set print demangle on
show print demangle
set print asm-demangle
set print asm-demangle on
show print asm-demangle
set demangle-style стиль
auto
gnu
g++
). Устанавливается по умолчанию.
hp
aCC
).
lucid
lcc
).
arm
cfront
.
Чтобы реализовать это, GDB требует дальнейших усовершенствований.
show demangle-style
set print object
set print object on
set print object off
show print object
set print static-members
set print static-members on
set print static-members off
show print static-members
set print vtbl
set print vtbl on
vtbl
не работают для программ,
скомпилированных компилятором HP ANSI Си++ (aCC
).)
set print vtbl off
show print vtbl
Значения, выведенные командой print
, сохраняются в истории
значений GDB. Это позволяет вам обращаться к ним в других
выражениях. Значения сохраняются, пока таблица символов не будет заново
считана или уничтожена (например, командами file
или
symbol-file
). При изменении таблицы символов история значений
уничтожается, так как значения могут содержать указатели на типы,
определенные в таблице символов.
Выведенным значениям присваиваются номера в истории, по которым вы
можете на них ссылаться. Эти номера являются последовательными целыми
числами, начинающимися с единицы. Команда print
показывает номер в истории, присвоенный значению, выводя перед ним
`$номер = ', где номер -- это номер в истории.
Для обращения к какому-либо предшествующему значению, используйте
`$', за которым следует номер в истории. Способ, которым
print
маркирует вывод, продуман так, чтобы напоминать вам об
этом. Просто $
ссылается на самое последнее значение в истории,
а $$
-- на предпоследнее. $$n
ссылается на n-е
с конца значение; $$2
-- значение, находящееся перед $$
,
$$1
эквивалентно $$
, а $$0
эквивалентно $
.
Предположим, например, вы только что вывели указатель на структуру и хотите посмотреть ее содержимое. Для этого достаточно ввести
p *$
Если у вас есть цепочка структур, где компонента next
указывает на
следующую, вы можете вывести содержимое следующей структуры так:
p *$.next
Вы можете выводить последовательные звенья в цепочке повторяя эту команду. Это можно сделать простым нажатием RET.
Обратите внимание на то, что в историю записываются значения, а не
выражения. Если значение x
равно 4, и вы наберете:
print x set x=5
то значение, записанное в историю значений командой print
, будет
по-прежнему равно 4, хотя значение x
изменилось.
show values
show values
не изменяет историю.
show values n
show values +
show values +
не выводит ничего.
Нажатие RET для повтора show values n
действует точно
так же, как `show values +'.
GDB предоставляет вспомогательные переменные, которые вы можете в нем использовать, чтобы сохранить значение и обратиться к нему позже. Эти переменные существуют только в GDB; они не являются частью вашей программы, и установка вспомогательной переменной не оказывает непосредственного влияния на ее дальшейшее выполнение. Поэтому вы можете пользоваться ими совершенно свободно.
Имена вспомогательных переменных начинаются с `$'. Любое имя с приставкой `$' может использоваться для вспомогательной переменной, если только оно не является предопределенным машинно-зависимым именем регистра, (см. раздел 8.10 Регистры). (Ссылки на историю значений, напротив, есть числа, которым предшествует `$'. См. раздел 8.8 История значений.)
Вы можете сохранить значение во вспомогательной переменной с помощью выражения присваивания, как если бы вы устанавливали переменную в вашей программе. Например:
set $foo = *object_ptr
сохранит в $foo
значение объекта, на который указывает
object_ptr
.
Первое использование вспомогательной переменной создает ее, но
значением переменной будет void
, пока вы не присвоите ей новое.
С помощью другого присваивания вы можете в любое время
изменить значение.
Вспомогательные переменные не имеют фиксированного типа. Вы можете присваивать вспомогательной переменной значение любого типа, включая структуры и массивы, даже если у этой переменной уже было значение другого типа. Будучи использованной в выражении, вспомогательная переменная имеет тип своего текущего значения.
show convenience
show conv
.
Один из способов использования вспомогательных переменных -- в качестве увеличивающегося счетчика или продвигающегося указателя. Например, чтобы напечатать поле из последовательных элементов массива структур:
set $i = 0 print bar[$i++]->contents
Повторяйте эту команду нажатием RET.
Некоторые вспомогательные переменные создаются GDB автоматически, и им присваиваются значения, которые вероятно могут оказаться полезными.
$_
$_
устанавливается автоматически командой x
в
последний исследованный адрес (см. раздел 8.5 Исследование памяти).
Другие команды, которые устанавливают адрес по умолчанию для
исследования командой x
, также присваивают $_
упомянутый
адрес; эти команды включают info line
и info breakpoint
.
Переменная $_
имеет тип void *
, если только она не
установлена командой x
; в этом случае она является указателем на
тип переменной $__
.
$__
$__
устанавливается автоматически командой x
в
значение, находящееся по последнему исследованному адресу. Ее тип
выбирается соответствующим формату, в котором это значение было
выведено.
$_exitcode
$_exitcode
автоматически присваивается код завершения,
когда отлаживаемая программа завершается.
В системах HP-UX, если вы ссылаетесь на функцию или переменную, чье имя начинается со знака доллара, GDB сначала производит поиск пользовательского или системного имени, перед поиском вспомогательной переменной.
В выражениях, вы можете обращаться к содержимому машинных регистров,
обозначая их как переменные с именами, начинающимся с `$'. Имена
регистров различаются от машины к машине; для вывода имен регистров,
используемых на вашей машине, воспользуйтесь командой info registers
.
info registers
info all-registers
info registers имя-рег ...
GDB распознает четыре "стандартных" имени регистров, которые
доступны (в выражениях) на большинстве машин -- если только они не
конфликтуют с каноническим для архитектуры обозначением регистров.
Названия регистров $pc
и $sp
используются для регистра
счетчика программы и указателя вершины стека. $fp
используется
как имя регистра, содержащего указатель на текущий кадр стека, а
$ps
-- как имя регистра, содержащего состояние процессора.
Например, вы можете вывести счетчик программы в шестнадцатеричной записи
с помощью
p/x $pc
или вывести следующую исполняемую инструкцию, используя
x/i $pc
или увеличить указатель вершины стека на четыре(12) с помощью
set $sp += 4
Когда возможно, эти четыре стандартных имени регистров доступны на вашей
машине, даже если она имеет другую каноническую мнемонику,
если не возникает конфликта. Команда info registers
показывает канонические имена. В SPARC, например, info registers
отображает регистр состояния процессора как $psr
, но вы также можете
называть его $ps
; а на машинах, базирующихся на платформе x86,
$ps
является синонимом для регистра EFLAGS.
Когда регистр изучается таким образом, GDB всегда рассматривает содержимое обычного регистра как целое. Некоторые машины имеют специальные регистры, которые могут содержать только значение с плавающей точкой; их значения трактуются как величины с плавающей точкой. Не существует способа сослаться на содержимое обычного регистра как на величину с плавающей точкой (хотя вы можете распечатать его значение командой print как величину с плавающей точкой, используя `print/f $имя-рег').
Некоторые регистры имеют различные "необработанные" и "виртуальные"
форматы данных. Это означает, что формат данных, в котором
операционная система сохраняет содержимое регистра, не совпадает с
тем, который обычно воспринимается вашей программой. Например, регистры
сопроцессора с плавающей точкой 68881 всегда сохраняются в
"расширенном" (необработанном) формате, но все программы на Си работают с
"двойным" (виртуальным) форматом. В подобных случаях, GDB обычно
работает только с виртуальным форматом (форматом, имеющим смысл в вашей
программе), но команда info registers
выводит данные в обоих
форматах.
Обычно значения регистров относятся к выбранному кадру стека (см. раздел 6.3 Выбор кадра). Это значит, что вы получаете значение, которое содержалось бы в регистре, если бы произошел выход из всех внутренних кадров стека, и их сохраненные регистры были бы восстановлены. Для того, чтобы увидеть истинное содержимое аппаратных регистров, вы должны выбрать самый внутренний кадр (с помощью `frame 0').
Однако, GDB, исходя из машинного кода, сгенерированного вашим компилятором, должен установить, где сохранены регистры. Если некоторые регистры не сохранены, или если GDB не в состоянии найти сохраненные регистры, выбранный кадр стека не имеет значения.
В зависимости от конфигурации, GDB может выдать вам больше информации о состоянии аппаратных средств поддержки вычислений с плавающей точкой.
info float