Отладка с помощью GDB - 8. Исследование данных

[Содержание]   [Назад]   [Пред]   [Вверх]   [След]   [Вперед]  


8. Исследование данных

Для исследования данных в вашей программе обычно используется команда print (сокращенно p) или ее синоним inspect. Она вычисляет и выводит значение выражения, записанного на том же языке, что и ваша программа (см. раздел 9. Использование GDB с различными языками программирования).

print выраж
print /f выраж
выраж является выражением (на исходном языке). По умолчанию, значение выраж выводится в формате, соответствующем его типу данных; вы можете выбрать другой формат, указав `/f', где f---буква, определяющая формат; смотрите раздел 8.4 Форматы вывода.
print
print /f
Если вы опустите выраж, GDB отображает последнее значение снова (из истории значений; см. раздел 8.8 История значений). Это предоставляет вам удобный способ изучить то же самое значение в другом формате.

Команда x позволяет исследовать данные на более низком уровне. Она исследует данные в памяти по указанному адресу и выводит их в указанном формате. См. раздел 8.5 Исследование памяти.

Если вас интересует информация о типах или о том, как объявлены поля структуры или класса, используйте команду ptype выраж вместо print. См. раздел 10. Исследование таблицы символов.

8.1 Выражения

print и многие другие команды GDB допускают в качестве параметра выражение и вычисляют его значение. В выражении GDB допустимо использование любого типа констант, переменных или операторов, определенных в используемом вами языке программирования, включая условные выражения, вызовы функций, приведение типов и строковые постоянные. К сожалению, исключением являются символы, определенные командами препроцессора #define.

GDB поддерживает константы-массивы в выражениях, введенных пользователем. Синтаксис следующий: {элемент, элемент...}. Например, вы можете использовать команду print {1, 2, 3}, чтобы создать в памяти массив, который будет доступен в программе так же, как выделенный функцией malloc.

По причине широкого распространения Си, большинство выражений в примерах этого руководства написаны на Си. См. раздел 9. Использование GDB с различными языками программирования, для информации об использовании выражений в других языках.

В этом разделе мы обсуждаем операторы, которые вы можете использовать в выражениях GDB независимо от используемого вами языка программирования.

Приведения типов поддерживается во всех языках, а не только в Си, так как бывает очень полезно преобразовать число в указатель, чтобы исследовать структуру, расположенную по этому адресу в памяти.

GDB поддерживает эти операторы, в дополнении к следующим, являющимися общими для языков программирования:

@
`@' является бинарным оператором, позволяющим рассматривать области памяти как массивы. См. раздел 8.3 Искусственные массивы, для дополнительной информации.
::
`::' позволяет вам указывать переменную в терминах файла или функции, где она определена. См. раздел 8.2 Переменные программы.
{тип} адрес
Ссылается на объект типа тип, хранящийся в памяти по адресу адрес. Адрес может быть любым выражением, значением которого является целое число или указатель (но вокруг бинарных операторов, также как и вокруг оператора приведения типа, требуются скобки). Эта конструкция допустима, независимо от того, какого типа данные предположительно расположены по адресу.

8.2 Переменные программы

Чаще всего в качестве выражения используется имя переменной вашей программы.

Переменные в выражениях трактуются в контексте выбранного кадра стека (см. раздел 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. У вас может быть возможность использовать DWARF-2 (`-gdwarf-2'), который тоже является эффективной формой представления отладочной информации. Смотрите раздел `Опции для отладки вашей программы или GNU CC' в Использование GNU CC, для дополнительной информации.

8.3 Искусственные массивы

Часто бывает полезным вывести несколько объектов одного типа, расположенных в памяти последовательно; часть массива или динамический массив, для которого в программе существует только указатель.

Вы можете это сделать, обращаясь к непрерывному участку памяти как к искусственному массиву, используя бинарный оператор `@'. Левым операндом для `@' должен быть первый элемент желаемого массива, и он должен быть индивидуальным объектом. Правым операндом должна быть длина массива. Результатом операции будет массив, все элементы которого имеют тот же тип, что и левый аргумент. Первым элементом массива является левый аргумент; второй элемент формируется из байтов памяти, непосредственно следующих за байтами, содержащими первый элемент, и так далее. Например, если в программе есть строка

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
...

8.4 Форматы вывода

По умолчанию, GDB печатает значение в соответствии с его типом. Это не всегда отвечает вашему желанию. Например, вы можете захотеть вывести число в шестнадцатеричной записи, или указатель в десятичной. Или вы можете захотеть просмотреть данные по некоторому адресу в памяти в виде строки символов или в виде инструкций. Для этого, при выводе значения укажите формат вывода.

Простейшим применением форматов вывода является форматирование вывода уже вычисленного выражения. Это осуществляется путем начала параметров команды print с косой черты и символа формата. Поддерживаются следующие символы формата:

x
Рассматривать биты значения как целое, и вывести целое в шестнадцатеричном виде.
d
Вывести как десятичное целое со знаком.
u
Вывести как десятичное целое без знака.
o
Вывести как восьмеричное целое.
t
Вывести как целое в двоичном виде. Буква `t' означает "two". (11)
a
Вывести в виде адреса, как абсолютного в шестнадцатеричной записи, так и в виде смещения от ближайшего предшествующего символа. Вы можете использовать этот формат для того, чтобы определить, где (в какой функции) расположен какой-либо неизвестный адрес:
(gdb) p/a 0x54320
$3 = 0x54320 <_initialize_vx+396>
c
Рассматривать как целое и вывести в виде строковой постоянной.
f
Рассматривать биты значения как число с плавающей точкой и вывести с использованием обычного синтаксиса для чисел с плавающей точкой.

Например, чтобы вывести счетчик программы в шестнадцатеричном виде (см. раздел 8.10 Регистры), введите

p/x $pc

Обратите внимание, что перед косой чертой не требуется пробела, потому что имена команд в GDB не могут содержать косую черту.

Чтобы вывести последнее значение из истории значений в другом формате, вы можете воспользоваться командой print лишь с указанием формата и без выражения. Например, `p/x' выведет последнее значение в шестнадцатеричной форме.

8.5 Исследование памяти

Вы можете использовать команду x (от слова "examine") для исследования памяти в одном из нескольких форматов, независимо от типов данных вашей программы.

x/nfu адрес
x адрес
x
Для исследования памяти используйте команду x.

n, f и u---необязательные параметры, определяющие, сколько памяти отобразить и в каком формате; адрес---это выражение, задающее адрес, с которого вы хотите начать отображение памяти. Если вы используете значения по умолчанию для nfu, то вам не нужно вводить косую черту `/'. Некоторые команды устанавливают удобные значения по умолчанию для адреса.

n, счетчик повторений
Счетчик повторений является десятичным целым числом; по умолчанию 1. Он определяет, сколько памяти отобразить (считая в единицах u).
f, формат отображения
Формат отображения--это один из форматов, используемых командой print, `s' (строка, оканчивающаяся нулем), или `i' (машинная инструкция). Первоначально, значением по умолчанию установлено `x' (шестнадцатеричная форма). Значение по умолчанию изменяется каждый раз, когда вы используете либо x, либо print.
u, размер единицы измерений
Размер единицы измерений может быть одним из
b
Байты.
h
Полуслова (два байта).
w
Слова (четыре байта). Это первоначальное значение по умолчанию.
g
Длинные слова (восемь байт).
Каждый раз, когда вы определяете размер единицы измерений командой x, этот размер становится размером по умолчанию при последующем использовании x. (Для форматов `s' и `i', размер единицы измерений игнорируется и обычно не пишется.)
адрес, начальный адрес отображения
адрес---это адрес, с которого вы хотите, чтобы GDB начинал отображение памяти. Значение выражения не обязано должно быть указателем (хотя может им быть); оно всегда интерпретируется как целый адрес байта в памяти. См. раздел 8.1 Выражения, для дополнительной информации о выражениях. Значением по умолчанию для адреса обычно является адрес, следующий за последним изученным адресом, но некоторые другие команды также устанавливают это значение: 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 задан счетчик повторений, адрес и его содержимое сохраняются из последнего выведенного элемента памяти; это не то же самое, что последний выведенный адрес, если в последней строке вывода были отображены несколько элементов.

8.6 Автоматическое отображение

Если вам необходимо часто выводить значение какого-либо выражения (чтобы увидеть, как оно меняется), вы можете добавить его в список автоматического отображения, чтобы GDB выводил его значение каждый раз при остановке вашей программы. Каждому выражению, добавленному в список, присваивается идентификационный номер; чтобы удалить выражение из списка, вы указываете этот номер. Автоматическое отображение выглядит следующим образом:

2: foo = 38
3: bar[5] = (struct hack *) 0x3804

Это отображение показывает номера элементов, выражения и их текущие значения. Как и при отображении, запрашиваемом вручную с помощью x или print, вы можете указать предпочитаемый формат вывода; фактически, display определяет, следует использовать print или x, в зависимости от того, на сколько жесткая ваша спецификация формата: используется x, если вы указываете размер элемента или один из двух форматов (`i' и s), которые поддерживаются только x; в остальных случаях используется print.

display выраж
Добавляет выражение выраж к списку выражений, отображаемых каждый раз, когда ваша программа останавливается. См. раздел 8.1 Выражения. display не повторяется, если вы повторно нажимаете RET после ее использования.
display/формат выраж
Если формат определяет только формат вывода, а не размер или счетчик повторений, выражение выраж добавляется в список автоматического отображения, но его отображение осуществляется в указанном формате формат. См. раздел 8.4 Форматы вывода.
display/формат адрес
Если форматом является `i' или `s', или он включает в себя размер элементов или их число, выражение адрес добавляется как адрес памяти для исследования при каждой остановке вашей программы. Под исследованием в данном случае подразумевается выполнение `x/формат адрес'. См. раздел 8.5 Исследование памяти.

Например, команда `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 будет вновь иметь смысл.

8.7 Параметры вывода

GDB предоставляет следующие способы управления выводом массивов, структур и символов.

Данные параметры полезны при отладке программ на любом языке:

set print address
set print address on
GDB выводит адреса памяти, показывающие положение стека, структур, указателей, точек останова, и так далее, даже когда он отображает также содержимое этих адресов. Значение по умолчанию установлено в 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
Велит GDB выводить имя исходного файла и номер строки символа в символьной форме адреса.
set print symbol-filename off
Не выводить имя исходного файла и номер строки символа. Принимается по умолчанию.
show print symbol-filename
Показать, будет GDB выводить имя исходного файла и номер строки в символьной форме адреса или нет.

Другая ситуация, в которой полезно показывать имена файлов и номера строк, возникает при дисассемблировании кода; GDB показывает вам номер строки и исходный файл, которые соответствуют каждой инструкции.

Вы также можете захотеть видеть символьную форму только в том случае, если выводимый адрес достаточно близок к ближайшему предшествующему символу:

set print max-symbolic-offset макс-смещение
Велит GDB выводить символьные формы только тех адресов, для которых смещение между ближайшим предшествующим символом и адресом меньше, чем макс-смещение. По умолчанию значение макс-смещение равно 0; в этом случае GDB всегда выводит адрес в символьной форме, если ему предшествует хоть какой-нибудь символ.
show print max-symbolic-offset
Запрашивает информацию о максимальном смещении, для которого GDB выводит символьную форму адреса.

Если у вас есть указатель, и вы не знаете, на что он указывает, попробуйте `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 число-элементов
Установить ограничение на количество выводимых GDB элементов массива. Если GDB выводит большой массив, вывод прерывается после того, как будет выведено установленное командой set print elements число элементов. Это ограничение также действует при отображении строк. Когда GDB стартует, этот предел принимается равным 200. Установка число-элементов в ноль означает, что вывод не ограничен.
show print elements
Показать количество элементов большого массива, которые будут выведены GDB. Если это число равно 0, вывод не ограничивается.
set print null-stop
Указывает GDB прекращать вывод символов массива, как только встретится первый NULL. Это полезно, когда большие массивы фактически содержат только короткие строки. По умолчанию отключено.
set print pretty on
Велит GDB выводить структуры в формате с отступами, по одному элементу в строке, например:
$1 = {
  next = 0x0,
  flags = {
    sweet = 1,
    sour = 1
  },
  meat = 0x54 "Pork"
}
set print pretty off
Указывает GDB выводить структуры в компактном формате, как здесь:
$1 = {next = 0x0, flags = {sweet = 1, sour = 1}, \
meat = 0x54 "Pork"}
Этот формат устанавливается по умолчанию.
show print pretty
Показать, какой формат GDB использует для вывода структур.
set print sevenbit-strings on
Осуществлять вывод, используя только семибитные символы; если этот параметр установлен, GDB отображает любые восьмибитные символы (в строках или символьных значениях), используя запись \nnn. Эта установка очень удобна, если вы работаете на английском (ASCII) и используете старший бит символов как маркер или "мета"-бит.
set print sevenbit-strings off
Выводить восьмибитные символы полностью. Это позволяет использовать большее количество международных наборов символов, и устанавливается по умолчанию.
show print sevenbit-strings
Показать, выводит GDB только семибитные литеры или нет.
set print union on
Велит GDB выводить объединения, содержащиеся в структурах. Устанавливается по умолчанию.
set print union off
Указывает GDB не выводить объединения, содержащиеся в структурах.
show print union
Запросить GDB, будет ли он выводить объединения, содержащиеся в структурах. Например, пусть даны описания
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
Позволить GDB выбрать стиль декодирования посредством изучения вашей программы.
gnu
Декодирование основывается на алгоритме кодирования компилятора GNU Си++ (g++). Устанавливается по умолчанию.
hp
Декодирование основывается на алгоритме кодирования HP ANSI Си++ (aCC).
lucid
Декодирование основывается на алгоритме кодирования компилятора Lucid Си++ (lcc).
arm
Декодировать, используя алгоритм из C++ Annotated Reference Manual. Предупреждение: одной этой установки недостаточно, чтобы производить отладку исполняемых программ, сгенерированных 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
Показать, производится структурный вывод таблиц виртуальных функций Си++ или нет.

8.8 История значений

Значения, выведенные командой 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
Вывести из истории последние десять значений, с их номерами. Это похоже на команду `p $$9', повторенную десять раз, за исключением того, что show values не изменяет историю.
show values n
Вывести десять значений из истории, расположенных вокруг элемента с номером n.
show values +
Вывести десять значений из истории, следующих сразу после последнего выведенного значения. Если доступных значений больше нет, show values + не выводит ничего.

Нажатие RET для повтора show values n действует точно так же, как `show values +'.

8.9 Вспомогательные переменные

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 сначала производит поиск пользовательского или системного имени, перед поиском вспомогательной переменной.

8.10 Регистры

В выражениях, вы можете обращаться к содержимому машинных регистров, обозначая их как переменные с именами, начинающимся с `$'. Имена регистров различаются от машины к машине; для вывода имен регистров, используемых на вашей машине, воспользуйтесь командой 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 не в состоянии найти сохраненные регистры, выбранный кадр стека не имеет значения.

8.11 Аппаратные средства поддержки вычислений с плавающей точкой

В зависимости от конфигурации, GDB может выдать вам больше информации о состоянии аппаратных средств поддержки вычислений с плавающей точкой.

info float
Отобразить аппаратно-зависимую информацию о модуле поддержки вычислений с плавающей точкой. Ее точное содержание и размещение зависит от микросхемы поддержки вычислений с плавающей точкой. В настоящее время, `info float' поддерживается на машинах ARM и x86.


[Содержание]   [Назад]   [Пред]   [Вверх]   [След]   [Вперед]