Назначение отладчика, такого как GDB---позволить вам увидеть, что происходит "внутри" другой программы во время ее выполнения, или что делала другая программа в момент краха.
GDB может выполнять действия четырех основных типов (а также другие, поддерживающие эти основные), чтобы помочь вам выявить ошибку:
Вы можете использовать GDB для отладки программ, написанных на Си и Си++. Для получения более подробной информации, смотрите section Поддерживаемые языки. Для дополнительной информации, смотрите section Си и Си++.
GDB частично поддерживает языки Модула-2 и Chill. Для получения информации о Модуле-2, смотрите section Модула-2. Для получения информации о Chill, см. section Chill
Отладка программ на Паскале, которые используют множества, поддиапазоны, файловые переменные или вложенные функции, в настоящее время не работает. GDB не поддерживает ввод выражений, вывод значений, и аналогичные возможности, использующие синтаксис Паскаля.
GDB может использоваться для отладки программ, написанных на Фортране, хотя может возникнуть необходимость ссылаться на некоторые переменные с использованием знака подчеркивания на конце.
GDB---свободная программа, защищенная Универсальной Общественной Лицензией GNU (GPL). GPL предоставляет вам свободу копировать или изменять программу, но каждый человек, получая копию, также получает свободу изменять эту копию (это означает, что он должен получить доступ к исходному коду), и свободу распространять последующие копии. Обычные компании, разрабатывающие программы, используют авторские права для ограничения ваших свобод; Фонд Свободного Программного Обеспечения использует GPL для сохранения этих свобод.
Главное, Универсальная Общественная Лицензия---это лицензия, говорящая, что вы имеете эти свободы и что вы не можете их у кого-либо отнять.
Первоначальным автором GDB, как и многих других программ GNU, был Ричард Столмен. Многие другие люди внесли вклад в его разработку. Этот раздел пытается отдать должное основным участникам разработки. Одним из достоинств свободных программ является то, что любой человек имеет свободу делать вклад в их развитие; к сожалению, мы не можем в действительности поблагодарить здесь всех. Файл `ChangeLog' в поставке GDB представляет детальнейший отчет.
Изменения, сделанные задолго до версии 2.0 потеряны в тумане времен.
Оправдание: Дополнения к этому разделу особенно приветствуются. Если вы или ваши друзья (или враги, чтобы соблюдать справедливость) были незаслуженно пропущены в этом списке, мы будем рады добавить ваши имена!
Особенно мы хотим сказать спасибо тем, кто присматривал за GDB между основными выпусками, чтобы они не сочли свои многочисленные заслуги оставленными без благодарности: Эндрю Кагни (выпуск 5.0); Джим Бленди (выпуск 4.18); Джесон Моленда (выпуск 4.17); Стан Шебс (выпуск 4.14); Фред Фиш (выпуски 4.16, 4.15, 4.13, 4.12, 4.11, 4.10, и 4.9); Сту Гроссман и Джон Гилмор (выпуски 4.8, 4.7, 4.6, 4.5, и 4.4); Джон Гилмор (выпуски 4.3, 4.2, 4.1, 4.0, и 3.9); Джим Кингдон (выпуски 3.5, 3.4, и 3.3) и Ренди Смит (выпуски 3.2, 3.1, и 3.0).
Ричард Столмен, которому в различные времена помогали Петер ТерМаат, Крис Хенсон и Ричард Млинарик, занимался выпусками до 2.8.
Михаэль Тиманн является автором большей части поддержки GNU Си++ в GDB, со значительным дополнительным вкладом от Пера Бозера. Джеймс Кларк написал дешифровщик(1) имен GNU Си++. Ранняя работа по Си++ была сделана Петером ТерМаатом (который также сделал много общей работы по обновлению, приведшей к выпуску 3.0).
Для исследования многих форматов объектных файлов, GDB 4 использует библиотеку подпрограмм BFD. BFD был совместным проектом Дэвида В. Хенкел-Волласа, Рича Пиксли, Стива Чемберлена, и Джона Гилмора.
Дэвид Джонсон первоначально написал поддержку COFF; Пейс Виллисон первоначально сделал поддержку инкапсулированного COFF.
Брент Бенсон из Harris Computer Systems сделал поддержку DWARF 2.
Адам ДеБур и Брэндли Дэвис сделали поддержку ISI Optimum V. Пер Бозер, Нобоюки Хикичи, и Алессандро Форин сделали поддержку MIPS. Жан-Даниэль Фекет сделал поддержку Sun 386i. Крис Хенсон улучшил поддержку HP9000. Нобоюки Хикичи и Томоюки Хаси сделали поддержку Sony/News OS 3. Дэвид Джонсон сделал поддержку Encore Umax. Юрки Куоппала сделал поддержку Altos 3068. Джефф Ло сделал поддержку HP PA и SOM. Кейс Паккард сделал поддержку NS32K. Доуг Ребсон сделал поддержку Acorn Risc Machine. Боб Раск сделал поддержку Harris Nighthawk CX-UX. Крис Смит сделал поддержку Convex (и отладку программ на Фортране). Джонатан Стоун сделал поддержку Pyramid. Михаэль Тиманн сделал поддержку SPARC. Тим Такер сделал поддержку для Gould NP1 и Gould Powernode. Пейс Виллисон сделал поддержку Intel 386. Джей Восбург сделал поддержку Symmetry.
Андреас Шваб сделал поддержку M68K Linux.
Рич Шаефер и Петер Шауер помогли реализовать поддержку разделяемых библиотек SunOS.
Джей Фенласон и Роланд МакГрес проверили совместимость GDB и GAS по нескольким наборам машинных инструкций.
Патрик Дювал, Тед Голдстейн, Викрам Кока и Гленн Инжел помогли разработать удаленную отладку. Intel Corporation, Wind River Systems, AMD и ARM сделали модули удаленной отладки для целей i960, VxWorks, A29K UDI, и RDI соответственно.
Брайан Фокс является автором библиотек Readline, предоставляющих историю команд и возможность редактирования командной строки.
Эндрю Бирс из SUNY Buffalo написал код для переключения языков, поддержку Модулы-2, главу `Языки' этого руководства.
Фред Фиш написал большую часть поддержки Unix System Vr4. Он также улучшил поддержку завершения команд для поддержки перегруженных символов Си++.
Hitachi America, Ltd. спонсировала поддержку для процессоров H8/300, H8/500 и Super-H.
NEC спонсировала поддержку процессоров v850, Vr4xxx и Vr5xxx.
Mitsubishi спонсировала поддержку процессоров D10V, D30V и M32R/D.
Toshiba спонсировала поддержку процессора TX39 Mips.
Matsushita спонсировала поддержку процессоров MN10200 и MN10300.
Fujitsu спонсировала поддержку процессоров SPARClite и FR30.
Кунг Шу, Джефф Ло и Рик Слэдки добавили поддержку аппаратных точек наблюдения.
Михаэль Снайдер добавил поддержку точек трассировки.
Сту Гроссман написал gdbserver.
Джим Кингдон, Петер Шауер, Ян Тейлор и Сту Гроссман сделали почти бесчисленное количество исправлений и улучшений во всем GDB.
Следующие люди из Hewlett-Packard Company сделали поддержку архитектуры PA-RISC 2.0, HP-UX 10.20, 10.30 и 11.0 (усеченный режим), реализации нитей HP в ядре, компилятора HP aC++, и конечного интерфейса пользователя: Бен Крепп, Ричард Тайтл, Джон Бишоп, Сюзан Макчиа, Кэси Манн, Сэтиш Пай, Индиа Поул, Стив Рейраур и Елена Заннони. Ким Хаас предоставил специфичную для HP информацию для этого руководства.
Cygnus Solutions спонсировала поддержку GDB и большую часть его развития с 1991 года. Среди инженеров Cygnus, работавших над GDB на постоянной основе, Марк Александер, Джим Бленди, Пер Бозер, Кевин Беттнер, Эдит Эпштейн, Крис Фейлор, Фред Фиш, Мартин Хант, Джим Ингам, Джон Гилмор, Сту Гроссман, Кунг Шу, Джим Кингдон, Джон Мецлер, Фернандо Нассер, Джеффри Ноер, Дон Перчик, Рич Пиксли, Зденек Радуч, Кейс Сейц, Стан Шебс, Дэвид Тейлор и Елена Заннони. Кроме того, Дейв Бролли, Ян Кармихаэль, Стив Чемберлен, Ник Клифтон, Джэй Ти Конклин, Стен Кокс, Ди Джей Делори, Ульрих Дреппер, Фрэнк Эйглер, Дуг Эванс, Син Фаган, Дэвид Хенкель-Воллас, Ричард Хендерсон, Джефф Холком, Джефф Ло, Джим Лемке, Том Лорд, Боб Мансон, Михаэль Мейсснер, Джейсон Меррилл, Кэтрин Мур, Дрю Мосли, Кен Робурн, Гавин Ромиг-Кох, Роб Савой, Джейми Смит, Майк Стамп, Ян Тейлор, Анжела Томас, Михаэль Тиманн, Том Тромей, Рон Унро, Джим Вилсон и Дэвид Зун также сделали свой вклад в большей или меньшей степени.
Вы можете пользоваться этим руководством в свое удовольствие, чтобы прочитать о GDB все. Однако, достаточно небольшого количества команд, чтобы начать пользоваться отладчиком. Эта глава иллюстрирует эти команды.
В этом примере сеанса мы выделяем ввод пользователя так: ввод, чтобы его было проще отличить от находящегося рядом вывода программы.
В одной из предварительных версий программы GNU m4
(настраиваемый
макропроцессор), была допущена следующая ошибка: иногда, при замене
строк, определяющих кавычки, со значений по умолчанию, команды,
использовавшиеся для поиска одного макроопределения внутри другого,
прекращали работать. В следующем коротком сеансе m4
, мы
определим макрос foo
, который расширяется до 0000
; затем мы
используем встроенную процедуру m4
defn
, чтобы определить
bar
точно также. Однако, когда мы изменим открывающую кавычку
на <QUOTE>
, а закрывающую на <UNQUOTE>
, та же самая процедура не
сможет определить новый синоним baz
:
$ cd gnu/m4 $ ./m4 define(foo,0000) foo 0000 define(bar,defn(`foo')) bar 0000 changequote(<QUOTE>,<UNQUOTE>) define(baz,defn(<QUOTE>foo<UNQUOTE>)) baz C-d m4: End of input: 0: fatal error: EOF in string(2)
Попытаемся с помощью GDB понять, что же происходит.
$ gdb m4 GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 5.0, Copyright 1999 Free Software Foundation, Inc... (gdb)
GDB читает только минимум символьных данных, достаточный для того, чтобы знать, где в случае необходимости искать остальные; в результате первое приглашение появляется очень быстро. Теперь мы велим GDB использовать меньшую ширину экрана, чем обычно, чтобы примеры умещались на страницах этого руководства.
(gdb) set width 70
Нам необходимо увидеть, как работает встроенная процедура m4
changequote
. Посмотрев исходный текст, мы знаем, что
соответствующей подпрограммой является m4_changequote
, так что мы
устанавливаем там точку останова с помощью команды GDB break
.
(gdb) break m4_changequote Breakpoint 1 at 0x62f4: file builtin.c, line 879.
Используя комманду run
, мы запускаем m4
под управлением
GDB; до тех пор, пока управление не достигло подпрограммы
m4_changequote
, программа выполняется как обычно:
(gdb) run Starting program: /work/Editorial/gdb/gnu/m4/m4 define(foo,0000) foo 0000
Чтобы активировать точку останова, мы вызываем changequote
.
GDB приостанавливает выполнение m4
, выводя на экран
информацию о том месте, где он остановился.
changequote(<QUOTE>,<UNQUOTE>) Breakpoint 1, m4_changequote (argc=3, argv=0x33c70) at builtin.c:879 879 if (bad_argc(TOKEN_DATA_TEXT(argv[0]),argc,1,3))
Теперь мы используем команду n
(next
), чтобы продолжить
выполнение до следующей строки текущей функции.
(gdb) n 882 set_quotes((argc >= 2) ? TOKEN_DATA_TEXT(argv[1])\ : nil,
set_quotes
выглядит как нужная нам подпрограмма. Мы можем войти в
нее, используя команду s
(step
) вместо next
.
step
переходит на следующую исполняемую строку любой
подпрограммы, так что она входит в set_quotes
.
(gdb) s set_quotes (lq=0x34c78 "<QUOTE>", rq=0x34c88 "<UNQUOTE>") at input.c:530 530 if (lquote != def_lquote)
Отображение, показывающее подпрограмму (и ее параметры), где m4
сейчас приостановлен, называется отображением кадра стека. Оно
показывает обзор стека. Мы можем использовать команду
backtrace
(которая может сокращаться как bt
), чтобы посмотреть, в
каком месте стека мы находимся: команда backtrace
выводит
кадр стека для каждой активной подпрограммы.
(gdb) bt #0 set_quotes (lq=0x34c78 "<QUOTE>", rq=0x34c88 "<UNQUOTE>") at input.c:530 #1 0x6344 in m4_changequote (argc=3, argv=0x33c70) at builtin.c:882 #2 0x8174 in expand_macro (sym=0x33320) at macro.c:242 #3 0x7a88 in expand_token (obs=0x0, t=209696, td=0xf7fffa30) at macro.c:71 #4 0x79dc in expand_input () at macro.c:40 #5 0x2930 in main (argc=0, argv=0xf7fffb20) at m4.c:195
Чтобы посмотреть, что же происходит, мы проходим по шагам еще несколько строк.
Первые два раза мы можем использовать `s'; следующие два раза
мы пользуемся командой n
, чтобы избежать
вхождения в подпрограмму xstrdup
.
(gdb) s 0x3b5c 532 if (rquote != def_rquote) (gdb) s 0x3b80 535 lquote = (lq == nil || *lq == '\0') ? \ def_lquote : xstrdup(lq); (gdb) n 536 rquote = (rq == nil || *rq == '\0') ? def_rquote\ : xstrdup(rq); (gdb) n 538 len_lquote = strlen(rquote);
Последняя выведенная строка выглядит несколько странно; мы можем
исследовать переменные lquote
и rquote
, чтобы понять,
действительно ли это определенные нами новые левая и правая кавычки.
Мы используем команду p
(print
), чтобы посмотреть их значения.
(gdb) p lquote $1 = 0x35d40 "<QUOTE>" (gdb) p rquote $2 = 0x35d50 "<UNQUOTE>"
Действительно, lquote
и rquote
являются новыми кавычками. Для
просмотра контекста, мы можем вывести десять строк исходного текста,
окружающих текущую строку, используя команду l
(list
).
(gdb) l 533 xfree(rquote); 534 535 lquote = (lq == nil || *lq == '\0') ? def_lquote\ : xstrdup (lq); 536 rquote = (rq == nil || *rq == '\0') ? def_rquote\ : xstrdup (rq); 537 538 len_lquote = strlen(rquote); 539 len_rquote = strlen(lquote); 540 } 541 542 void
Давайте пройдем еще две строки, которые устанавливают len_lquote
и
len_rquote
, и затем исследуем значения этих переменных.
(gdb) n 539 len_rquote = strlen(lquote); (gdb) n 540 } (gdb) p len_lquote $3 = 9 (gdb) p len_rquote $4 = 7
Это, очевидно, неправильно, так как len_lquote
и len_rquote
обозначают длины переменных lquote
и rquote
соответственно.
Мы можем присвоить им лучшие значения, используя
команду p
, так как она может выводить значение любого выражения, а
выражение может содержать вызовы подпрограмм и присваивания.
(gdb) p len_lquote=strlen(lquote) $5 = 7 (gdb) p len_rquote=strlen(rquote) $6 = 9
Достаточно ли этого, чтобы решить проблему использования новых кавычек
во встроенной процедуре m4
defn
? Мы можем
продолжить выполнение m4
командой c
(continue
),
и затем попробовать пример, первоначально вызывавший ошибку:
(gdb) c Continuing. define(baz,defn(<QUOTE>foo<UNQUOTE>)) baz 0000
Успех! Теперь новые кавычки работают так же хорошо, как и стандартные.
Кажется, проблема заключалась лишь в двух опечатках, приводивших к
неправильному определению длин. Мы позволим m4
выйти, подавая ему
на вход EOF:
C-d Program exited normally.(3)
Сообщение `Program exited normally.'
исходит от GDB; оно
показывает, что m4
закончил выполнение. Мы можем завершить наш
сеанс работы с GDB командой quit
.
(gdb) quit
Эта глава посвящена тому, как запустить GDB и как из него выйти. Основные принципы:
quit
или C-d для выхода из него.
Вызывайте GDB путем запуска программы gdb
.
Начав работу, GDB считывает команды с терминала до тех пор,
пока вы не скажете ему выйти.
Вы также можете запустить gdb
с различными аргументами и
ключами, чтобы в самом начале лучше настроить среду отлаживания.
Ключи командной строки, описанные здесь, предназначены для охвата различных ситуаций; в дейтсвительности, в некоторых средах часть этих ключей может быть недоступна.
Чаще всего GDB вызывается с одним аргументом, который определяет исполняемую программу:
gdb программа
Вы также можете указать при старте как исполняемую программу, так и файл дампа памяти:
gdb программа дамп
Если вы хотите отладить выполняющийся в данный момент процесс, то вместо этого, вы можете указать вторым аргументом идентификатор этого процесса:
gdb программа 1234
присоединит GDB к процессу 1234
(если, конечно, у вас
нет файла с именем `1234', GDB сначала проверяет
наличие файла дампа памяти).
Преимущества, которые можно получить при использовании второго аргумента командной строки, требуют наличия достаточно совершенной операционной системы; если вы используете GDB как удаленный отладчик, присоединенный к компьютеру без операционной системы, там вообще может не быть понятия "процесса", и часто нет никакого способа получить дамп. GDB предупредит вас, если ему не удается присоединиться к процессу или считать файл дампа памяти.
Вы можете запустить gdb
без вывода начального сообщения,
описывающего отсутствие гарантии на него, указав -silent
:
gdb -silent
Кроме того, вы можете контролировать процесс запуска GDB с помощью ключей командной строки. GDB может сам напомнить вам о доступных ключах.
Введите
gdb -help
чтобы вывести на экран все доступные опции с кратким описанием их использования (сокращенный эквивалент---`gdb -h').
Все заданные вами ключи и параметры командной строки обрабатываются последовательно. Порядок становится важным при использовании ключа `-x'.
При запуске, GDB считывает параметры, отличные от ключей, как указатели на исполняемую программу и файл дампа (или идентификатор процесса), точно так же, как если бы эти параметры задавались ключами `-se' и `-c' соответственно. (GDB считает первый параметр, не имеющий соответствующего флага ключа, эквивалентом ключа `-se', за которым следует этот параметр; а второй параметр, не имеющий соответствующего флага ключа, если он есть, эквивалентом ключа `-c', за которым следует этот параметр.)
Если GDB был сконфигурирован без включения поддержки файлов дампа, что имеет место для большинства встроенных целей, то он выразит недовольство вторым аргументом и проигнорирует его.
Многие ключи имеют как длинную, так и краткую формы; в следующем списке приводятся обе. GDB также распознает сокращения длинных форм, не являющиеся двусмысленными. (Вы можете, по желанию, обозначать ключи с помощью `--', а не `-', хотя мы показываем наиболее употребляемый формат.)
-symbols файл
-s файл
-exec файл
-e файл
-se файл
-core файл
-c файл
-c номер
attach
(при условии, что нет файла в формате дампа
памяти с именем номер; в этом
случае `-c' определяет этот файл как дамп для считывания).
-command файл
-x файл
-directory каталог
-d каталог
-m
-mapped
mmap
, вы можете использовать этот ключ,
чтобы GDB записывал символы из вашей программы в файл в текущем
каталоге, допускающий повторное использование. Если программа,
которую вы отлаживаете, называется `/tmp/fred', то отображаемым
символьным файлом будет `/tmp/fred.syms'. Последующие отладочные
сеансы GDB замечают наличие этого файла и могут быстро
отобразить в память символьную информацию из него, а не читать
таблицу символов из выполняемого файла.
Файл `.syms' специфичен для рабочей машины, на которой запускается
GDB. Он содержит точный образ внутренней символьной
таблицы GDB. Он не может быть разделен между несколькими
рабочими платформами.
-r
-readnow
Ключи -mapped
и -readnow
обычно используются вместе, чтобы
построить файл `.syms', который содержит полную информацию о
символах. (See section Команды для задания файлов, для информации о
файлах `.syms'.) Вот простой вызов GDB, не делающий
ничего, кроме построения файла `.syms' для использования в будущем:
gdb -batch -nx -mapped -readnow имя-программы
Вы можете вызывать GDB в различных альтернативных режимах---например, в пакетном или в "тихом" режиме.
-nx
-n
-quiet
-silent
-q
-batch
0
после обработки
всех командных файлов, заданных ключем `-x' (и всех команд
из инициализационных файлов, если это не запрещено ключем `-n').
Выйти с ненулевым значением, если во время выполнения
команд GDB из командных файлов произойдет ошибка.
Пакетный режим может быть полезен при вызове GDB как
фильтра; например, чтобы загрузить программу и запустить ее на
другом компьютере. Для того, чтобы сделать это более удобным, сообщение
Program exited normally.(которое обычно выдается при завершении программы, выполняемой под управлением GDB), при выполнении в пакетном режиме не выдается.
-nowindows
-nw
-windows
-w
-cd каталог
-fullname
-f
-epoch
-annotate уровень
-async
-noasync
-baud бод-в-сек
-b бод-в-сек
-tty устройство
-t устройство
-interpreter интерп
-write
-statistics
-version
quit [выражение]
q
quit
(сокращенно q
),
или введите знак конца файла (обычно C-d).
Если вы не укажете выражение, GDB
закончит работу нормально; в противном случае, он
использует результат выражения как код ошибки.
Прерывание (часто C-c) не приводит к выходу из GDB, а завершает любую выполняющуюся команду и возвращает вас на командный уровень. Вы можете безопасно пользоваться прерыванием в любое время, потому что GDB не позволяет ему вступить в силу до того, как это станет безопасным.
Если вы использовали GDB для управления присоединенным процессом
или устройством, вы можете освободить его командой detach
(see section Отладка запущенного ранее процесса).
Если вам случайно потребовалось выполнить команды оболочки в течение сеанса
отладки, нет смысла приостанавливать или покидать
GDB; вам достаточно воспользоваться командой shell
.
shell командная строка
SHELL
, если она существует, определяет,
какую оболочку запустить. В противном случае, GDB
использует оболочку по умолчанию (`/bin/sh' в системах Unix,
`COMMAND.COM' в MS-DOS, и так далее).
В средах разработки часто бывает необходимо воспользоваться
утилитой make
. Для этой цели вам не обязательно пользоваться
командой shell
в GDB:
make make-арг
make
с указанными аргументами. Это
эквивалентно `shell make make-арг'.
Вы можете сокращать команды GDB по нескольким первым символам имени команды, если это сокращение однозначно; и вы можете повторять определенные команды GDB простым нажатием RET. Вы также можете использовать клавишу TAB для того, чтобы GDB сам дополнил остаток слова в команде (или показал вам возможные альтернативы, если существует несколько вариантов).
Команда GDB представляет собой одну строку ввода. Никаких
ограничений на ее длину нет. Она начинается именем команды, за которым
следуют параметры, значение которых определяется ее названием.
Например, команда step
допускает в качестве параметра число
шагов, как в `step 5'. Вы также можете использовать команду
step
и без параметров. Некоторые команды не допускают
никаких параметров.
Названия команд GDB всегда могут быть сокращены, если это
сокращение однозначно. Другие возможные сокращения команд перечислены в
документации по отдельным командам. В некоторых случаях, допускаются
даже неоднозначные сокращения; напрмер, s
специально определено
как эквивалент step
, даже если существуют другие команды, чьи
названия начинаются на s
. Вы можете проверить сокращения,
задавая их как параметр для команды help
.
Введенная пустая строка (просто нажатие RET), означает повтор
предыдущей команды. Определенные команды (например, run
)
не повторяются таким способом; это те команды, непреднамеренное
повторение которых может вызвать проблемы и которые вы вряд ли захотите
повторять.
Команды list
и x
, при их повторе нажатием RET,
вместо точного повтора создают новые параметры. Это позволяет легко
просматривать исходный текст или память.
GDB может также использовать RET по-другому: для
разделения длинного вывода, аналогично обычной утилите more
(see section Размер экрана). Так как в такой ситуации легко
нажать RET слишком много раз, GDB блокирует повтор после
любой команды, генерирующей такой тип вывода.
Любой текст, расположенный от # до конца строки является комментарием; он ничего не делает. В основном, это полезно в командных файлах (see section Командные файлы).
GDB может дополнить за вас окончание слова в команде, если существует только один вариант; он также может в любой момент показать, какие завершения возможны для следующего слова в команде. Это работает для команд и подкоманд GDB, а также для имен символов в вашей программе.
Нажмите TAB в любой момент, когда захотите, чтобы GDB дополнил оставшуюся часть слова. Если существует только одна возможность, GDB дополняет слово и ждет, пока вы закончите команду (или нажмете RET, чтобы ввести ее). Например, если вы введете
(gdb) info bre TAB
GDB дополнит остаток слова `breakpoints', так как у
команды info
есть единственная подкоманда, начинающаяся с `bre':
(gdb) info breakpoints
Теперь вы можете нажать либо RET, чтобы выполнить команду
info breakpoints
, либо удалить часть символов и ввести что-то другое,
если `breakpoints' не является той командой, которую вы ожидали.
(Если вы с самого начала были уверены, что хотите info breakpoints
,
вы также могли просто нажать RET, сразу после `info bre',
использовав сокращение команды вместо завершения).
Если при нажатии TAB существует несколько вариантов для следующего слова, GDB издает звук. Вы можете либо ввести больше символов и попробовать снова, либо нажать TAB второй раз; GDB выведет все возможные завершения для этого слова. Например, вы можете захотеть установить точку останова на подпрограмме, чье имя начинается с `make_', но когда вы вводите b make_TAB, GDB лишь издает звук. Повторное нажатие TAB отображает все имена функций в вашей программе, начинающиеся с этих символов. Например:
(gdb) b make_ TAB GDB издает звук; нажав TAB еще раз, видим: make_a_section_from_file make_environ make_abs_section make_function_type make_blockvector make_pointer_type make_cleanup make_reference_type make_command make_symbol_completion_list (gdb) b make_
После отображения возможных вариантов, GDB копирует ваш частичный ввод (`b make_' в этом примере), так что вы можете закончить команду.
Если вы сначала хотите только увидеть список альтернатив, вы можете нажать M-?, а не нажимать TAB дважды. M-? означает META ?. Вы можете ввести это либо удерживая клавишу, обозначенную на вашей клавиатуре как META (если такая есть), и нажать ?, или как ESC, за которой следует ?.
Иногда нужная вам строка, являясь логически "словом", может содержать
скобки или другие символы, которые GDB обычно исключает из
своего понятия о слове. Чтобы позволить завершению слов работать в
такой ситуации, вы можете заключить слова в командах GDB в
'
(знаки одинарных кавычек).
Наиболее вероятная ситуация, где вам это может потребоваться, это при
вводе имени функции в Си++. Это происходит потому, что Си++ допускает
перегрузку функций (множественные определения одной и той же функции,
различающиеся типом параметров). Например, когда вы хотите установить
точку останова, вам может потребоваться различать, имеете вы в виду
версию name
с параметром целого типа, name(int)
, или же
версию с параметром вещественного типа, name(float)
. Для
использования возможностей завершения слов в такой ситуации, введите
одинарную кавычку '
в начале имени функции. Это предупреждает
GDB, что ему может потребоваться принять во внимание больше
информации, чем обычно, когда вы нажимаете TAB или M-? для
запроса завершения слова:
(gdb) b 'bubble( M-? bubble(double,double) bubble(int,int) (gdb) b 'bubble(
В некоторых случаях, GDB может сам определить, что завершение имени требует использования кавычек. Когда это происходит, GDB вставляет кавычку за вас (выполняя завершение на столько, на сколько это возможно), если вы не ввели ее в первой позиции:
(gdb) b bub TAB GDB изменяет вашу строку ввода на следующую, и издает звук: (gdb) b 'bubble(
Вообще, GDB может определить, что кавычка нужна (и вставляет ее), если вы запрашиваете завершение перегруженного символа до того, как начали вводить список параметров.
Для большей информации о перегруженных функциях, смотрите section Выражения Си++. Вы можете использовать команду set
overload-resolution off
для отключения распознавания перегруженных
символов; смотрите section Возможности GDB для Си++.
Используя команду help
, вы всегда можете запросить информацию о
командах у самого GDB.
help
h
help
(сокращенно h
) без параметров,
для отображения короткого списка именованных классов команд:
(gdb) help List of classes of commands: aliases -- Aliases of other commands breakpoints -- Making program stop at certain points data -- Examining data files -- Specifying and examining files internals -- Maintenance commands obscure -- Obscure features running -- Running the program stack -- Examining the stack status -- Status inquiries support -- Support facilities tracepoints -- Tracing of program execution without stopping the program user-defined -- User-defined commands Type "help" followed by a class name for a list of commands in that class. Type "help" followed by command name for full documentation. Command name abbreviations are allowed if unambiguous. (gdb)
help класс
status
:
(gdb) help status Status inquiries. List of commands: info -- Generic command for showing things about the program being debugged show -- Generic command for showing things about the debugger Type "help" followed by command name for full documentation. Command name abbreviations are allowed if unambiguous. (gdb)
help команда
help
, GDB
выведет короткую справку о том, как ей пользоваться.
apropos арг
apropos арг
производит поиск по регулярному
выражению, заданному в арг, во всех командах GDB и их
документации. Она выводит все найденные совпадения. Например:
apropos reloadприводит к:
set symbol-reloading -- Set dynamic symbol table reloading multiple times in one run show symbol-reloading -- Show dynamic symbol table reloading multiple times in one run
complete арг
complete арг
перечисляет все возможные завершения для
начала команды. Используйте арг для задания начала команды,
которую вы хотите завершить. Например,
complete iприводит к:
if ignore info inspectЭто предназначено для использования GNU Emacs.
В дополнение к help
, вы можете использовать команды GDB
info
и show
для получения информации о состоянии вашей программы,
или о состоянии самого GDB. Каждая команда поддерживает много
тем запросов; это руководство описывает каждую тему в соответствующем месте.
Списки в разделах info
и show
в Алфавитном указателе
указывают на все подкоманды. See section Алфавитный указатель.
info
i
) предназначена для описания состояния
вашей программы. Например, вы можете с помощью info args
просмотреть аргументы, переданные вашей программе, с помощью info
registers
перечислить используемые в настоящий момент регистры, или
используя info breakpoints
вывести установленные вами точки
останова. Вы можете получить полный список подкоманд команды
info
с помощью help info
.
set
set
. Например, вы можете установить приглашение GDB в
знак $ используя set prompt $
.
show
info
, команда show
предназначена для описания
состояния самого GDB. Вы можете изменить почти все, что
показывает show
, используя соответствующую команду set
.
Например, командой set radix
вы можете задать, какую систему
счисления использовать для вывода, или просто узнать, какая система
используется в данный момент с помощью команды show radix
.
Для отображения всех устанавливаемых параметров и их текущих значений,
вы можете использовать show
без аргументов; также можно
использовать info set
. Обе команды приводят к одинаковому
результату.
Вот три разнообразные подкоманды show
, которые не имеют
соответствующих set
-команд:
show version
show copying
show warranty
Прежде чем выполнять программу под управлением GDB, при компиляции вы должны сгенерировать отладочную информацию.
Вы можете запустить GDB с параметрами или без, в любой среде по вашему выбору. Если вы отлаживаете программу на той же машине, на которой выполняется GDB, вы можете перенаправить ввод и вывод вашей программы, отлаживать уже выполняющийся процесс, или убить дочерний процесс.
Для эффективной отладки программы, при компиляции вы должны сгенерировать отладочную информацию. Эта отладочная информация сохраняется в объектном файле; она описывает тип данных каждой переменной или функции, и соответствие между номерами строк исходного текста и адресами в выполняемом коде.
Чтобы запросить генерацию отладочной информации, укажите ключ `-g' при вызове компилятора.
Многие компиляторы Си не могут обрабатывать ключи `-g' и `-O' вместе. Используя такие компиляторы, вы не можете создавать оптимизированные выполняемые файлы, содержащие отладочную информацию.
GCC, GNU компилятор Си, поддерживает `-g' с или без `-O', делая возможным отладку оптимизированного кода. Мы рекомендуем, чтобы вы всегда использовали `-g' при компиляции программ. Вы можете думать, что ваша программа правильная, но нет никакого смысла испытывать удачу.
Когда вы отлаживаете программу, откомпилированную с `-g -O', помните, что оптимизатор перестраивает ваш код; отладчик же показывает то, что там находится в действительности. Не удивляйтесь, если порядок выполнения не будет в точности соответствовать вашему исходному файлу! Крайний пример: если вы определяете переменную, но нигде ее не используете, GDB никогда не увидит этой переменной, потому что при оптимизации компилятор ее исключит.
Некоторые вещи не работают с `-g -O' также, как просто с `-g', в частности, на машинах с планированием инструкций. Если сомневаетесь, перекомпилируйте с одним ключем `-g', и если это устранит проблему, пожалуйста, сообщите нам об этом как об ошибке (включите тестовый пример!).
Ранние версии компилятора GNU Си допускали вариант ключа для отладочной информации `-gg'. GDB больше не поддерживает этот формат; если этот ключ есть у вашего компилятора GNU Си, не используйте его.
run
r
run
для запуска вашей программы под
управлением GDB. Сначала вы должны задать имя программы (кроме
как на VxWorks) с параметрами GDB (see section Вход и выход из GDB), или используя команды file
или exec-file
(see section Команды для задания файлов).
Если вы запускаете вашу программу в среде выполнения, поддерживающей
процессы, run
создает подчиненный процесс, и этот процесс
выполняет вашу программу. (В средах, не поддерживающих процессы,
run
выполняет переход на начало вашей программы.)
Выполнение программы зависит от определенной информации, которую она получает от породившего ее процесса. GDB предоставляет способы задать эту информацию, что вы должны сделать до запуска программы. (Вы можете изменить ее после старта, но такие изменения воздействуют на вашу программу только при следующем запуске.) Эта информация может быть разделена на четыре категории:
run
. Если на вашей системе доступна оболочка, она
используется для передачи параметров, так что при их описании вы можете
использовать обычные соглашения (такие как раскрывание шаблонов или
подстановка переменных).
В системах Unix, вы можете контролировать, какая оболочка используется, с
помощью переменной среды SHELL
.
See section Аргументы вашей программы.
set environment
и
unset environment
, чтобы изменить часть настроек среды, влияющих
на нее. See section Рабочая среда вашей программы.
cd
.
See section Рабочий каталог вашей программы.
run
, или использовать команду tty
,
чтобы установить другое устройство для вашей программы.
See section Ввод и вывод вашей программы.
Предупреждение: Хотя перенаправление ввода и вывода работает, вы
не можете использовать каналы для передачи выходных данных отлаживаемой
программы другой программе; если вы попытаетесь это сделать, скорее
всего GDB перейдет к отладке неправильной программы.
Когда вы подаете команду run
, ваша программа начинает выполняться
немедленно. See section Остановка и продолжение исполнения, для обсуждения
того, как остановить вашу программу. Как только ваша программа
остановилась, вы можете вызывать функции вашей программы, используя
команды print
или call
. See section Исследование данных.
Если время модификации вашего символьного файла изменилось с того момента, когда GDB последний раз считывал символы, он уничтожает свою символьную таблицу и считывает ее заново. При этом GDB старается сохранить ваши текущие точки останова.
Аргументы к вашей программе могут быть заданы как аргументы к команде
run
.
Они передаются оболочке, которая раскрывает символы шаблонов и выполняет
перенаправление ввода-вывода, и с того момента попадают в вашу
программу. Ваша переменная среды SHELL
(если она существует)
определяет, какую оболочку использует GDB. Если вы не
определите SHELL
, он использует оболочку по умолчанию
(`/bin/sh' в Unix).
В не-Unix системах, программу обычно запускает непосредственно GDB, который эмулирует перенаправление ввода-вывода через соответствующие системные вызовы, и символы шаблонов раскрываются кодом запуска, а не оболочкой.
run
без аргументов использует те же аргументы, которые
использовались предыдущей командой run
, или которые установлены
командой set args
.
set args
set args
нет аргументов, run
выполняет вашу программу без аргументов. Если вы запустили вашу
программу с аргументами, то единственный способ запустить ее
снова без аргументов---это использовать set args
до следующего
запуска командой run
.
show args
Среда состоит из набора переменных среды и их значений. Переменные среды обычно хранят такие данные, как ваше имя пользователя, домашний каталог, тип терминала и путь поиска для запуска программ. Как правило, вы устанавливаете переменные среды с помощью оболочки и они наследуются всеми другими программами, которые вы вызываете. При отладке может оказаться полезным попробовать запустить программу в измененной среде, не перезапуская GDB.
path каталог
PATH
(пути
поиска выполняемых файлов), как для GDB, так и для вашей
программы. Вы можете указать названия нескольких каталогов, разделив их
пробелом или системно-зависимым разделителем (`:' в Unix, `;'
в MS-DOS и MS-Windows). Если каталог уже находится в списке путей,
он переносится в начало, так что поиск в нем будет производиться
раньше.
Вы можете использовать строку `cwd', чтобы сослаться на
рабочий каталог, который является текущим в тот момент, когда
GDB производит поиск. Если вместо этого вы используете
`.', то она будет указывать на тот каталог, в котором вы
выполнили команду path
. GDB заменяет `.' в
аргументе каталог (на текущий путь) до добавления каталога к
списку путей поиска.
show paths
PATH
).
show environment [имя-перем]
environment
как env
.
set environment имя-перем [=значение]
set env USER = fooговорит отлаживаемой программе, что при последующих запусках именем пользователя является `foo'. (Пробелы, окружающие `=', использованы здесь для ясности; в действительности, они не обязательны.)
unset environment имя-перем
unset environment
удаляет переменную из среды, а не присваивает
ей пустое значение.
Предупреждение: В системах Unix, GDB вызывает вашу
программу, используя оболочку, указанную вашей переменной среды
SHELL
, если она определена (или /bin/sh
, если не
определена). Если ваша переменная SHELL
указывает на оболочку,
которая выполняет файл инициализации---такой как `.cshrc' для
оболочки C-shell, или `.bashrc' для BASH---любая переменная, которую вы
установите в этом файле, воздействует на вашу программу. В этой
связи, вы можете захотеть перенести установку переменных среды в
файлы, которые выполняются только при вашем входе в систему, такие как
`.login' или `.profile'.
Каждый раз, когда вы запускаете свою программу командой run
, она
наследует рабочий каталог от текущего рабочего каталога
GDB. В начальный момент, рабочий каталог GDB
наследуется от его родительского процесса (обычно оболочки), но вы
можете задать новый рабочий каталог командой cd
из GDB.
Рабочий каталог GDB также служит каталогом по умолчанию для команд отладчика, определяющих действия с файлами. See section Команды для задания файлов.
cd каталог
pwd
По умолчанию, программа, которую вы запускаете под управлением GDB, осуществляет ввод и вывод на тот же терминал, что и GDB. Для взаимодействия с вами, GDB переключает терминал в свой собственный терминальный режим, но он записывает терминальные режимы, которые использовала ваша программа, и переключается назад к ним, когда вы продолжаете выполнение программы.
info terminal
Вы можете перенаправить ввод и/или вывод вашей программы, используя
перенаправление оболочки с помощью команды run
. Например,
run > выходной-файл
запускает вашу программу, перенаправляя ее вывод в `выходной-файл'.
Другой способ задать, как ваша программа должна осуществлять ввод и
вывод---использовать команду tty
. Эта команда принимает в
качестве агрумента имя файла, который будет использоваться по умолчанию
для будущих команд run
. Эта команда также сбрасывает управляющий
терминал для дочернего процесса для будущих команд run
.
Например,
tty /dev/ttyb
указывает, что процессы, запущенные последующими командами run
,
для ввода и вывода используют по умолчанию терминал `/dev/ttyb', и
что он будет их управляющим терминалом.
Явное перенаправление в run
замещает эффект команды tty
для устройств ввода-вывода, но не ее воздействие на управляющий терминал.
Когда вы используете команду tty
или перенаправляете ввод в
команде run
, изменяется только ввод для вашей программы.
Ввод для GDB по прежнему происходит через ваш терминал.
attach идент-процесса
info files
показывает ваши
активные цели.) В качестве аргумента команда получает идентификатор
процесса. Обычный способ узнать идентификатор
Unix-процесса---воспользоваться утилитой ps
или командой оболочки
`jobs -l'.
attach
не повторяется, если вы нажмете RET второй раз
после выполнения команды.
Чтобы использовать attach
, ваша программа должна выполняться в
среде, поддерживающей процессы; например, attach
не работает на
специальных машинах, не имеющих операционной системы. Вы также должны
обладать полномочиями для посылки сигнала процессу.
Когда вы используете attach
, отладчик находит программу
выполняющегося процесса, производя поиск сперва в текущем рабочем
каталоге, а затем (если программа не найдена), используя пути поиска
исходных файлов (see section Определение каталогов с исходными файлами). Также, для загрузки программы вы можете
использовать команду file
. See section Команды для задания файлов.
Первое, что GDB делает после подготовки указанного процесса к
отладке---останавливает его. Вы можете исследовать и изменять
присоединенный процесс всеми командами GDB, которые обычно
доступны, когда вы запускаете процессы с помощью run
. Вы можете
устанавливать точки останова; вы можете пошагово выполнять программу и
продолжить ее обычное выполнение, вы можете изменять области данных.
Если вы решите продолжить выполнение процесса после присоединения к нему
GDB, вы можете использовать команду continue
.
detach
detach
. Отсоединение процесса продолжает его
выполнение. После команды detach
, этот процесс и
GDB снова становятся совершенно независимыми, и вы готовы
присоединить или запустить с помощью run
другой процесс.
detach
не повторяется, если вы нажмете RET еще раз
после выполнения команды.
Если вы выйдете из GDB или используете команду run
, пока
у вас есть присоединенный процесс, вы убьете этот процесс. По
умолчанию, GDB запрашивает подтверждение, если вы пытаетесь
сделать одну из этих вещей; вы можете контролировать, нужно вам это
подтверждение или нет, используя команду set confirm
(see section Необязательные предупреждения и сообщения).
kill
Эта команда полезна, если вы хотите отладить дамп памяти, а не выполняющийся процесс. GDB игнорирует любые дампы памяти, пока ваша программа выполняется.
В некоторых операционных системах, программа не может быть выполнена вне
GDB, пока у вас есть в ней точки останова, установленные
отладчиком. В этой ситуации вы можете использовать команду
kill
, чтобы разрешить выполнение вашей программы вне отладчика.
Команда kill
также полезна, если вы хотите перекомпилировать и
перекомпоновать вашу программу, так как во многих системах невозможно
модифицировать исполняемый файл во время выполнения процесса. В этом
случае, когда вы в следующий раз введете run
, GDB
заметит, что файл изменился, и заново прочитает символьную таблицу
(стараясь при этом сохранить ваши точки останова).
В некоторых операционных системах, таких как HP-UX и Solaris, одна программа может иметь несколько нитей выполнения. Точная семантика нитей меняется от одной операционной системы к другой, но в общем, нити одной программы сродни нескольким процессам---за исключением того, что они разделяют одно адресное пространство (то есть, все они могут исследовать и модифицировать одни и те же переменные). С другой стороны, каждая нить имеет свои собственные регистры и стек выполнения, и, возможно, свои собственные участки памяти.
GDB предоставляет следующие возможности для отладки многонитевых программ:
Предупреждение: Эти возможности доступны еще не в любой конфигурации GDB, где операционная система поддерживает нити. Если ваш GDB не поддерживает нити, эти команды не имеют эффекта. Например, в системах без поддержки нитей, GDB ничего не выводит на команду `info threads', и всегда отвергает команду
thread
, как в этом примере:(gdb) info threads (gdb) thread 1 Thread ID 1 not known. Use the "info threads" command to see the IDs of currently known threads.(5)
Возможности отладки нитей GDB позволяют вам наблюдать все нити во время выполнения вашей программы, но когда управление переходит к GDB, одна конкретная нить выделяется для отладки. Она называется текущей нитью. Отладочные команды показывают информацию о программе с точки зрения текущей нити.
Когда GDB обнаруживает новую нить в вашей программе, он выводит для нее идентификатор на целевой системе с сообщением в форме `[New сист-тег]'. Сист-тег является идентификатором нити, чья форма различается в зависимости от конкретной системы. Например, в LynxOS вы можете увидеть
[New process 35 thread 27]
когда GDB замечает новую нить. Напротив, в системе SGI, сист-тег выглядит просто как `process 368', без дополнительных спецификаций.
Для отладочных целей, GDB присваивает свои собственные номера нитей---всегда в виде одного целого числа---каждой нити в вашей программе.
info threads
(gdb) info threads 3 process 35 thread 27 0x34e5 in sigpause () 2 process 35 thread 23 0x34e5 in sigpause () * 1 process 35 thread 13 main (argc=1, argv=0x7ffffff8) at threadtest.c:68
В системах HP-UX:
Для отладочных целей, GDB присваивает свои собственные номера нитей---небольшие целые, присваиваемые в порядке создания нитей--- каждой нити в вашей программе.
Когда GDB обнаруживает новую нить в вашей программе, он выводит как номер нити, присвоенный GDB, так и идентификатор на целевой системе для нити с сообщением в форме `[New сист-тег]'. сист-тег является идентификатором нити, чья форма различается в зависимости от конкретной системы. Например, в HP-UX, когда GDB замечает новую нить, вы увидите
[New thread 2 (system thread 26594)]
info threads
(gdb) info threads * 3 system thread 26607 worker (wptr=0x7b09c318 "@") \
at quicksort.c:137 2 system thread 26606 0x7b0030d8 in __ksleep () \
from /usr/lib/libc.2 1 system thread 27905 0x7b003498 in _brk () \
from /usr/lib/libc.2
thread номер-нити
(gdb) thread 2 [Switching to process 35 thread 23] 0x34e5 in sigpause ()Также как и с сообщением `[New ...]', форма текста после `Switching to' зависит от соглашений для идентификации нитей в вашей системе.
threads apply [номер-нити] [all] арг
thread apply
позволяет вам применить команду к одной или
нескольким нитям. Задайте номера нитей, на которые вы хотите
воздействовать, в аргументе номер-нити. Номер-нити---это
внутренний номер нити GDB, который показан в первом поле
`info threads'. Чтобы применить команду ко всем нитям, используйте
thread apply all
арг.
Когда GDB останавливает вашу программу, вследствие точки останова или по сигналу, он автоматически выбирает нить, в которой появилась точка останова или сигнал. GDB предупреждает вас о переключении контекста сообщением в форме `[Switching to сист-тег]' для идентификации нити.
See section Остановка и запуск многонитевых программ, для дополнительной информации о поведении GDB, когда вы останавливаете и запускаете многонитевую программу.
See section Установка точек наблюдения, для информации о точках наблюдения в многонитевых программах.
В большинстве систем, GDB не имеет специальной поддержки для
отладки программ, создающих дополнительные процессы с помощью функции
fork
. Когда программа вызывает fork
, GDB будет
продолжать отладку родительского процесса, а дочерний процесс будет
выполняться беспрепятственно. Если выполнение дочернего процесса дойдет
до места, где вы установили точку останова, дочерний процесс получит
сигнал SIGTRAP
, который приведет к остановке процесса (если он не
перехватывает этот сигнал).
Однако, если вы хотите отладить дочерний процесс, существует достаточно
простое решение. Поместите вызов sleep
в код программы, который
дочерний процесс выполнит после fork
. Может быть удобным
вызывать sleep
только если установлена определенная переменная
среды или если существует определенный файл, так что задержка не будет
происходить, если вы не захотите отлаживать дочерний процесс.
Пока дочерний процесс спит, используйте программу ps
для
получения ее идентификатора процесса. Затем укажите GDB
(новому экземпляру GDB, если вы отлаживаете также и родительский
процесс) присоединиться к дочернему процессу (see section Отладка запущенного ранее процесса).
Начиная с этого момента, вы можете отлаживать дочерний процесс точно
также, как любой другой процесс, к которому вы присоединились.
В системе HP-UX (только в версиях 11.x и более поздних?) GDB
предоставляет средства для отладки программ, которые создают
дополнительные процессы, используя функции fork
или vfork
.
По умолчанию, когда программа ветвится, GDB будет продолжать отладку родительского процесса, а дочерний процесс будет выполняться беспрепятственно.
Если вы хотите отлаживать дочерний процесс вместо родительского,
используйте команду set follow-fork-mode
.
set follow-fork-mode режим
fork
или vfork
в
программе. Вызов fork
или vfork
создает новый процесс.
режим может быть:
parent
child
ask
show follow-fork-mode
fork
или
vfork
.
Если вы запрашиваете отладку дочернего процесса и за
vfork
следует exec
, GDB выполняет новую программу
до первой точки останова, установленной в ней. Если у вас была
установлена точка останова на функции main
в вашей исходной
программе, она будет также установлена на main
в
дочернем процессе.
Когда дочерний процесс порождается вызовом vfork
, вы не можете
отлаживать дочерний или родительский процесс до тех пор, пока не
завершится вызов exec
.
Если вы даете GDB команду run
после выполнения
exec
, новая программа стартует заново. Чтобы перезапустить
родительский процесс, используйте команду file
с именем
выполняемого файла родительской программы в качестве аргумента.
Вы можете использовать команду catch
, чтобы остановить
GDB, когда сделан вызов fork
, vfork
или
exec
. See section Установка точек перехвата.
Основные цели применения отладчика---остановка вашей программы до ее завершения, или чтобы в случае нарушений в работе вашей программы вы могли выяснить их причину.
Внутри GDB ваша программа может остановиться по нескольким
причинам, таким как сигнал, точка останова, или достижение новой строки
после команды GDB, такой как step
. Затем вы можете
исследовать и изменять значения переменных, устанавливать новые точки
останова и удалять старые, и затем продолжить выполнение. Обычно,
выводимые GDB сообщения предоставляют достаточную информацию о
состоянии вашей программы, но вы также можете запросить эту информацию
явно в любое время.
info program
Точка останова останавливает вашу программу всякий раз, когда ее
выполнение достигает определенной точки. Для каждой точки останова вы
можете добавлять условия для лучшего управления условиями остановки.
Вы можете устанавливать точки останова командой
break
и ее вариантами (see section Установка точек останова), чтобы задать место, где должна остановиться
ваша программа, по номеру строки, имени функции или точному адресу.
В конфигурациях HP-UX, SunOS 4.x, SVR4 и Alpha OSF/1, вы можете устанавливать
точки останова в разделяемых библиотеках до запуска выполняемого файла.
В системах HP-UX существует небольшое ограничение: вы должны подождать,
пока программа не перестанет выполняться, для установки точек
останова в подпрограммах из разделяемой библиотеки, которые не
вызываются напрямую из программы (например, подпрограммах, являющихся
аргументами вызова pthread_create
).
Точка наблюдения---это специальная точка останова, которая останавливает вашу программу при изменении значения выражения. Вы должны использовать другую команду для установки точки наблюдения (see section Установка точек наблюдения), но помимо этого, вы можете обращаться с ней так же, как с любой другой точкой останова: вы включаете, отключаете и удаляете точки останова и точки наблюдения при помощи одних и тех же команд.
Вы можете установить, что значения из вашей программы должны отображаться автоматически, когда GDB останавливается в точке останова. See section Автоматическое отображение.
Точка перехвата---это другая специализированная точка останова,
которая останавливает вашу программу при возникновении события
определенного типа, такого как выбрасывание исключения в Си++ или
загрузка библиотеки. Также как с точками наблюдения, вы используете
другую команду для установки точки перехвата, (see section Установка точек перехвата), но помимо этого, вы можете
обращаться с ней так же, как с любой другой точкой останова. (Для
остановки, когда ваша программа получает сигнал, используйте команду
handle
; смотрите section Сигналы.)
Когда вы создаете точку останова, наблюдения или перехвата, GDB присваивает ей номер; эти номера являются последовательными целыми числами, начинающимися с единицы. Во многих командах для управления различными возможностями точек останова, вы используете эти номера для указания, какую точку останова вы хотите изменить. Каждая точка останова может быть включена или отключена; если точка останова отключена, она не оказывает никакого влияния на вашу программу, пока вы снова не включите ее.
Некоторые команды GDB допускают в качестве указания точек останова, на которые они действуют, их диапазоны. Диапазон точек останова---это или номер одной точки, например `5', или два таких номера, в порядке увеличения, разделенные дефисом, например `5-7'. Когда команде задается диапазон точек останова, она действует на все точки останова в этом диапазоне.
Точки останова устанавливаются командой break
(сокращенно
b
). Вспомогательная переменная отладчика `$bpnum' хранит
номер последней установленной вами точки останова; смотрите
section Вспомогательные переменные, для
обсуждения того, что вы можете делать со вспомогательными переменными.
Вы можете задавать место для установки новой точки останова несколькими способами.
break функция
break +смещение
break -смещение
break номер-строки
break имя-файла:номер-строки
break имя-файла:функция
break *адрес
break
break
устанавливает точку останова на
инструкции, которая должна быть выполнена следующей в выбранном кадре
стека (see section Исследование стека). В любом выбранном кадре,
кроме самого внутреннего, это останавливает вашу программу, как только
управление возвращается в этот кадр. Это похоже на результат команды
finish
в кадре внутри выбранного кадра---за исключением того, что
finish
не оставляет активной точки останова. Если вы используете
break
без аргументов в самом внутреннем кадре, GDB
останавливается, когда в следующий раз достигает текущего места; это
может быть полезно внутри циклов.
Обычно GDB игнорирует точки останова, когда он возобновляет
выполнение, пока не будет выполнена хотя бы одна
инструкция. Если бы он этого не делал, вы не могли бы продолжать
выполнение после точки останова, не отключив сперва эту точку останова.
Это правило применяется вне зависимости от того, существовала или нет
точка останова, когда ваша программа остановилась.
break ... if усл
tbreak арг
break
, и точка останова
устанавливается аналогичным образом, но она автоматически уничтожается
после того, как ваша программа первый раз на ней остановится.
See section Отключение точек останова.
hbreak арг
break
, и точка
останова устанавливается аналогичным образом, но она требует аппаратной
поддержки и некоторые целевые платформы могут ее не иметь. Основной
целью этого является отладка кода EPROM/ROM, так что вы можете установить точку
останова на инструкции без изменения инструкции. Это может быть
использовано с новой генерацией ловушек, предоставляемой SPARClite DSU и
некоторыми машинами на базе x86. Эти платформы будут генерировать
ловушки, когда программа обращается к некоторым данным или адресу
инструкции, которые назначены регистрам отладки. Однако, регистры
аппаратных точек останова могут хранить ограниченное число точек
останова. Например, на DSU, только две точки останова могут быть
установлены одновременно, и GDB будет отвергать эту команду,
если используется больше. Удалите или отключите неиспользуемые
аппаратные точки останова перед установкой новых (see section Отключение точек останова). See section Условия останова.
thbreak арг
hbreak
, и точка останова устанавливается
аналогичным образом. Однако, как в случае команды tbreak
, точка
останова автоматически уничтожается после того, как программа первый раз
на ней остановится. Также, как и в случае команды hbreak
,
точка останова требует аппаратной поддержки и некоторые аппаратные
платформы могут ее не иметь. See section Отключение точек останова. Смотрите также section Условия останова.
rbreak рег-выр
break
. Вы можете удалять их, отключать,
или делать их условными таким же способом, как любые другие точки
останова.
Регулярные выражения имеют стандартный синтаксис, используемый такими
средствами, как `grep'. Заметьте, что это отличается от
синтаксиса, используемого оболочками; так, например, foo*
подходит для всех функций, которые включают fo
, за которым
следует любое число букв o
. Существует неявное .*
в
начале и в конце введенного вами регулярного выражения, так что для
нахождения только тех функций, которые начинаются на foo
,
используйте ^foo
.
При отладке программ, написанных на Си++, rbreak
полезна для
установки точек останова на перегруженных функциях, не являющихся
членами никакого специального класса.
info breakpoints [n]
info break [n]
info watchpoints [n]
info break
показывает условие на
строке, следующей за этой точкой; команды точки останова, если они есть,
перечисляются после этого.
info break
с номером точки останова n в качестве аргумента
отображает только эту точку. Вспомогательная переменная $_
и
адрес по умолчанию для исследования для команды x
устанавливаются
равными адресу последней из перечисленных точек останова (see section Исследование памяти).
info break
отображает то число раз, которое точка останова была
активирована. Это особенно полезно при использовании вместе с командой
ignore
. Вы можете игнорировать большое число активаций точки
останова, посмотреть информацию о точке останова чтобы узнать, сколько
раз она активировалась, и затем запустить заново, игнорируя на единицу
меньше, чем это число. Это быстро приведет вас к последней активации
этой точки останова.
GDB позволяет вам установить любое число точек останова в одном и том же месте вашей программы. В этом нет ничего глупого или бессмысленного. Когда точки останова являются условными, это даже полезно (see section Условия останова).
GDB сам иногда устанавливает точки останова в вашей программе
для специальных целей, таких как правильная обработка longjmp
(в
программах на Си). Этим внутренним точкам останова присваиваются
отрицательные номера, начиная с -1
; `info breakpoints' не
отображает их.
Вы можете увидеть эти точки останова с помощью служебной команды GDB `maint info breakpoints'.
maint info breakpoints
breakpoint
watchpoint
longjmp
longjmp
.
longjmp resume
longjmp
.
until
until
.
finish
finish
.
shlib events
Вы можете использовать точку наблюдения для остановки выполнения, как только изменится значение какого-либо выражения, не предсказывая конкретное место, где это может произойти.
В зависимости от вашей системы, точки наблюдения могут быть реализованы программно или аппаратно. GDB осуществляет программную реализацию точек наблюдения путем пошагового выполнения вашей программы и проверки значения переменной на каждом шаге, что в сотни раз медленнее нормального выполнения. (Но тем не менее это может стоить того, найти ошибку в программе, когда вы не представляете, в какой ее части она находится, может быть очень нелегко.)
В некоторых системах, таких как HP-UX, Linux и некоторых других платформах, базирующихся на x86, GDB включает поддержку для аппаратных точек наблюдения, которые не замедляют выполнение вашей программы.
watch выраж
rwatch выраж
awatch выраж
info watchpoints
info break
.
Когда это возможно, GDB устанавливает аппаратную точку наблюдения. Аппаратные точки наблюдения выполняются очень быстро, и отладчик сообщает об изменении величины точно в месте инструкции, где это изменение произошло. Если GDB не может установить аппаратную точку наблюдения, он устанавливает программную точку наблюдения, которая выполняется намного медленнее и сообщает об изменении величины на следующем операторе, а не инструкции, после появления изменения.
Когда вы даете команду watch
, GDB сообщает
Hardware watchpoint номер: выраж
если ему удалось установить аппаратную точку наблюдения.
В настоящее время, команды awatch
и rwatch
могут
устанавливать только аппаратные точки наблюдения, так как доступы к данным,
которые не изменяют величины наблюдаемого выражения, не могут быть
замечены без исследования каждой инструкции во время ее выполнения, а
GDB пока этого не делает. Если GDB обнаруживает, что
не может установить аппаратную точку останова командами awatch
или rwatch
, он напечатает сообщение, аналогичное этому:
Expression cannot be implemented with read/access watchpoint.(6)
Иногда GDB не может установить аппаратную точку наблюдения из-за того, что тип данных наблюдаемого выражения занимает больше места, чем допускает аппаратная точка наблюдения на целевой платформе. Например, некоторые системы позволяют наблюдать за областями, занимающими до 4 байт; на таких системах вы не можете устанавливать аппаратные точки наблюдения за выражениями, которые в результате дают число с плавающей точкой двойной точности (которое обычно занимает 8 байт). В качестве одного из решений, можно разбить большую область на несколько меньших областей, и затем наблюдать за каждой из них с помощью отдельной точки наблюдения.
Если вы установите слишком много аппаратных точек наблюдения, GDB может быть не в состоянии задействовать их все, когда вы возобновите выполнение вашей программы. Так как точное количество активных точек наблюдения неизвестно до того момента, когда ваша программа должна возобновить выполнение, GDB может быть не в состоянии предупредить вас об этом, когда вы устанавливаете точку наблюдения, и предупреждение будет напечатано только когда программа возобновит выполнение:
Hardware watchpoint номер: Could not insert watchpoint(7)
Если это происходит, удалите или отключите некоторые точки наблюдения.
SPARClite DSU будет генерировать ловушки, когда программа обращается к
некоторым данным или адресу инструкции, которые отведены для отладочных
регистров. Для адресов данных, DSU упрощает команду watch
.
Однако, аппаратные регистры точек останова могут принять только две
точки наблюдения за данными, и обе точки наблюдения должны быть одного
типа. Например, вы можете установить две точки наблюдения с помощью
команды watch
, две с помощью команды rwatch
, или
две с помощью команды awatch
, но вы не можете установить одну
точку наблюдения с помощью одной команды, а другую с помощью другой.
GDB не примет команду, если вы попытаетесь смешать различные
точки наблюдения. Удалите или отключите неиспользуемые точки наблюдения
перед установкой новых.
Если вы вызываете функцию интерактивно, используя print
или
call
, все установленные вами точки наблюдения будут неактивными,
до тех пор пока GDB не достигнет точки останова другого типа,
или пока вызов не завершится.
GDB автоматически удаляет точки наблюдения, которые наблюдают
за локальными переменными, или за выражениями, которые используют такие
переменные, когда они выходят из области видимости, то есть когда
выполнение покидает блок, в котором эти переменные были определены. В
частности, когда отлаживаемая программа завершается, все
локальные переменные выходят из области видимости, и таким образом
остаются установленными только те точки наблюдения, которые наблюдают за
глобальными переменными. Если вы снова запустите программу, вы должны
будете заново установить все такие точки наблюдения. Одним из способов
сделать это будет установить точку останова на входе в функцию
main
, и, когда программа остановится, установить все точки
наблюдения.
Предупреждение: В многонитевых программах точки наблюдения являются лишь частично полезными. С текущей реализацией точек наблюдения, GDB может наблюдать только за величиной выражения в одной нити. Если вы уверены, что выражение может измениться только вследствие действий внутри текущей нити (и если вы также уверены, что никакая другая нить не может стать текущей), то вы можете использовать точки наблюдения как обычно. Однако, GDB может не заметить, когда действия в не текущей нити изменяют выражение.
Предупреждение для HP-UX: В многонитевых программах, программные точки наблюдения являются лишь частично полезными. Если GDB создает программную точку наблюдения, она может наблюдать только за величиной выражения в одной нити. Если вы уверены, что выражение может измениться только вследствие действий внутри текущей нити (и если вы также уверены, что никакая другая нить не может стать текущей), то вы можете использовать программные точки наблюдения как обычно. Однако, GDB может не заметить, когда действия в не текущей нити изменяют выражение. (Аппаратные же точки наблюдения напротив, наблюдают за выражением во всех нитях.)
Вы можете использовать точки перехвата, чтобы вызвать остановку
отладчика в ответ на определенные типы событий в программе, такие как
исключения в Си++ или загрузка разделяемой библиотеки. Для установки
точки перехвата используйте команду catch
.
catch событие
throw
catch
exec
exec
. В настоящее время это доступно только на HP-UX.
fork
fork
. В настоящее время это доступно только на HP-UX.
vfork
vfork
. В настоящее время это доступно только на HP-UX.
load
load имя-библ
unload
unload имя-библ
tcatch событие
Используйте команду info break
для получения списка текущих точек
перехвата.
В настоящее время, в GDB существуют некоторые ограничения на
обработку исключений Си++ (catch throw
и catch catch
):
Иногда catch
не является лучшим способом отладки обработки
исключений: если вам необходимо точно знать, где исключение возбуждено,
то лучше остановиться до того, как вызван обработчик исключения,
так как в этом случае вы можете увидеть стек до того, как произойдет
какое-либо развертывание.
Если вместо этого вы установите точку останова в обработчике исключений,
то может быть нелегко определить, где исключение было возбуждено.
Для остановки сразу перед вызовом обработчика исключений, вам необходимы
некоторые знания о реализации. В случае GNU Си++, исключения
возбуждаются путем вызова библиотечной функции __raise_exception
,
которая имеет следующий интерфейс ANSI Си:
/* addr -- где хранится идентификатор исключения. id -- идентификатор исключения. */ void __raise_exception (void **addr, void *id);
Для того, чтобы отладчик перехватывал все исключения до того, как
произойтет развертывание стека, установите точку останова на
__raise_exception
(see section Точки останова, точки наблюдения и точки перехвата).
С помощью условных точек останова (see section Условия останова), зависящих от величины id, вы можете остановить вашу программу, когда возбуждается определенное исключение. Вы можете использовать несколько условных точек останова, чтобы остановить программу, когда возбуждается любое из нескольких исключений.
Часто бывает необходимо уничтожить точку останова, наблюдения или перехвата, когда она сделала свое дело и вы больше не хотите останавливать там свою программу. Это называется уничтожением точки останова. Точка останова, которая была уничтожена, более не существует; она забыта.
С помощью команды clear
вы можете удалять точки останова в
соответствии с тем, где они находятся в вашей программе. С помощью
команды delete
вы можете удалять отдельные точки останова,
наблюдения или перехвата, указывая их номера.
Не обязательно удалять точку останова, чтобы продолжить выполнение после нее. GDB автоматически игнорирует точки останова на первой инструкции, которая должна быть выполнена, когда вы продолжаете исполнение без изменения адреса выполнения.
clear
clear функция
clear имя-файла:функция
clear номер-строки
clear имя-файла:номер-строки
delete [breakpoints] [диапазон...]
set confirm off
). Вы можете сократить это команду
как d
.
Вместо того, чтобы удалять точку останова, наблюдения или перехвата, вам может быть удобнее отключить ее. Это делает точку останова бездействующей, как если бы она была удалена, но информация о ней запоминается, так что вы можете позже включить ее снова.
Вы отключаете и включаете точки останова, наблюдения и перехвата
командами enable
и disable
, возможно указывая один или
более номеров точек останова в качестве аргументов. Используйте
info break
или info watch
для распечатки списка точек
останова, наблюдения и перехвата, если вы не знаете какие номера
использовать.
Точка останова, наблюдения или перехвата может находиться в одном из четырех состояний:
break
, изначально находится в таком состоянии.
tbreak
, изначально находится в этом состоянии.
Вы можете использовать следующие команды для включения или отключения точек останова, наблюдения и перехвата:
disable [breakpoints] [диапазон...]
disable
как dis
.
enable [breakpoints] [диапазон...]
enable [breakpoints] once диапазон...
enable [breakpoints] delete диапазон...
Кроме точек останова, установленных командой tbreak
(see section Установка точек останова),
установленные вами точки останова изначально включены; следовательно,
они становятся отключенными или включенными только когда вы используете
одну из вышеперечисленных команд. (Команда until
может
устанавливать и удалять свою собственную точку останова, но она не
изменяет состояние ваших других точек останова; см. section Продолжение и выполнение по шагам.)
Простейшая точка останова останавливает вашу программу каждый раз, когда управление достигает заданного места. Вы можете также указать условие для точки останова. Условие является просто булевым выражением в вашем языке программирования (see section Выражения). Точка останова с условием вычисляет выражение каждый раз, когда ваша программа достигает ее, и ваша программа остановится только в том случае, если условие истинно.
Это противоположно использованию утверждений для проверки правильности программы; в этом случае, вы хотите остановиться, когда утверждение нарушается---то есть, когда условие ложно. В Си, если вы хотите проверить утверждение, выраженное условием assert, вы должны установить условие `! assert' на соответствующей точке останова.
Условия также допускаются для точек наблюдения; вам они могут не понадобиться, так как точка наблюдения так или иначе контролирует значение выражения---но может оказаться проще, скажем, просто установить точку наблюдения на имя переменной и указать условие, проверяющее, является ли новое значение тем, которое нас интересует.
Условия останова могут иметь побочные эффекты, и даже могут вызывать функции в вашей программе. Это может быть полезным, например, для активации функций, которые запоминают продвижение выполнения вашей программы, или для использования ваших собственных функций печати для форматирования специальных структур данных. Результаты полностью предсказуемы, если нет другой включенной точки останова по тому же адресу. (В этом случае, GDB может сначала увидеть другую точку останова и остановить вашу программу программу без проверки условия первой точки останова.) Заметьте, что команды точек останова обычно более удобны и гибки, чем условия останова, для выполнения побочных эффектов, когда достигается точка останова (see section Команды точки останова).
Условия останова могут быть заданы в момент установки точки останова,
используя `if' в аргументах команды break
. See section Установка точек останова. Они могут быть также
изменены в любой момент с помощью команды condition
.
Вы также можете использовать ключевое слово if
с командой
watch
. Команда catch
не распознает ключевое слово
if
; condition
является единственным способом наложить
дальнейшие условия на точку перехвата.
condition номер выражение
condition
, GDB немедленно проверяет
выражение на синтаксическую корректность и для определения, что
символы в нем имеют объекты ссылки в контексте вашей точки останова.
Если выражение использует символы, не существующие в контексте
точки останова, GDB выведет сообщение об ошибке:
No symbol "foo" in current context.(8)Однако, GDB в действительности не вычисляет выражение в момент подачи команды
condition
(или команды, устанавливающей
точку останова с условием, такой как break if ...
).
See section Выражения.
condition номер
Специальным случаем условия для точки останова является остановка только когда точка останова была достигнута определенное число раз. Это настолько полезно, что существует специальный способ сделать это, используя счетчик игнорирования точки останова. Каждая точка останова имеет счетчик игнорирования, являющийся целым числом. Как правило, счетчик игнорирования равен нулю, и, следовательно, не производит никакого действия. Но если ваша программа достигает точки останова, чей счетчик игнорирования положителен, тогда вместо того чтобы остановиться, она лишь уменьшит его на единицу и продолжит выполнение. В результате, если величина счетчика игнорирования равна n, точка останова не остановит программу следующие n раз, когда программа его достигнет.
ignore номер значение
continue
для возобновления выполнения вашей
программы от точки останова, вы можете установить счетчик игнорирований
непосредственно как аргумент к continue
, а не использовать
ignore
. See section Продолжение и выполнение по шагам.
Если точка останова имеет положительный счетчик игнорирований и условие,
то условие не проверяется. Как только счетчик игнорирований достигнет
нуля, GDB возобновит проверку условия.
Вы можете достигнуть эффекта счетчика игнорирований с помощью такого
условия, как `$foo-- <= 0', используя вспомогательную
переменную отладчика, которая уменьшается каждый раз.
See section Вспомогательные переменные.
Счетчики игнорирований можно использовать с точками останова, точками наблюдения и точками перехвата.
Вы можете подать любой точке останова (наблюдения или перехвата) ряд команд, которые будут выполняться при остановке вашей программы на этой точке останова. Например, вы можете захотеть вывести значения определенных выражений, или включить другие точки останова.
commands [номер]
... список-команд ...
end
end
.
Чтобы удалить все команды от точки останова, введите commands
и
немедленно за этим end
, то есть задайте пустой список команд.
Без аргумента номер, commands
относится к последней
установленной точке останова, наблюдения или перехвата (но не к
последней встреченной).
Нажатие RET, как средство повторения последней команды GDB, отключено внутри списка-команд.
Вы можете использовать команды для точки останова, чтобы снова запустить
вашу программу на выполнение. Просто используйте команду continue
, или
step
, или любую другую команду, возобновляющую выполнение.
После команды, возобновляющей выполнение, любые другие команды в списке
игнорируются. Так сделано потому, что каждый раз, когда вы
возобновляете выполнение (даже просто с помощью next
или
step
), вы можете встретить другую точку останова---которая может
иметь свой собственный список команд, что приведет к неоднозначности,
какой из списков выполнять.
Если в качестве первой команды в списке команд вы укажете silent
,
обычное сообщение об остановке на точке останова не будет выводиться.
Это может быть желательно для точек останова, которые должны вывести
определенное сообщение, и затем продолжить выполнение. Если никакая из
оставшихся команд ничего не выводит, вы не увидите никакого знака о том,
что точка останова была достигнута. silent
имеет смысл только в
начале списка команд точки останова.
Команды echo
, output
и printf
позволяют вам
более точно контролировать выводимый текст, и часто полезны в "тихих"
точках останова. See section Команды для управляемого вывода.
Например, вот как вы можете использовать команды точки останова для
вывода величины x
на входе в foo
, когда x
положительна.
break foo if x>0 commands silent printf "x is %d\n",x cont end
Одним из применений команд точки останова является компенсация одной
ошибки, так, чтобы вы могли искать другую. Поместите точку останова
сразу после строки кода, содержащей ошибку, задайте ей условие для
определения случая, в котором было сделано что-то ошибочное, и
определите команды для присвоения правильных значений тем переменным,
для которых это требуется. Закончите командой continue
, чтобы
ваше программа не останавливалась, а начните с команды silent
,
чтобы не было никакого вывода. Вот пример:
break 403 commands silent set x = y + 4 cont end
Некоторые языки программирования (особенно Си++) допускают, чтобы одно и
то же имя функции было определено несколько раз, для применения в
различных контекстах. Это называется перегрузкой. Когда имя
функции перегружается, `break функция' не достаточно, чтобы
указать GDB, где вы хотите установить точку останова.
Если вы столкнулись с этой проблемой, вы можете использовать что-то типа
`break функция(типы)' для указания, какую конкретную
версию функции вы имеете в виду. В противном случае, GDB
предлагает вам выбор из пронумерованных вариантов для различных
возможных точек останова, и ждет вашего выбора с приглашением
`>'. Первыми двумя вариантами всегда являются `[0] cancel'
и `[1] all'. Ввод 1 устанавливает точку останова на каждом
определении функции, и ввод 0 прерывает команду break
без установки новых точек останова.
Например, следующая выдержка из сеанса иллюстрирует попытку установить
точку останова на перегруженном символе String::after
. Мы
выбрали три конкретных определения имени функции:
(gdb) b String::after [0] cancel [1] all [2] file:String.cc; line number:867 [3] file:String.cc; line number:860 [4] file:String.cc; line number:875 [5] file:String.cc; line number:853 [6] file:String.cc; line number:846 [7] file:String.cc; line number:735 > 2 4 6 Breakpoint 1 at 0xb26c: file String.cc, line 867. Breakpoint 2 at 0xb344: file String.cc, line 875. Breakpoint 3 at 0xafcc: file String.cc, line 846. Multiple breakpoints were set. Use the "delete" command to delete unwanted breakpoints. (gdb)
В некоторых операционных системах точки останова не могут быть использованы в программе, если какой-либо другой процесс выполняет эту программу. В этом случае, попытка выполнить или продолжить выполнение программы с точкой останова приводит тому, что GDB печатает сообщение об ошибке:
Cannot insert breakpoints. The same program may be running in another process.(9)
Когда это происходит, у вас есть три варианта дальнейших действий:
exec-file
для указания, что GDB
должен выполнять вашу программу под этим именем. Затем запустите вашу
программу снова.
Аналогичное сообщение может выводиться, если вы запрашиваете слишком много активных аппаратно-поддерживаемых точек останова и наблюдения:
Stopped; cannot insert breakpoints. You may have requested too many hardware breakpoints and watchpoints.(10)
Это сообщение выводится, когда вы пытаетесь возобновить выполнение программы, так как только тогда GDB знает точно, сколько аппаратных точек останова и наблюдения ему нужно установить.
Когда это сообщение выводится, вам необходимо отключить или удалить некоторые аппаратно-поддерживаемые точки останова и наблюдения, и затем продолжить.
Продолжение означает возобновление выполнения программы до ее
нормального завершения. Напротив, пошаговое выполнение означает
выполнение еще одного "шага" вашей программы, где "шаг" быть либо
одной строкой исходного кода, либо одной машинной инструкцией (в
зависимости от того, какую именно команду вы используете). И в
случае продолжения, и в случае выполнения по шагам, ваша программа
может остановиться и раньше, вследствие точки останова или сигнала.
(Если она останавливается по сигналу, вы можете использовать
handle
, или `signal 0' для возобновления выполнения.
See section Сигналы.)
continue [счетчик-игнор]
c [счетчик-игнор]
fg [счетчик-игнор]
ignore
(see section Условия останова).
Аргумент счетчик-игнор имеет смысл только если ваша программа
остановилась в точке останова. В остальных случаях, аргумент к
continue
игнорируется.
Синонимы c
и fg
(от foregroung, так как отлаживаемая
программа считается фоновой), предоставляются исключительно для
удобства, и имеют в точности тот же смысл, что и continue
.
Чтобы возобновить выполнение с другого места, вы можете использовать
return
(see section Возврат из функции) чтобы вернуться
назад к вызывающей функции; или jump
(see section Продолжение исполнения с другого адреса) для перехода к произвольному месту в
вашей программе.
Типичная техника для использования пошагового выполнения заключается в установке точки останова (see section Точки останова, точки наблюдения и точки перехвата) на начале функции или раздела вашей программы, где предположительно находится ошибка, выполнении вашей программы до остановки на этой точке останова, и затем пошаговом выполнении подозреваемого участка, с исследованием интересуемых переменных, пока вы не увидите, что случилась ошибка.
step
s
.
КомандаПредупреждение: Если вы используете команду
step
, когда управление находится внутри функции, которая была скомпилирована без отладочной информации, выполнение продолжается, пока управление не достигнет функции, которая имеет ее. Аналогично, пошаговое выполнение не будет заходить в функцию, скомпилированную без отладочной информации. Для пошагового выполнения таких функций используйте командуstepi
, описанную ниже.
step
останавливается только на первой инструкции строки
исходного текста. Это предотвращает множественные остановки, которые
в противном случае могут возникнуть в операторе switch
, цикле
for
, и так далее. step
продолжает останавливаться, если
функция, имеющая отладочную информацию, вызывается внутри строки.
Другими словами, step
заходит внутрь функций, вызываемых в
данной строке.
Также, команда step
входит в функцию только если для нее существует
информация о номерах строк. Иначе она действует как команда
next
. Это позволяет избежать проблем, появляющихся при
использовании cc -gl
на машинах MIPS. Раньше step
заходила в подпрограмму, если существовала хоть какая-нибудь отладочная
информация о подпрограмме.
step число
step
, но делает это
число раз. Если достигается точка останова, или приходит
сигнал, не связанный с пошаговым выполнением, до выполнения числа
шагов, пошаговое выполнение сразу останавливается.
next [число]
step
, но вызовы
функций, которые появляются внутри строки кода, выполняются без
остановки. Выполнение останавливается, когда управление достигает другой
строки кода в исходном уровне стека, который выполнялся, когда вы дали
команду next
. Эта команда сокращается как n
.
Аргумент число является счетчиком повторений, как для step
.
Команда next
останавливается только на первой инструкции исходной
строки. Это предотвращает множественные остановки, которые
иначе могут возникнуть в операторах switch
, циклах for
, и
так далее.
finish
return
(see section Возврат из функции).
until
u
next
, за исключением
того, что когда until
встречает переход, она автоматически
продолжает выполнение, пока счетчик выполнения программы не станет
больше, чем адрес перехода.
Это означает, что когда вы достигаете конца цикла после его выполнения по
шагам, until
продолжает выполнение вашей программы, пока она не
выйдет из цикла. Напротив, команда next
в конце цикла просто
переходит назад в начало цикла, что заставляет вас выполнять по
шагам следующую итерацию.
until
всегда останавливает вашу программу, если она пытается выйти
из текущего кадра стека.
until
может привести к несколько неожиданным результатам, если
порядок машинных кодов не совпадает с порядком строк исходного текста.
Например, в следующем отрывке сеанса отладки, команда f
(frame
) показывает, что выполнение остановилось на строке
206
; хотя, когда мы используем until
, мы переходим к строке
195
:
(gdb) f #0 main (argc=4, argv=0xf7fffae8) at m4.c:206 206 expand_input(); (gdb) until 195 for ( ; argc > 0; NEXTARG) {Это произошло потому, что для эффектвности выполнения компилятор сгенерировал код для проверки окончания цикла в конце, а не в начале цикла---даже если проверка в цикле
for
Си написана до тела
цикла. Кажется, что команда until
переместилась назад к началу
цикла, когда двигалась к этому выражению; однако, в действительности она
не переходила к более раннему оператору---в терминах фактического
машинного кода.
until
без аргументов работает посредством пошагового выполнения
отдельных инструкций, и, следовательно, является более медленной, чем
until
с аргументом.
until положение
u положение
break
(see section Установка точек останова). Эта форма команды использует точки останова, и,
следовательно, является более быстрой, чем until
без аргумента.
stepi
stepi арг
si
step
.
nexti
nexti арг
ni
next
.
Сигнал---это асинхронное событие, которое может произойти в программе.
Операционная система определяет возможные типы сигналов и дает каждому
типу имя и номер. В Unix, например, SIGINT
---это сигнал, получаемый
программой, когда вы вводите знак прерывания (часто C-c);
SIGSEGV
---сигнал, получаемый программой при ссылке на область
памяти, отличную от всех используемых областей; SIGALRM
появляется
при срабатывании интервального таймера (возникает только, если ваша
программа запросила временной сигнал).
Некоторые сигналы, такие как SIGALRM
, являются обычной частью
функционирования вашей программы. Другие, такие как SIGSEGV
,
обозначают ошибки; эти сигналы являются фатальными (они немедленно
убивают вашу программу), если программа не определила заранее другой
способ их обработки. SIGINT
не указывает на ошибку в вашей
программе, но обычно является фатальным, так что он может выполнять
функцию прерывания: убить программу.
GDB способен обнаружить любое появление сигнала в вашей программе. Вы можете заранее сообщить GDB, что делать для каждого типа сигнала.
Обычно, GDB установлен так, чтобы игнорировать неошибочные сигналы,
такие как SIGALRM
(чтобы не мешать их действию при исполнении вашей
программы), но немедленно останавливать вашу программу всякий раз, когда
возникает сигнал об ошибке. Вы можете изменить эти установки командой
handle
.
info signals
info handle
info handle
является синонимом для info signals
.
handle сигнал ключевые-слова...
Ключевые слова, допускаемые командой handle
, могут быть
сокращены. Вот их полные имена:
nostop
stop
print
.
print
noprint
nostop
.
pass
nopass
Когда сигнал останавливает вашу программу, он невидим для нее,
пока вы не продолжите выполнение. Затем ваша программа видит
сигнал, если в данный момент на рассматриваемый сигнал
распространяется действие команды pass
. Другими словами, после
того, как GDB сообщит о сигнале, вы можете использовать команду
handle
c pass
или nopass
, чтобы
указать, должна ли ваша программа увидеть этот сигнал при продолжении.
Вы также можете использовать команду signal
для того, чтобы
помешать вашей программе увидеть сигнал или, наоборот, заставить ее
заметить обычно игнорируемый сигнал, или чтобы подать ей произвольный
сигнал в любое время. Например, если ваша программа остановилась
вследствие какой-либо ошибки обращения к памяти, вы можете сохранить
правильные значения в ошибочные переменные и продолжить выполнение, в
надежде посмотреть на дальнейшее выполнение, но ваша программа вероятно
немедленно остановилась бы из-за фатального сигнала, как только она бы
его заметила. Чтобы помешать этому, вы можете продолжить выполнение с
`signal 0'. See section Подача сигнала вашей программе.
Когда ваша программа имеет несколько нитей выполнения (see section Отладка программ с несколькими нитями), вы можете выбрать, установить точки останова либо во всех, либо в каких-то отдельных нитях.
break ном-строки thread номер-нити
break ном-строки thread номер-нити if ...
thread
для условных
точек останова; в этом случае, поместите `thread номер-нити'
перед условием точки останова, вот так:
(gdb) break frik.c:13 thread 28 if bartab > lim
При любой остановке вашей программы под управлением GDB, прекращается выполнение всех нитей, а не только текущей. Это позволяет вам исследовать полное состояние программы, включая переключение между нитями, не опасаясь, что это может изменить что-либо в дальнейшем.
Наоборот, когда вы снова запускаете программу, все нити
начинают выполняться. Это верно даже при пошаговом выполнении
такими командами, как step
или next
.
В частности, GDB не может пошагово выполнять все нити параллельно. Так как планированием выполнения нити занимается операционная система отлаживаемой цели (не контролируемая GDB), то пока в текущей нити выполняется один шаг, в других может выполниться несколько. Более того, когда выполнение программы останавливается, другие потоки вообще могут остановиться в середине операторов, а не на границе между ними.
Вы даже можете обнаружить, что после продолжения исполнения или после пошагового выполнения ваша программа остановилась в другой нити. Это случается всякий раз, когда другая нить достигает точки останова, получает сигнал или в ней возникает исключительная ситуация, прежде чем первая нить завершает выполнение того, что вы запросили.
В некоторых операционных системах вы можете заблокировать планировщик заданий и тем самым позволить выполняться только одной нити.
set scheduler-locking режим
off
, то блокировки нет и любая нить может выполняться в любое
время. Если этот режим установлен в on
, то только текущая нить
может выполняться, когда выполнение продолжается.
Режим step
производит оптимизацию для пошагового выполнения. Он
не дает другим нитям "захватывать приглашение" путем приоритетного
прерывания обслуживания текущей нити во время пошагового выполнения.
Другие нити едва ли получат возможность начать выполнение, когда вы
выполняете очередной шаг. С большей вероятностью они начнут выполняться,
когда вы выполняете команду next
на вызове функции, и им не что
не помешает выполняться, когда вы используете такие команды, как
`continue', `until' или `finish'. Однако, если другие
нити не достигнут точки останова в течение отведенного ему для
выполнения времени, они никогда не перехватят приглашение GDB у
отлаживаемой вами нити.
show scheduler-locking
Когда ваша программа остановилась, первое, что вам нужно знать---где она остановилась и как она туда попала.
Каждый раз, когда ваша программа производит вызов функции, о нем создается определенная информация. Она включает положение вызова в вашей программе, параметры вызова и локальные переменные вызываемой функции. Информация сохраняется в блоке данных, называемом кадром стека. Кадры стека размещаются в области памяти, называемой стеком вызовов.
Команды GDB для исследования стека позволяют вам увидеть всю эту информацию при остановке вашей программы.
Один из кадров стека является выбранным GDB, и многие команды GDB неявно относятся к нему. В частности, когда вы запрашиваете у GDB значение переменной вашей программы, это значение находится в выбранном кадре. Для выбора интересующего вас кадра существуют специальные команды GDB. See section Выбор кадра.
Когда ваша программа останавливается, GDB автоматически
выбирает текущий выполняющийся кадр и выдает его краткое описание,
аналогично команде frame
(see section Информация о кадре стека).
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
без аргументов выводит десять
строк, расположенных вокруг точки выполнения в кадре.
See section Вывод строк исходного текста.
up-silently n
down-silently n
up
и down
соответственно,
отличаясь от них тем, что делают свою работу "тихо", не отображая новый
кадр. Они предназначены для использования в основном в
командных сценариях GDB, где вывод может быть ненужным и
отвлекающим.
Существуют несколько других команд для вывода информации о выбранном кадре стека.
frame
f
f
. С аргументом, эта команда
используется для выбора кадра стека.
See section Выбор кадра.
info frame
info f
info frame адрес
info f адрес
frame
(для некоторых архитектур
не один, а несколько).
See section Выбор кадра.
info args
info locals
info catch
up
, down
или
frame
); затем наберите info catch
.
See section Установка точек перехвата.
GDB может выводить части исходных текстов вашей программы, так как отладочная информация, записанная в ней, сообщает GDB, какие исходные файлы использовались при создании программы. Когда ваша программа останавливается, GDB сам выводит строку, на которой она остановилась. Аналогично, когда вы выбираете кадр стека (see section Выбор кадра), GDB выводит строку, на которой остановилось выполнение в этом кадре. Вы можете выводить другие части исходных файлов с помощью явных команд.
Если вы используете GDB через интерфейс к GNU Emacs, вы можете предпочесть воспользоваться средствами Emacs для просмотра исходных текстов; смотрите section Использование GDB под управлением GNU Emacs.
Чтобы вывести строки файла с исходным текстом, используйте команду
list
(сокращенно l
). По умолчанию выводятся десять строк.
Существует несколько способов определения того, какую часть файла вы хотите
вывести.
Здесь представлены наиболее употребительные формы команды list
:
list номер-строки
list функция
list
list
, то выводятся
строки, следующие за последними выведенными; если, однако,
последней выведенной строкой была одиночная строка, выведенная
как часть отображения кадра стека (see section Исследование стека),
то выводятся строки, расположенные вокруг нее.
list -
По умолчанию, для любой из этих форм команды list
GDB
выводит десять строк исходного текста. Вы можете изменить это
командой set listsize
:
set listsize число
list
строк в число
(если аргумент команды list
не задает явно какое-нибудь другое число).
show listsize
list
.
Повторение команды list
нажатием RET отбрасывает аргумент,
так что это эквивалентно вводу просто list
. Это полезнее, чем
вывод тех же самых строк снова. Исключение сделано для параметра
`-'; этот параметр сохраняется при повторе команды, так что каждое
повторение приводит к перемещению вверх по исходному файлу.
Обычно команда list
ожидает от вас ноль, один или два
указателя строк. Указатели строк определяют строки
исходного текста; существует несколько способов их задания, но
результат всегда заключается в задании строки исходного текста. Вот
полное описание возможных параметров команды list
:
list указ-стр
list перв,посл
list ,посл
list перв,
list +
list -
list
Ниже перечислены способы указания одиночной строки исходного текста---все виды указателей строк.
номер
list
задано два указателя
строк, это относится к тому же исходному файлу, что и первый указатель
строки.
+смещение
list
, имеющей два указателя,
задает строку, смещенную на смещение строк вниз относительно строки,
определенной первым указателем.
-смещение
имя-файла:номер
функция
имя-файла:функция
*адрес
Существуют две команды для поиска по регулярному выражению в текущем исходном файле.
forward-search рег-выраж
search рег-выраж
fo
.
reverse-search рег-выраж
rev
.
Исполняемые программы иногда не сохраняют имена каталогов, в которых находились исходные файлы, из которых они скомпилированы, а хранят лишь имена файлов. Даже если они их сохранили, каталоги могли быть перемещены в период между компиляцией и сеансом отладки. У GDB есть список каталогов для поиска исходных файлов; он называется путь для исходных файлов. Каждый раз, когда GDB требуется исходный файл, он перебирает по порядку все каталоги из этого списка, пока не находит файл с требуемым именем. Заметьте, что пути поиска исполняемых файлов для этой цели не используются, как не используется и текущий рабочий каталог, если только он не присутствует в пути для исходных файлов.
Если GDB не может найти исходный файл, используя путь для исходных файлов, а в объектном файле программы указан какой-либо каталог, GDB просматривает также и его. В последнюю очередь, если путь для исходных файлов пуст и запись о каталоге компиляции отсутствует, GDB просматривает текущий каталог.
При переустановке или переупорядочивании пути для исходных файлов, GDB очищает любую запомненную им информацию о том, где исходные файлы были найдены и о расположении строк в них.
Когда вы вызываете GDB, путь для исходных файлов
содержит только `cdir' и `cwd', в этом порядке. Для
добавления других каталогов, используйте команду directory
.
directory имя-каталога ...
dir имя-каталога ...
directory
show directories
Если ваш путь для исходных файлов перемешан с уже неиспользуемыми каталогами, GDB может иногда вызвать недоумение, найдя неправильный вариант исходного файла. Вы можете исправить ситуацию следующим образом:
directory
без параметров, чтобы очистить путь
поиска исходных файлов.
directory
с подходящими аргументами, чтобы
переустановить каталоги, которые вы хотите видеть в пути для исходных
файлов. Вы можете добавить все каталоги одной командой.
Вы можете использовать команду info line
, чтобы отобразить cтроки
исходного текста в программные адреса (и наоборот), и
команду disassemble
, чтобы вывести диапазон адресов в виде
машинных инструкций. При запуске в режиме GNU Emacs, команда
info line
выводит стрелку, указывающую на заданную строку.
Также info line
выводит адреса как в символьной форме, так и в
шестнадцатеричной.
info line указ-стр
list
(see section Вывод строк исходного текста).
Например, мы можем использовать info line
для определения
положения объектного кода первой строки функции
m4_changequote
:
(gdb) info line m4_changequote Line 895 of "builtin.c" starts at pc 0x634c and ends at 0x6350.
Мы также можем запросить (используя *адрес
как форму
задания указ-стр), какая строка исходного текста соответствует
определенному адресу:
(gdb) info line *0x63ff Line 926 of "builtin.c" starts at pc 0x63e4 and ends at 0x6404.
После info line
, адрес, используемый по умолчанию для команды
x
, меняется на начальный адрес строки, так что `x/i'
достаточно для начала исследования машинного кода (see section Исследование памяти). Этот адрес также сохраняется как значение
вспомогательной переменной $_
(see section Вспомогательные переменные).
disassemble
Следующий пример показывает результат дисассемблирования диапазона адресов кода HP PA-RISC 2.0:
(gdb) disas 0x32c4 0x32e4 Dump of assembler code from 0x32c4 to 0x32e4: 0x32c4 <main+204>: addil 0,dp 0x32c8 <main+208>: ldw 0x22c(sr0,r1),r26 0x32cc <main+212>: ldil 0x3000,r31 0x32d0 <main+216>: ble 0x3f8(sr4,r31) 0x32d4 <main+220>: ldo 0(r31),rp 0x32d8 <main+224>: addil -0x800,dp 0x32dc <main+228>: ldo 0x588(r1),r26 0x32e0 <main+232>: ldil 0x3000,r31 End of assembler dump.
Некоторые архитектуры имеют несколько широко используемых наборов мнемоник инструкций или другой синтаксис.
set disassembly-flavor набор-инструкций
disassemble
и x/i
.
В настоящее время, эта команда определена только для Intel x86. Вы
можете установить набор-инструкций в intel
или att
.
По умолчанию установлено att
, диалект AT&T используется по
умолчанию ассемблерами Unix на архитектурах, базирующихся на x86.
Для исследования данных в вашей программе обычно используется
команда print
(сокращенно p
) или ее синоним
inspect
. Она вычисляет и выводит значение выражения, записанного
на том же языке, что и ваша программа (see section Использование GDB с различными языками программирования).
print выраж
print /f выраж
print
print /f
Команда x
позволяет исследовать данные на более низком уровне. Она
исследует данные в памяти по указанному адресу и выводит их в
указанном формате. See section Исследование памяти.
Если вас интересует информация о типах или о том, как объявлены
поля структуры или класса, используйте команду ptype выраж
вместо print
. See section Исследование таблицы символов.
print
и многие другие команды GDB допускают в качестве
параметра выражение и вычисляют его значение. В выражении GDB
допустимо использование любого типа констант, переменных или операторов,
определенных в используемом вами языке программирования, включая
условные выражения, вызовы функций, приведение типов и строковые
постоянные. К сожалению, исключением являются символы, определенные
командами препроцессора #define
.
GDB поддерживает константы-массивы в выражениях, введенных
пользователем. Синтаксис следующий: {элемент,
элемент...}. Например, вы можете использовать команду
print {1, 2, 3}
, чтобы создать в памяти массив,
который будет доступен в программе так же, как выделенный функцией
malloc
.
По причине широкого распространения Си, большинство выражений в примерах этого руководства написаны на Си. See section Использование GDB с различными языками программирования, для информации об использовании выражений в других языках.
В этом разделе мы обсуждаем операторы, которые вы можете использовать в выражениях GDB независимо от используемого вами языка программирования.
Приведения типов поддерживается во всех языках, а не только в Си, так как бывает очень полезно преобразовать число в указатель, чтобы исследовать структуру, расположенную по этому адресу в памяти.
GDB поддерживает эти операторы, в дополнении к следующим, являющимися общими для языков программирования:
@
::
{тип} адрес
Чаще всего в качестве выражения используется имя переменной вашей программы.
Переменные в выражениях трактуются в контексте выбранного кадра стека (see section Выбор кадра); они могут быть либо
либо
Это означает, что в функции
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'), который тоже является эффективной формой представления отладочной информации. Смотрите section `Опции для отладки вашей программы или GNU CC' in Использование GNU CC, для дополнительной информации.
Часто бывает полезным вывести несколько объектов одного типа, расположенных в памяти последовательно; часть массива или динамический массив, для которого в программе существует только указатель.
Вы можете это сделать, обращаясь к непрерывному участку памяти как к искусственному массиву, используя бинарный оператор `@'. Левым операндом для `@' должен быть первый элемент желаемого массива, и он должен быть индивидуальным объектом. Правым операндом должна быть длина массива. Результатом операции будет массив, все элементы которого имеют тот же тип, что и левый аргумент. Первым элементом массива является левый аргумент; второй элемент формируется из байтов памяти, непосредственно следующих за байтами, содержащими первый элемент, и так далее. Например, если в программе есть строка
int *array = (int *) malloc (len * sizeof (int));
то вы можете вывести содержимое array
с помощью
p *array@len
Левый операнд операции `@' должен находиться в памяти. Значения массивов, полученных операцией `@', при индескации ведут себя точно так же, как и другие массивы, и приводятся к указателям при использовании в выражениях. Искусственные массивы чаще всего появляются в выражениях через историю значений (see section История значений), после вывода одного из них.
Другой способ создания искусственного массива---использование приведения типов. Оно заново интерпретирует значение так, как если бы оно было массивом. Значение не обязано находиться в памяти.
(gdb) p/x (short[2])0x12345678 $1 = {0x1234, 0x5678}
Если вы опускаете длину массива (как в `(тип[])значение'), GDB для удобства вычисляет его размер для заполнения значениями (как `sizeof(значение)/sizeof(тип)':
(gdb) p/x (short[])0x12345678 $2 = {0x1234, 0x5678}
Иногда механизма искусственных массивов бывает недостаточно;
в сравнительно сложных структурах данных, интересующие нас элементы могут
не быть смежными---например, если вас интересуют значения указателей в
массиве. Одно из полезных решений этой проблемы---использование
вспомогательной переменной (see section Вспомогательные переменные) в качестве счетчика в выражении, выводящем
первое интересующее нас значение, а затем повторять это выражение
нажатием 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
Например, чтобы вывести счетчик программы в шестнадцатеричном виде (see section Регистры), введите
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';
see section Регистры), в шестнадцатеричном виде (`x').
Так как все буквы, обозначающие размер единиц измерения, отличаются от букв, определяющих форматы вывода, вы не должны запоминать, формат или размер единиц измерений указывается раньше; это можно делать в любом порядке. Спецификации вывода `4xw' и `4wx' означают в точности одно и то же. (Однако, число n должно быть первым; `wx4' не сработает.)
Хотя размер единицы измерения u игнорируется для форматов `s'
и `i', тем не менее вы можете воспользоваться счетчиком повторений
n; например, `3i' указывает, что вы хотите вывести три
машинные инструкции, включая любые операнды. Команда disassemble
предоставляет альтернативный способ исследования машинных инструкций;
смотрите section Исходный текст и машинный код.
Все значения по умолчанию для аргументов команды 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'---это общее обозначение счетчика программы; see section Регистры).
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; они не являются частью вашей программы и установка вспомогательной переменной не оказывает непосредственного влияния на ее дальшейшее выполнение. Поэтому вы можете пользоваться ими совершенно свободно.
Имена вспомогательных переменных начинаются с `$'. Любое имя с приставкой `$' может использоваться для вспомогательной переменной, если только оно не является предопределенным машинно-зависимым именем регистра, (see section Регистры). (Ссылки на историю значений, напротив, есть числа, которым предшествует `$'. See section История значений.)
Вы можете сохранить значение во вспомогательной переменной с помощью выражения присваивания, как если бы вы устанавливали переменную в вашей программе. Например:
set $foo = *object_ptr
сохранит в $foo
значение объекта, на который указывает
object_ptr
.
Первое использование вспомогательной переменной создает ее, но
значением переменной будет void
, пока вы не присвоите ей новое.
С помощью другого присваивания вы можете в любое время
изменить значение.
Вспомогательные переменные не имеют фиксированного типа. Вы можете присваивать вспомогательной переменной значение любого типа, включая структуры и массивы, даже если у этой переменной уже было значение другого типа. Будучи использованной в выражении, вспомогательная переменная имеет тип своего текущего значения.
show convenience
show conv
.
Один из способов использования вспомогательных переменных---в качестве увеличивающегося счетчика или продвигающегося указателя. Например, чтобы напечатать поле из последовательных элементов массива структур:
set $i = 0 print bar[$i++]->contents
Повторяйте эту команду нажатием RET.
Некоторые вспомогательные переменные создаются GDB автоматически, и им присваиваются значения, которые вероятно могут оказаться полезными.
$_
$_
устанавливается автоматически командой x
в
последний исследованный адрес (see section Исследование памяти).
Другие команды, которые устанавливают адрес по умолчанию для
исследования командой 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
выводит данные в обоих
форматах.
Обычно значения регистров относятся к выбранному кадру стека (see section Выбор кадра). Это значит, что вы получаете значение, которое содержалось бы в регистре, если бы произошел выход из всех внутренних кадров стека и их сохраненные регистры были бы восстановлены. Для того чтобы увидеть истинное содержимое аппаратных регистров, вы должны выбрать самый внутренний кадр (с помощью `frame 0').
Однако, GDB, исходя из машинного кода, сгенерированного вашим компилятором, должен установить, где сохранены регистры. Если некоторые регистры не сохранены, или если GDB не в состоянии найти сохраненные регистры, выбранный кадр стека не имеет значения.
В зависимости от конфигурации, GDB может выдать вам больше информации о состоянии аппаратных средств поддержки вычислений с плавающей точкой.
info float
Хотя языки программирования обычно имеют общие аспекты, их выражения редко
выглядят одинаково. Например, в ANSI Си, разыменование указателя
p
осуществляется операцией *p
, а в Модуле-2 это
выполняется как p^
. Представление (и отображение) значений также
может быть различным. Шестнадцатеричные числа в Си отображаются как
`0x1ae', в то время как в Модуле-2 они отображаются как `1AEH'.
В GDB встроена специальная информация о некоторых языках, которая позволяет описывать действия, подобные упомянутым, на языке вашей программы, и позволяет GDB выводить значения в виде, принятом в языке, на котором написана ваша программа. Язык, которым вы пользуетесь для построения выражений, называется рабочим языком.
Существует два способа управления рабочим языком: либо GDB
устанавливает его автоматически, либо вы можете сделать это
самостоятельно. Для этих целей вы можете воспользоваться командой set
language
. По умолчанию, при старте GDB устанавливает язык
автоматически. Рабочий язык используется чтобы определить, как
интерпретируются вводимые вами выражения, как выводятся значения, и так
далее.
В дополнение к рабочему языку, каждый исходный файл, с
которым работает GDB, имеет свой собственный рабочий язык. Для
некоторых форматов объектных файлов компилятор может указывать, на
каком языке написан конкретный исходный файл. Однако, чаще всего
GDB распознает язык по имени файла. Язык исходного файла
определяет, будут ли восстанавливаться имена Си++; таким образом,
backtrace
может показывать каждый кадр в соответствии с
исходным языком. Не существует способа установить язык исходного файла
из GDB, но вы можете установить язык, ассоциированный с
расширением файла. See section Отображение языка программирования.
Наиболее часто эта проблема возникает, когда вы используете программу,
такую как cfront
или f2c
, которая создает текст на Си, но
написана на другом языке. В этом случае нужно сделать, чтобы программа
использовала директивы #line
в выводе текста Си; тогда
GDB будет знать правильный язык исходного текста первоначальной
программы, и выведет этот исходный код, а не сгенерированный код Си.
Если имя исходного файла заканчивается одним из следующих расширений, то GDB воспринимает это как указание на обозначенный язык.
В дополнение к этому, вы можете установить язык, ассоциированный с расширением имени файла. See section Отображение языка программирования.
Если вы позволяете GDB устанавливать язык автоматически, выражения в сеансе отладки и в вашей программе интерпретируются одинаково.
По желанию, вы можете установить язык сами. Для этого
воспользуйтесь командой `set language язык', где
язык---название языка, например, c
или modula-2
.
Чтобы получить перечень поддерживаемых языков, наберите `set language'.
Установка языка вручную запрещает GDB автоматически переключать рабочий язык. Это может привести к неприятным последствиям, если вы попытаетесь отладить программу, когда рабочий язык не совпадает с исходным языком, когда выражение допустимо в обоих языках, но означает разные вещи. Например, если текущий исходный файл написан на Си, а в GDB выбрана Модула-2, команда
print a = b + c
может не привести к ожидаемому результату. В Си это означает
сложить b
и c
и поместить результат в a
.
Выведенным результатом будет значение a
. В Модуле-2 это
означает сравнение a
с результатом b+c
, выдающее значение
типа BOOLEAN
.
Для автоматической установки GDB рабочего языка, используйте `set language local' или `set language auto'. Тогда GDB будет определять рабочий язык автоматически. То есть при остановке вашей программы в кадре стека (обычно, в точке останова), GDB устанавливает рабочий язык в тот, который записан для функции в этом кадре. Если язык для кадра неизвестен (то есть, если функция или блок, соответствующие кадру, были определены в исходном файле, не имевшем распознаваемого расширения), текущий рабочий язык не изменяется, а GDB выдает предупреждающее сообщение.
Для большинства программ, которые написаны целиком на одном языке, автоматическая установка языка может показаться ненужной. Однако, в основной программе, написанной на одном исходном языке, могут использоваться программные модули и библиотеки, написанные на другом исходном языке. Использование в этом случае `set language auto' освобождает вас от установки рабочего языка вручную.
Следующие команды помогают вам определить, какой язык является рабочим, а также на каком языке были написаны исходные файлы.
show language
print
для построения и вычисления
выражений, в которые могут входить переменные вашей программы.
info frame
info source
При необычных обстоятельствах, у вас могут быть исходные файлы с расширениями, не входящими в стандартный список. Вы можете явно установить расширение, ассоциированное с языком:
set extension-language .расш язык
info extensions
Предупреждение: В этот выпуск включены команды GDB для проверки диапазона и соответствия типов, но они пока не оказывают никакого действия. Этот раздел описывает их предполагаемые возможности.
Некоторые языки обеспечивают защиту от достаточно общих ошибок с помощью набора проверок времени компиляции и времени выполнения. Это включает проверку типов аргументов функций и операторов и обеспечивает проверку математического переполнения во время выполнения. Проверки такого рода помогают убедиться в корректности программы после ее компиляции путем устранения несоответствия типов, и предоставляя активную проверку ошибок выхода за пределы диапазона во время выполнения.
По вашему желанию, GDB может проводить подобные проверки. Хотя
GDB не проверяет операторы вашей программы, он может, например, проверять
выражения, введенные непосредственно в GDB для вычисления
командой print
. Как и в случае рабочего языка,
GDB может также автоматически решить, выполнять проверку или нет,
основываясь на исходном языке вашей программы. See section Поддерживаемые языки, для информации об установках по умолчанию для
поддерживаемых языков.
Некоторые языки, такие как Модула-2, должны иметь жесткое соответствие типов, то есть аргументы операторов и функций должны иметь правильный тип, в противном случае возникает ошибка. Описанные здесь проверки предотвращают ошибки несоответствия типов, которые могут вызвать ошибки времени выполнения. Например,
1 + 2 => 3 но error--> 1 + 2.3
Во втором примере ошибка, потому что CARDINAL
1 не совместим по
типу с REAL
2.3.
Для выражений, используемых вами в командах GDB, вы можете указать GDB не производить проверку; или же рассматривать любое несоответствие как ошибку и прекращать обработку выражения; или только выводить предупреждение в случае возникновения несоответствия, но вычислять выражение в любом случае. В последнем случае, GDB вычисляет выражения, подобные второму примеру, но также выводит предупреждающее сообщение.
Даже если вы отключили проверку типов, GDB может прекратить
обработку выражения по другим причинам, связанным с типами. Например,
GDB не знает, как сложить int
и struct foo
. Такие
типы ошибок не имеют ничего общего с используемым языком и
обычно возникают из выражений, подобных описанному выше, которые нет смысла
вычислять.
Каждый язык определяет степень строгости контроля типов. Например, как Модула-2, так и Си требуют, чтобы аргументы арифметических операций были числами. В Си, перечисляемые типы и указатели могут быть представлены в виде чисел, так что они допустимы в качестве аргументов математических операторов. See section Поддерживаемые языки, для более подробного обсуждения конкретных языков.
GDB предоставляет некоторые дополнительные команды для контроля проверки типов:
set check type auto
set check type on
set check type off
set check type warn
show type
В некоторых языках (например, в Модуле-2), выход за границы диапазона типа считается ошибкой; эти ошибки отслеживаются с помощью контроля времени выполнения. Эти проверки диапазона служат для того, чтобы избежать переполнения при вычислениях и не допустить превышения индексами элементов массива границ индексации.
В выражениях, используемых вами в командах GDB, вы можете указать GDB обрабатывать ошибки диапазона одним из трех способов: игнорировать их, всегда рассматривать как ошибки и прерывать обработку выражения, или выводить предупреждение и продолжать вычисление выражения.
Ошибки диапазона могут возникать при числовом переполнении, при превышении границы индексации массива или при использовании константы, не принадлежащей ни к одному типу. Однако, некоторые языки не считают переполнение ошибкой. Во многих реализациях Си, математическое переполнение вызывает "циклический переход" к меньшему значению. Например, если m---наибольшее целое значение, а s---наименьшее, то
m + 1 => s
Это также является специфичным для конкретных языков, а в некоторых случаях---для отдельного компилятора или машины. Для дальнейших сведений по отдельным языкам, See section Поддерживаемые языки.
GDB обеспечивает некоторые дополнительные команды для контроля проверки диапазона:
set check range auto
set check range on
set check range off
set check range warn
show range
GDB поддерживает Си, Си++, Фортран, Java, Chill, ассемблер и
Модула-2. Некоторые возможности GDB могут быть задействованы в
выражениях независимо от используемого языка: операторы GDB
@
и ::
и конструкция `{тип}адрес'
(see section Выражения) могут быть использованы в конструкциях
любого поддерживаемого языка.
Следующие разделы подробно описывают, до какой степени каждый из исходных языков поддерживается GDB. Эти разделы не задумывались как учебники или руководства по языкам; они лишь служат справочным руководством по тому, что допускает анализатор выражений GDB, и как должны выглядеть входные и выходные форматы в различных языках. Существует много хороших книг по каждому из этих языков; пожалуйста, загляните в них, если вам нужен учебник или справочник по языку.
Поскольку Си и Си++ тесно связаны, многие возможности GDB применимы к ним обоим. Когда это имеет место, мы обсуждаем эти языки вместе.
Средства отладки Си++ обеспечиваются совместно компилятором Си++
и GDB. Следовательно, для эффективной отладки программы на
Си++, вам следует пользоваться одним из поддерживаемых компиляторов,
например GNU g++
, или компилятором HP ANSI Си++
(aCC
).
При использовании GNU Си++, для получения наилучших результатов используйте формат отладочной информации stabs. Вы можете выбрать его явно с помощью ключа командной строки `-gstabs' или `-gstabs+'. Смотрите section `Ключи для отладки вашей программы или GNU CC' in Использование GNU CC, для дополнительной информации.
Операторы должны быть определены на значениях определенных типов.
Например, +
определен на числах, но не на структурах.
Операторы часто определяются на группах типов.
Для целей Си и Си++, имеют место следующие определения:
int
с любыми спецификаторами
класса памяти; char
; enum
; и, для Си++, bool
.
float
, double
и
long double
(если поддерживается целевой платформой).
(тип *)
.
Поддерживаются следующие операторы, перечисленные здесь в порядке возрастания приоритета:
,
=
опер=
a опер= b
и преобразовывается в a = a опер b
.
опер=
и =
имеют одинаковый приоритет.
опер может быть одним из операторов |
, ^
, &
,
<<
, >>
, +
, -
, *
,
/
, %
.
?:
a ? b : c
истолковывается
так: если a, то b, иначе c. a
должно быть целого типа.
||
&&
|
^
&
==, !=
<, >, <=, >=
<<, >>
@
+, -
*, /, %
++, --
*
++
.
&
++
.
Для отладки Си++, GDB реализует использование `&'
независимо от того, что позволяет сам язык Си++: вы можете использовать
`&(&ссылка)' (или просто `&&ссылка'),
чтобы исследовать адрес, по которому хранится
переменная-ссылка Си++ (объявленная с помощью `&ссылка').
-
++
.
!
++
.
~
++
.
., ->
struct
) и объединения (union
).
.*, ->*
[]
a[i]
определяется как
*(a+i)
. Имеет тот же приоритет, что и ->
.
()
->
.
::
struct
, union
и class
.
::
::
, описанный выше.
Если оператор переопределен в пользовательском коде, GDB обычно пытается выполнить переопределенную версию, а не использовать предопределенное значение оператора.
GDB позволяет вам выражать константы Си и Си++ следующими способами:
long
).
float
(в отличие от
double
по умолчанию), или буквой `l' или `L', что
указывает на константу типа long double
.
'
), или число---порядковое значение соответствующего
символа (обычно его значение ASCII). Внутри кавычек, одиночный
символ может быть представлен либо буквой, либо экранирующей
последовательностью, которая имеет форму `\nnn', где
nnn является восьмеричным представлением порядкового значения
символа; или форму `\x', где `x'---специальный
предопределенный знак, например, `\n' для знака новой строки.
"
). Туда
могут входить любые допустимые символьные константы (как описано выше).
Двойным кавычкам внутри строки должна предшествовать обратная косая
черта, так что `"a\"b'c"', например, является строкой из пяти
символов.
Обработчик выражений GDB может интерпретировать большинство выражений Си++.
Предупреждение: GDB может отлаживать программы на Си++ только если вы используете подходящий компилятор. Обычно, отладка Си++ зависит от использования дополнительной отладочной информации в таблице символов, и, таким образом, требует специальной поддержки. В частности, если ваш компилятор генерирует a.out, MIPS ECOFF, RS/6000 XCOFF, или ELF с расширениями stabs к таблице символов, все эти средства доступны. (С GNU CC вы можете использовать ключ `-gstabs', чтобы явно запросить расширения отладки stabs). С другой стороны, если формат объектного кода---стандартный COFF или DWARF в ELF, значительная часть поддержки Си++ в GDB не работает.
count = aml->GetOriginal(x, y)
this
по тем же правилам, что и Си++.
set overload-resolution off
. See section Возможности GDB для Си++.
Вы должны указать set overload-resolution off
, чтобы задать
функцию явно при вызове перегруженной функции, как в примере
p 'foo(char,int)'('x', 13)Возможности GDB для завершения команд могут упростить это; смотрите section Завершение команд.
::
---ваши выражения могут использовать его так же, как в вашей
программе. Так как одна область видимости может быть определена
внутри другой, вы можете при необходимости неоднократно использовать
::
, например, в выражении типа
`обл1::обл2::имя'. GDB также
позволяет определить область видимости имени путем ссылки на исходный
файл, при отладке как Си, так и Си++ (see section Переменные программы).
Кроме того, при использовании с компилятором HP Си++, GDB правильно поддерживает вызов виртуальных функций, вывод виртуальный баз объектов, вызов функций в базовом подобъекте, приведение объектов и выполнение операторов, определенных пользвателем.
Если вы разрешаете GDB устанавливать проверки диапазона и принадлежности типу автоматически, обе они по умолчанию отключены, если рабочий язык изменяется на Си или Си++. Это происходит независимо от того, выбираете рабочий язык вы или GDB.
Если вы разрешаете GDB устанавливать язык автоматически, он распознает исходные файлы, чьи имена заканчиваются расширением `.c', `.C' или `.cc', и так далее, и когда GDB начинает обработку кода, скомпилированного из одного из этих файлов, он устанавливает рабочий язык в Си или Си++. See section Распознавание GDB исходного языка, для более подробного обсуждения.
Когда GDB производит разбор выражений Си или Си++, по умолчанию проверки соответствия типов не проводятся. Однако, если вы их включите, GDB считает типы двух переменных эквивалентными, если:
typedef
.
Проверка диапазона, если она включена, выполняется для математических операций. Индексы массивов не проверяются, так как они часто применяются для индексирования указателей, которые сами по себе массивами не являются.
Команды set print union
и show print union
применимы к типу
union
. При установке в `on', любые объединения, находящиеся внутри
структуры или класса, также выводятся. В противном случае, они
отображаются как `{...}'.
Оператор @
помогает при отладке динамических массивов,
сформированных с помощью указателей и функции выделения памяти.
See section Выражения.
Некоторые команды GDB особенно полезны при использовании с Си++, а некоторые разработаны специально для него. Ниже приведено их краткое описание:
меню точки останова
rbreak рег-выр
catch throw
catch catch
ptype имя-типа
set print demangle
show print demangle
set print asm-demangle
show print asm-demangle
set print object
show print object
set print vtbl
show print vtbl
vtbl
не работают для программ, скомпилированных
компилятором HP ANSI Си++ (aCC
).)
set overload-resolution on
on
. Для перегруженных функций,
GDB вычисляет аргументы и ищет функции, чьи сигнатуры
удовлетворяют типам аргументов, используя стандартные правила
преобразования Си++ (смотрите section Выражения Си++, для
дополнительной информации). Если GDB не может найти такие
функции, он выводит сообщение.
set overload-resolution off
Перегруженные имена смиволов
символ(типы)
вместо просто
символ. Вы также можете воспользоваться средствами завершения
слова командной строки GDB, чтобы вывести список возможных
вариантов, или чтобы завершить набор за вас.
See section Завершение команд, для подробного обсуждения, как это
сделать.
Расширения, сделанные в GDB для поддержки Модулы-2, поддерживаются только для программ, скомпилированных GNU компилятором Модулы-2 (который сейчас разрабатывается). Другие компиляторы Модулы-2 в настоящее время не поддерживаются, и попытка отладки исполняемых программ, полученных ими, скорее всего приведет к ошибке при считывании GDB таблицы символов этой программы.
Операторы должны быть определены на значениях определенных типов.
Например, +
определен на числах, но не на структурах.
Операторы часто определяются на группах типов. Для целей Модулы-2,
имеют место следующие определения:
INTEGER
, CARDINAL
и их поддиапазонов.
CHAR
и его поддиапазонов.
REAL
.
POINTER TO
тип
.
SET
и BITSET
.
BOOLEAN
.
Поддерживаются следующие операторы; они представлены в порядке возрастания приоритета:
,
:=
:=
знач является знач.
<, >
<=, >=
<
.
=, <>, #
<
. В сценариях
GDB, для неравенства допустимо только <>
, так как
#
конфликтует со знаком комментария.
IN
<
.
OR
AND, &
@
+, -
*
/
*
.
DIV, MOD
*
.
-
INTEGER
и REAL
.
^
NOT
^
.
.
RECORD
. Определен для данных типа RECORD
.
Такое же приоритет, как у ^
.
[]
ARRAY
. Такой же
приоритет, как у ^
.
()
PROCEDURE
.
Такой же приоритет, как у ^
.
::, .
Предупреждение: Множества и операции над ними еще не поддерживаются, так что GDB трактует использование оператора
IN
или операторов+
,-
,*
,/
,=
, ,<>
,#
,<=
, и>=
на множествах как ошибку.
Модула-2 также делает доступными несколько встроенных процедур и функций. При их описании, используются следующие метапеременные:
ARRAY
.
CHAR
.
SET OF метатип
(где метатип---тип m).
Ниже описаны все встроенные процедуры Модулы-2, возвращающие результат.
ABS(n)
CAP(c)
CHR(i)
DEC(v)
DEC(v,i)
EXCL(m,s)
FLOAT(i)
HIGH(a)
INC(v)
INC(v,i)
INCL(m,s)
MAX(t)
MIN(t)
ODD(i)
ORD(x)
SIZE(x)
TRUNC(r)
VAL(t,i)
Предупреждение: Множества и операции над ними еще не поддерживаются, так что GDB рассматривает использование процедур
INCL
иEXCL
как ошибку.
GDB позволяет вам выражать константы Модулы-2 следующими способами:
'
), либо двойных ("
).
Они также могут быть заданы своим порядковым значением (обычно
ASCII-значением), за которым следует `C'.
'
), либо двойных
("
). Также допускаются экранирующие последовательности в
стиле Си. See section Константы Си и Си++, для краткого
объяснения экранирующих последовательностей.
TRUE
и FALSE
.
Если проверка диапазона или принадлежности типу устанавливается
GDB автоматически, то по умолчанию обе они устанавливаются в
on
, если рабочим языком становится Модула-2. Это происходит
независимо от того, кто выбрал рабочий язык---вы или GDB.
Если вы разрешаете GDB выбирать язык автоматически, то при анализе кода, скомпилированного из файла, чье имя оканчивается на `.mod', GDB установит рабочим языком Модулу-2. See section Распознавание GDB исходного языка, для дополнительной информации.
Для упрощения отладки программ на Модуле-2 было сделано несколько изменений. В основном, это сделано путем ослабления строгости контроля типов:
:=
) возвращает значение своего правого аргумента.
Предупреждение: в этом выпуске, GDB еще не выполняет проверки диапазона и принадлежности типу.
GDB считает две переменные Модулы-2 эквивалентными по типу, если:
TYPE
t1 = t2
Пока проверка соответствия типов включена, любая попытка скомбинировать переменные не эквивалентных типов является ошибкой.
Проверка диапазона выполняется во всех математических операциях, присваиваниях, при индексации массивов и во всех встроенных функциях и процедурах.
::
и .
Существует несколько тонких различий между операторами области видимости
Модулы-2 (.
) и GDB (::
). Оба имеют похожий синтаксис:
модуль . идент область :: идент
где область---имя модуля или процедуры, модуль---имя модуля, а идент---любой идентификатор, описанный в пределах вашей программы, за исключением другого модуля.
Использование оператора ::
заставляет GDB искать
идентификатор идент в области. Если он в ней
не найден, GDB ищет его во всех областях,
содержащих область.
Использование оператора .
заставляет GDB искать
идентификатор идент, который был импортирован из модуля определения
модуль, в текущей области видимости. В этом операторе cчитается
ошибкой, если идентификатор идент не был
импортирован из модуля определения модуль, или если идент не
является в нем идентификатором.
Некоторые команды GDB имеют мало смысла при отладке программ на
Модуле-2. Пять подкоманд из команд set print
и show
print
применимы исключительно к Си и Си++: `vtbl', `demangle',
`asm-demangle', `object' и `union'. Первые четыре
применимы к Си++, а последняя к типу Си union
, который не имеет
прямого аналога в Модуле-2.
Оператор @
(see section Выражения) хоть и доступен при
использовании любого языка, бесполезен при работе с Модулой-2. Его цель
состоит в том, чтобы помочь при отладке динамических массивов, которые
не могут быть созданы в Модуле-2 в отличие от Си или Си++. Однако,
конструкция `{тип}адр-выр' все же полезна, так как
адрес может быть определен целочисленной константой.
В сценариях GDB, оператор неравенства Модулы-2 #
интерпретируется как начало комментария. Используйте вместо него <>
.
Расширения, сделанные в GDB для поддержки Chill, работают только с программами, созданными компилятором GNU Chill. Другие компиляторы Chill в настоящее время не поддерживаются, и попытка отладить программы, полученные с их помощью, скорее всего приведет к ошибке в тот момент, когда GDB будет считывать таблицу символов выполняемого файла.
Этот раздел охватывает темы, связанные с Chill, и возможности GDB для их поддержки.
Поддержка GDB типов данных (режимов) Chill непосредственно связана с возможностями компилятора GNU Chill, и, следовательно, слегка отличается от стандартной спецификации языка. Вот предоставляемые режимы:
Дискретные режимы:
BYTE,
UBYTE, INT, UINT, LONG, ULONG
,
BOOL
,
CHAR
,
SET
.
(gdb) ptype x type = SET (karli = 10, susi = 20, fritzi = 100)Если тип является ненумерованным множеством, значения элементов множества опускаются.
тип = <базовый-режим>(<нижняя граница> : <верхняя граница>)
где <нижняя граница>, <верхняя граница>
может быть любым
дискретным буквенным выражением (например, имена элементов множества).
Режим powerset:
POWERSET
, за
которым следует режим элемента.
(gdb) ptype x type = POWERSET SET (egon, hugo, otto)
Режимы-ссылки:
REF
, за которым следует название режима, к которому ссылка
привязана.
PTR
.
Процедурный режим
тип = PROC(<список параметров>)
<возвращаемый режим> EXCEPTIONS (<список исключений>)
. <список
параметров>
представляет собой список режимов параметров.
<возвращаемый режим>
указывает режим результата процедуры, если
она возвращает результат. <список исключений>
перечисляет все
возможные исключения, которые могут быть возбуждены процедурой.
Синхронизационные режимы:
EVENT (<длина события>)
где <длина события>
является необязательной.
BUFFER (<длина буфера>)<режим елементов буфера>
где (<длина буфера>)
является необязательной.
Режимы времени:
DURATION
TIME
Вещественные режимы:
REAL
и LONG_REAL
.
Строковые режимы:
CHARS(<длина строки>)
за которым следует ключевое слово VARYING
, если строковый режим
является изменяющимся режимом
BOOLS(<длина строки>)
Режим массива:
ARRAY(<диапазон>)
,
за которым следует режим элементов (который, в свою очередь, может быть
режимом массива).
(gdb) ptype x type = ARRAY (1:42) ARRAY (1:20) SET (karli = 10, susi = 20, fritzi = 100)
Структурный режим
STRUCT(<список
полей>)
. <список полей>
состоит из имен и режимов полей
структуры. Структуры с вариантами имеют ключевое слово CASE
<поле> OF <варианты поля> ESAC
в их списке полей. Так как текущая
версия компилятора GNU Chill не реализует обработку тегов (нет
проверок времени выполнения вариантных полей, и, следовательно, нет
отладочной информации), вывод всегда содержит все вариантные поля.
(gdb) ptype str type = STRUCT ( as x, bs x, CASE bs OF (karli): cs a (ott): ds x ESAC )
Местоположением в Chill является объект, который может содержать значения.
Доступ к значению местоположения обычно производится посредством (описанного) имени местоположения. Вывод удовлетворяет спецификации значений в программах на Chill. То, как значения задаются, является темой следующего раздела, смотрите section Значения и операции с ними.
Псевдо-местоположение RESULT
(или result
) может
использоваться для отображения или изменения результата процедуры,
активной в настоящий момент:
set result := EXPR
Это делает то же самое, что и действие Chill RESULT EXPR
(которое
в GDB недоступно).
Значения местоположений режима ссылок выводятся, в случае режима
свободной ссылки, посредством
PTR(<шестнадцатеричное значение>)
, и с помощью (REF <режим ссылки>) (<шестнадцатеричное
значение>)
в случае привязанной ссылки. <шестнадцатеричное
значение>
представляет адрес, на который указывает ссылка. Для доступа
к значению местоположения, указываемого ссылкой, используйте оператор
разыменовывания `->'.
Значения местоположений процедурного режима отображаются как
{ PROC
(<режимы аргументов> ) <возвращаемый режим> } <адрес> <имя
местоположения процедуры>
<режимы аргументов>
---это список
режимов, в соответствии со спецификацией параметров процедуры, а
<адрес>
указывает адрес точки входа.
Подструктуры значений строковых режимов, режимов массивов или структур (например, срезы массивов, поля структурных местоположений) доступны при использовании определенных операторов, которые описаны в следующем разделе, смотрите section Значения и операции с ними.
Значение местоположения может быть интерпретировано как имеющее другой
режим посредством преобразования местоположений. Это преобразование
режимов записывается как <имя режима>(<местоположение>)
.
Пользователь должен учесть, что размеры режимов должны быть равными, в
противном случае возникает ошибка. Более того, не производится никаких
проверок диапазона местоположения по сравнению с режимом назначения, и,
следовательно, результат может быть достаточно обескураживающим.
(gdb) print int (s(3 up 4)) XXX TO be filled in !! XXX
Значения используются для изменения местоположений, для более подробного изучения сложных структур и для отфильтровывания значимой информации из большого объема данных. Определено несколько операций (зависящих от режима), которые позволяют проводить подобные изучения. Эти операции применимы не только к значениям-константам, но также и к местоположениям, что может оказаться достаточно полезным при отладке сложных структур. Во время разбора командной строки (например, вычисляя выражение), GDB рассматривает имена местоположений как значения этих местоположений.
Этот раздел описывает, как должны задаваться значения и какие операции допустимо использовать с этими значениями.
Буквенные значения
Значения-наборы
<имя режима>[<набор>]
, где <имя
режима>
может быть опущено, если режим набора определяется однозначно.
Эта однозначность определяется из контекста вычисляемого выражения.
<набор>
может быть одним из:
Значение элемента строки
<строковое значение>(<индекс>)
где <индекс>
является целочисленным
выражением. Это дает символьное значение, которое экивалентно символу,
указываемому в строке индексом <индекс>
.
Значение среза строки
<значение строки>(<спецификация
среза>)
, где <спецификация среза>
может быть либо диапазоном
целых выражений, либо задаваться в виде <начальное выражение> up
<размер>
. <размер>
обозначает число элементов, которое содержит
срез. Полученная величина является строкой, которая является частью
указанной строки.
Значения элементов массива
<величина
массива>(<выр>)
и дает величину элемента массива с режимом как у
указанного массива.
Значение среза массива
<значение массива>(<спецификация
среза>)
, где <спецификация среза>
может быть диапазоном,
определенным либо выражениями, либо как <начальное выр> up
<размер>
. <размер>
обозначает число элементов массива, которое
содержит срез. Получаемое значение есть массив, который является
частью указанного.
Значение поля структуры
<значение структуры>.<имя
поля>
, где <имя поля>
указывает имя поля, заданное в определении
режима структуры. Режим полученного значения соответствует этому
определению режима в определении структуры.
Значения вызова процедуры
ULONG
.
Значения местоположений режима-времени выводятся как
TIME(<сек>:<нсек>)
.
Значение безаргументного оператора
Значения выражений
OR, ORIF, XOR
AND, ANDIF
NOT
=, /=
>, >=
<, <=
+, -
*, /, MOD, REM
-
//
()
->
->loc
), или для
разыменовывания ссылки местоположения (loc->
).
OR, XOR
AND
NOT
>, >=
<, <=
IN
GDB считает два режима переменных Chill эквивалентными, если их размеры равны. Это правило применяется рекурсивно для более сложных типов данных. Это означает, что сложные режимы считаются эквивалентными, если режимы всех элементов (которые тоже могут быть сложными, например, массивами, структурами, и так далее) имеют одинаковый размер.
Проверка диапазона производится для всех математических операций, присваиваний, границ индексов массива и всех встроенных процедур.
Строгие проверки типов включаются с помощью команды GDB
set check strong
. Это навязывает строгую проверку диапазона и
принадлежности типу для всех действий, где используются конструкции
Chill (выражения, встроенные функции, и так далее), в соответствии с
семантикой, определенной в спецификации языка z.200.
Все проверки могут быть отключены командой GDB set check
off
.
Если проверки типа и диапазона установлены GDB автоматически, обе они по умолчанию включены, когда рабочий язык переключается на Chill. Это происходит независимо от того, вы выбрали рабочий язык или GDB.
Если вы разрешите GDB устанавливать рабочий язык автоматически, то при попадании в код, скомпилированный из файла, чье имя заканчивается на `.ch', он переключает рабочий язык на Chill. See section Распознавание GDB исходного языка, для дополнительной информации.
Команды, описанные в этой главе, позволяют вам получить информацию о символах (именах переменных, функций и типов), определенных в вашей программе. Эта информация присуща тексту вашей программы и не изменяется при ее выполнении. GDB находит эту информацию в таблице символов вашей программы, в файле, определенном при его вызове (see section Выбор файлов), или посредством одной из команд управления файлами (see section Команды для задания файлов).
Иногда вам может потребоваться сослаться на символы, содержащие
необычные знаки, которые GDB обычно трактует как разделители
слов. Наиболее часто это встречается при ссылках на статические
переменные в других исходных файлах (see section Переменные программы). Имена файлов записаны в объектных файлах как отладочные
символы, но GDB обычно производит разбор типичного имени файла, например
`foo.c', как три слова: `foo' .
c
. Чтобы GDB
идентифицировал `foo.c' как одно слово, заключите его в одинарные
кавычки; например,
p 'foo.c'::x
ищет значение x
в области видимости файла `foo.c'.
info address символ
whatis выраж
whatis
$
, последней записи в истории значений.
ptype имя-типа
ptype выраж
ptype
ptype
отличается от
whatis
тем, что выводится детальное описание, а не только имя
типа.
Например, для такого описания переменной:
struct complex {double real; double imag;} v;эти две команды выведут следущее:
(gdb) whatis v type = struct complex (gdb) ptype v type = struct complex { double real; double imag; }Как и
whatis
, использование ptype
без параметра относится
к типу $
, последней записи в истории значений.
info types рег-выр
info types
value
, а `i type ^value$' выдает инфоpмацию
только о типах с полным именем value
.
Эта команда отличается от ptype
следующим: во-пеpвых, как и
whatis
, она не выводит детального описания; во-вторых, она
перечисляет все исходные файлы, где определен тип.
info source
info sources
info functions
info functions рег-выр
step
;
`info fun ^step' находит функции с именами, начинающимися со step
.
info variables
info variables рег-выр
set symbol-reloading on
set symbol-reloading off
symbol-reloading
в состоянии off
, так как
иначе GDB может уничтожить символы пpи сборке больших программ,
которые могут содеpжать несколько модулей с одинаковым именем (из разных
каталогов или библиотек).
show symbol-reloading
on
или off
.
set opaque-type-resolution on
struct
, class
или union
---например, struct MyType *
---то есть,
используется в одном исходном файле, хотя полное описание struct
MyType
находится в другом исходном файле. По умолчаний установлено в
on
.
Изменения в установке этой подкомандой не вступят в силу, пока символы
для этого файла не будут снова загружены.
set opaque-type-resolution off
{<no data fields>}
show opaque-type-resolution
maint print symbols имя-файла
maint print psymbols имя-файла
maint print msymbols имя-файла
info sources
, чтобы
определить, какие это файлы. Если же вы используете `maint print
psymbols', дамп показывает информацию о тех символах, о которых
GDB имеет лишь частичную информацию, то есть символы определены
в файлах, которые GDB только просмотрел, но не прочитал
полностью. Наконец, `maint print msymbols', выводит только
минимальную информацию о символах, требуемую для каждого
объектного файла, из которых GDB пpочитал какие-либо символы.
See section Команды для задания файлов, для обсуждения как
GDB считывает символы (в описании symbol-file
).
Если вы думаете, что нашли ошибку в своей программе, вы можете захотеть выяснить наверняка, приведет ли исправление кажущейся ошибки к правильным результатам в остальной части программы. Вы можете получить ответ экспериментируя, используя средства GDB для изменения выполнения программы.
Например, вы можете сохранить новые значения в переменных или ячейках памяти, подать своей программе сигнал, перезапустить ее с другого адреса или даже преждевременно вернуться из функции.
Для изменения значения переменной, вычислите выражение присваивания. See section Выражения. Например,
print x=4
сохраняет значение 4 в переменной x
и затем выводит значение данного
выражения (которое равно 4). See section Использование GDB с различными языками программирования, для получения большей инфоpмации
об операторах в поддерживаемых языках.
Если вы не хотите видеть значение присваивания, используйте команду
set
вместо print
. Команда set
аналогична команде
print
за исключением того, что значение выражения не выводится и не
заносится в историю значений (see section История значений). Выражение вычисляется только ради его действия.
Если начало строки параметров команды set
выглядит идентично
подкоманде set
, используйте вместо нее команду set
variable
. Эта команда аналогична set
, но не имеет подкоманд.
Например, если в вашей программе есть переменная width
, то вы получите
ошибку, если попытаетесь установить новое значение просто с помощью
`set width=13', потому что GDB имеет команду
set width
:
(gdb) whatis width type = double (gdb) p width $4 = 13 (gdb) set width=47 Invalid syntax in expression.
Недопустимое выражение, это, конечно, `=47'. Для того чтобы
действительно установить переменную программы width
, используйте
(gdb) set var width=47
Так как команда set
имеет много подкоманд, которые могут
конфликтовать с именами переменных в программе, то хорошей практикой
является использование команды set variable
вместо просто
set
. Например, если ваша программа имеет переменную g
, у
вас возникнут проблемы, если вы попытаетесь установить новое значение
с помощью `set g=4', потому что GDB имеет команду
set gnutarget
, которая сокращается как set g
:
(gdb) whatis g type = double (gdb) p g $1 = 1 (gdb) set g=4 (gdb) p g $2 = 1 (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/smith/cc_progs/a.out "/home/smith/cc_progs/a.out": can't open to read symbols: Invalid bfd target. (gdb) show g The current BFD target is "=4".
Переменная программы g
не изменилась, и вы незаметно установили
gnutarget
в неверное значение. Для установки значения переменной
g
, используйте
(gdb) set var g=4
GDB допускает больше неявных преобразований в присваиваниях, чем Си; вы можете свободно сохранить целое значение в переменной-указателе и наоборот, преобразовать любую структуру к любой другой, которая имеет ту же длину или короче.
Для сохранения значений в произвольных местах
памяти, используйте конструкцию `{...}' для создания
значения определенного типа по определенному адресу памяти
(see section Выражения). Например, {int}0x83040
ссылается на ячейку памяти 0x83040
как на целое (что
предполагает соответствующий размер и представление в памяти), и
set {int}0x83040 = 4
записывает в эту ячейку памяти значение 4.
Обычно, когда вы продолжаете выполнение программы, вы делаете это
с того места, где она остановилась, командой continue
. Вместо
этого, вы можете продолжить выполнение с любого выбранного адреса
при помощи следующих команд:
jump указ-стр
tbreak
вместе с jump
является
обычной практикой. See section Установка точек останова.
Команда jump
не изменяет ни текущий кадр стека, ни
указатель стека, ни содержимое каких-либо ячеек памяти или регистров, кроме
счетчика программы. Если строка указ-стр находится вне
выполняющейся в настоящее время функции,
результаты могут быть странными, если эти
функции используют аргументы или локальные переменные разных типов. По
этой причине, команда jump
запрашивает подтверждение, если
указанная строка не находится в функции, выполняющейся в настоящее
время. Однако, даже странные результаты предсказуемы, если вы хорошо
знакомы с машинным кодом вашей программы.
jump *адрес
На многих системах, вы можете достичь такого же результата, как и с командой
jump
, сохранением нового значения в регистр $pc
. Отличие в
заключается том, что это не начинает выполнение вашей программы, а лишь
изменяет адрес, с которого будет выполняться программа,
когда вы продолжите выполнение. Например,
set $pc = 0x485
выполняет следующую команду continue
или команду пошагового
выполнения с адреса 0x485
, а не с того адреса, где ваша программа
остановилась. See section Продолжение и выполнение по шагам.
Наиболее общий случай использования команды jump
состоит в
возврате к выполнению части программы, возможно с большим количеством
установленных точек останова, которая уже выполнилась, для того чтобы
исследовать выполнение более детально.
signal сигнал
signal 2
и signal
SIGINT
---два способа подать сигнал прерывания.
Наоборот, если сигнал является нулем, выполнение продолжается без
подачи сигнала. Это полезно, если ваша программа остановилась из-за
сигнала и в обычном случае увидит его при возобновлении выполнения командой
continue
; `signal 0' продолжит выполнение без сигнала.
signal
не повторяется, когда вы нажимаете RET второй раз
после выполнения команды.
Вызов команды signal
отличается от вызова утилиты kill
из
оболочки. Подача сигнала посредством kill
заставляет
GDB решать, что делать с сигналом, в зависимости от таблиц
обработки сигналов (see section Сигналы). Команда signal
передает
сигнал непосредственно вашей программе.
return
return выражение
return
.
Если вы задаете параметр выражение, его значение используется
в качестве возвращаемого значения.
Когда вы используете return
, GDB уничтожает выбранный
кадр стека (и все кадры внутри него). Вы можете считать это
преждевременным возвратом из уничтоженного кадра. Если вы хотите
указать возвращаемое значение, задайте его в качестве аргумента к
return
.
Это выталкивает выбранный кадр стека (see section Выбор кадра) и все другие кадры внутри него, оставляя самым внутренним кадр, из которого произошел вызов. Этот кадр становится выбранным. Указанное значение сохраняется в регистрах, используемых для возвращаемых функцией значений.
Команда return
не возобновляет выполнение; она оставляет
программу остановленной в том состоянии, в котором бы она была сразу
после возврата из функции. Напротив, команда finish
(see section Продолжение и выполнение по шагам) возобновляет выполнение до естественного возврата из
выбранного кадра стека.
call выраж
void
)
возвращенных значений.
Вы можете использовать этот вариант команды print
, если хотите
выполнить функцию из вашей программы, не засоряя вывод пустыми возвращенными
значениями. Если результат не пустой, он выводится и
сохраняется в истории значений.
Для A29K, устанавливаемая пользователем переменная
call_scratch_address
задает положение рабочей области, которая
будет использоваться, когда GDB вызывает функцию на целевой машине.
Это необходимо, так как обычный метод размещения рабочей области в стеке
не работает в системах с раздельными областями команд и данных.
По умолчанию, GDB открывает файл, содержащий исполняемый код вашей программы (или файл дампа памяти), в режиме только для чтения. Это предотвращает случайные изменения машинного кода; но это также предотвращает и преднамеренное исправление двоичного файла вашей программы.
Если вы хотите иметь возможность исправлять двоичный код, вы можете
указать это явно с помощью команды set write
. Например, вы
можете захотеть установить внутренние флаги отладки или даже сделать
аварийные исправления.
set write on
set write off
set write
вам
необходимо загрузить его снова (используя команды exec-file
или
core-file
), чтобы новые установки вступили в силу.
show write
GDB должен знать имя файла программы, которая будет отлаживаться, чтобы прочитать его таблицу символов и чтобы запустить его. Для отладки дампа памяти от предыдущего выполнения, вы также должны сообщить GDB имя этого файла.
Вы можете указать имена исполняемого файла и файла дампа памяти. Обычно это делается во время вызова GDB, используя параметры с командами запуска GDB (see section Вход и выход из GDB).
Иногда во время сеанса GDB необходимо перейти к другому файлу. Или вы можете запустить GDB и забыть указать файл, который хотите использовать. В этих ситуациях полезны команды GDB для задания новых файлов.
file имя-файла
run
. Если вы не укажете каталог, и файл
не будет найден в рабочем катологе GDB, он использует переменную
среды PATH
в качестве списка каталогов для поиска, точно так
же, как это делает оболочка, когда ищет программу для выполнения.
Используя команду path
, вы можете изменить значение этой
переменной как для GDB, так и для вашей программы.
В системах с отображаемыми в память файлами, информация из таблицы
символов для имя-файла может храниться во вспомогательном файле
`имя-файла.syms'. Если это так, GDB осуществляет
отображение таблицы символов из `имя-файла.syms', запускаясь
намного быстрее. Смотрите описания ключей файлов `-mapped' и
`-readnow' (доступных с командной строки и в командах
file
, symbol-file
или add-symbol-file
, описанных
ниже), для получения большей информации.
file
file
без параметров велит GDB уничтожить любую имеющуюся
информацию как об исполняемом файле, так и о таблице символов.
exec-file [ имя-файла ]
PATH
. Отсутствие имя-файла означает, что необходимо
уничтожить информацию о выполняемом файле.
symbol-file [ имя-файла ]
PATH
. Для получения таблицы символов и исполняемой программы из
одного и того же файла, используйте команду file
.
symbol-file
без параметров сбрасывает информацию GDB о
таблице символов вашей программы.
Команда symbol-file
велит GDB забыть содержимое своих
вспомогательных переменных, историю значений и все точки останова и выражения
автоматического отображения, так как они могут содержать указатели
на внутренние данные, хранящие символы и типы данных, которые
являются частью данных старой таблицы символов, уничтоженной внутри
GDB.
symbol-file
не повторяется, если вы снова нажимаете RET
после первого выполнения.
Когда GDB сконфигурирован для определенной среды, он распознает
отладочную информацию в том формате, который обычно генерируется
для этой среды; вы можете использовать или компилятор GNU, или другие
компиляторы, которые придерживаются местных соглашений. Наилучшие
результаты обычно достигаются с помощью компилятора GNU;
например, используя gcc
, вы можете создавать отладочную
информацию для оптимизированного кода.
Для большинства типов объектных файлов, за исключением старых систем
SVR3, использующих COFF, команда symbol-file
обычно не считывает
таблицу символов сразу целиком. Вместо этого, она быстро сканирует
ее для определения, какие исходные файлы и символы в ней
присутствуют. Детали читаются позже, по одному исходному файлу за раз,
по мере необходимости.
Такая стратегия чтения в две стадии используется для того, чтобы
GDB вызывался быстрее. За исключением редких пауз, чтение
деталей таблицы символов для конкретного исходного файла в большинстве
случаев практически незаметно. (Команда set verbose
позволяет при желании превратить эти паузы в сообщения.
See section Необязательные предупреждения и сообщения.)
Мы еще не реализовали двухступенчатую стратегию чтения для COFF. Когда
таблица символов сохранена в формате COFF, symbol-file
считывает данные
таблицы символов сразу полностью. Заметьте, что "stabs-in-COFF" все
же реализует двухступенчатую стратегию, так как отладочная информация
реально хранится в формате stabs.
symbol-file имя-файла [ -readnow ] [ -mapped ]
file имя-файла [ -readnow ] [ -mapped ]
mmap
, вы можете использовать другой параметр,
`-mapped', чтобы GDB записывал символы для вашей программы
в файл многократного использования. Последующие сеансы отладки
GDB отображают информацию о символах из этого вспомогательного
файла (если программа не изменилась), вместо того, чтобы
тратить время на чтение таблицы символов из исполняемой программы.
Использование параметра `-mapped' производит такой же эффект, как
вызов GDB с ключем командной строки `-mapped'.
Вы можете использовать оба параметра вместе, чтобы быть уверенным,
что вспомогательный файл символов содержит всю информацию о символах
вашей программы.
Вспомогательный файл символов для программы myprog называется
`myprog.syms'. Если этот файл существует (и создан позже,
чем соответствующая исполняемая программа), GDB всегда пытается
использовать его при отладке myprog; не требуется никаких
специальных ключей или команд.
Файл `.syms' является специфичным для рабочей машины, на которой вы
вызываете GDB. Он содержит точный образ внутренней таблицы
символов GDB. Он не может быть использован одновременно на
разных рабочих платформах.
core-file [ имя-файла ]
core-file
без параметра указывает, что файл дампа памяти
использоваться не должен.
Обратите внимание, что файл дампа памяти игнорируется, если в данное
время ваша программа выполняется под управлением GDB. Так что
если вы выполняли программу, и желаете вместо этого отладить файл
дампа, вы должны убить подпроцесс, в котором выполняется ваша программа.
Для этого используйте команду kill
(see section Уничтожение дочернего процесса).
add-symbol-file имя-файла адрес
add-symbol-file имя-файла адрес [ -readnow ] [ -mapped ]
add-symbol-file имя-файла -sраздел адрес
add-symbol-file
считывает дополнительную информацию
таблицы символов из файла имя-файла. Вы должны использовать эту
команду, если файл имя-файла был динамически загружен (другими
средствами) в выполняющуюся программу. Адрес должен быть адресом
памяти, по которому был загружен файл; GDB сам его определить
не может. Вы можете указать дополнительно произвольное количество пар
`-s раздел адрес', чтобы явно указать имя раздела и
базовый адрес для него. Вы можете указать произвольный адрес как
выражение.
Таблица символов из файла имя-файла добавляется к таблице,
изначально считанной по команде symbol-file
. Вы можете
использовать команду add-symbol-file
произвольное число раз;
прочитанные таким образом символьные данные добавляются к старым. Чтобы
уничтожить все старые данные, используйте команду symbol-file
без
аргументов.
Команда add-symbol-file
не повторяется, если вы нажимаете
RET после ее использования.
Чтобы изменить способ обработки GDB таблицы символов для
имя-файла, вы можете использовать параметры `-mapped' и
`-readnow' так же, как и с командой symbol-file
.
add-shared-symbol-file
add-shared-symbol-file
может быть использована только для
Motorola 88k в операционной системе Harris CXUX. GDB
ищет разделяемые библиотеки автоматически, однако, если он не находит
ваших, вы можете выполнить add-shared-symbol-file
. Эта команда
не имеет аргументов.
section
section
изменяет базовый адрес раздела раздел
выполняемого файла в адрес. Это может быть использовано, если
выполняемый файл не содержит адресов разделов, (что имеет место для
формата a.out), или когда адреса, указанные в самом файле, неверны.
Каждый раздел должен изменяться отдельно. Команда info files
,
описанная ниже, перечисляет все разделы и их адреса.
info files
info target
info files
и info target
являются синонимами; они обе
выводят текущую цель (see section Определение отладочной цели), включая имена выполняемого файла и файла дампа памяти, используемых
GDB, и файлов, из которых были загружены символы. Команда
help target
выводит все возможные цели, а не только текущую.
Все команды для задания файлов допускают в качестве аргументов как абсолютные, так и относительные имена файлов. GDB всегда преобразовывает имя файла к абсолютному и запоминает его в таком виде.
GDB поддерживает разделяемые библиотеки на HP-UX, SunOS, SVr4, Irix 5 и IBM RS/6000.
Когда вы даете команду run
, или когда исследуете
файл дампа памяти, GDB автоматически загружает определения
символов из разделяемых библиотек. (Однако, если вы не отлаживаете файл дампа,
GDB не понимает ссылки на функции из разделяемой библиотеки до
того, как вы выполните команду run
.)
На HP-UX, если программа загружает разделяемую библиотеку явно,
GDB автоматически загружает символы в момент вызова
shl_load
.
info share
info sharedlibrary
sharedlibrary рег-выр
share рег-выр
run
. Если рег-выр опущено, загружаются все разделяемые
библиотеки, требуемые вашей программой.
В системах HP-UX, GDB сам определяет загрузку разделяемой библиотеки и автоматически считывает символы из нее, до некоторого изначально установленного порогового значения, которое вы можете при желании изменить.
После этого порогового значения, символы из разделяемых библиотек должны
загружаться явно. Для загрузки этих символов, используйте команду
sharedlibrary имя-файла
. Базовый адрес разделяемой
библиотеки определяется GDB автоматически и вы не
должны его задавать.
Для отображения или установки порогового значения, используйте следующие команды:
set auto-solib-add порог
sharedlibrary
. По
умолчанию, порог равен 100 мегабайтам.
show auto-solib-add
При чтении файла символов, GDB иногда сталкивается с такими
проблемами, как типы символов, которые он не распознает, или известные
ошибки вывода компилятора. По умолчанию, GDB не сообщает вам о таких
проблемах, так как они сравнительно общие и прежде всего представляют
интерес для людей, занимающихся отладкой компиляторов. Если вам интересна
информация о плохо созданных таблицах символов, вы можете запросить
GDB печатать только одно сообщение по каждому типу проблем,
независимо от того, сколько раз проблема появляется; или вы можете
попросить GDB напечатать больше сообщений, чтобы увидеть, сколько раз
проблема встречалась, командой set complaints
(see section Необязательные предупреждения и сообщения).
Печатаемые сообщения и их значения, включают:
inner block not inside outer block in символ
(don't known)
".
block at адрес out of order
set verbose on
. See section Необязательные предупреждения и сообщения.)
bad block start address patched
bad string table offset in symbol n
foo
,
что может вызвать другие проблемы, если много символов
заканчиваются этим именем.
unknown symbol type 0xnn
0xnn
---это тип символа неверно
истолкованной информации, в шестнадцатеричном виде.
GDB обходит ошибку, игнорируя эту символьную информацию. Это
обычно позволяет вам отладживать программу, хотя некоторые
символы и недоступны. Если вы столкнетесь с такой проблемой и
желаете ее отладить, вы можете отладить gdb
с помощью
него же, установив точку останова на complain
, затем дойти до
функции read_dbx_symtab
и исследовать *bufp
, чтобы
увидеть символ.
stub type has NULL name
const/volatile indicator missing (ok if using g++ v1.x), got...
info mismatch between compiler and debugger
Цель---это среда выполнения, занятая вашей программой.
Часто GDB выполняется в той же рабочей среде, что и ваша
программа; в этом случае, отладочная цель задается неявно в момент
использования команд file
или core
. Когда вам нужна
большая гибкость---например, выполнение GDB на другой машине, или
управление автономной системой через последовательный порт или системой
реального времени через соединение TCP/IP---вы можете использовать
команду target
для определения цели одного из типов,
сконфигурированных для GDB (see section Команды для управления целями).
Существует три класса целей: процессы, файлы дампов памяти и выполняемые файлы. GDB может обрабатывать одновременно до трех активных целей, по одной в каждом классе. Это позволяет вам (например) запустить процесс и проверять его действия, не прерывая вашу работу над файлом дампа.
Например, если вы выполняете `gdb a.out', то исполняемый файл
a.out
является единственной активной целью. Если вы назначите также
файл дампа---возможно от предыдущего выполнения, завершившегося ошибкой
и создавшего дамп---
тогда GDB имеет две активные цели и использует их вместе,
просматривая сначала файл дампа, а затем исполняемый файл, для выполнения
запросов к адресам памяти. (Обычно эти два класса целей дополняют друг
друга, так как файлы дампа памяти содержит только память программы,
доступную для чтения и записи
(переменные и тому подобное), и машинное состояние, в то время как исполняемый
файлы содержат только текст программы и инициализированные данные.)
Когда вы вводите run
, ваш исполняемый файл становится также активным
целевым процессом. Когда целевой процесс активен, все команды GDB,
запрашивающие адреса памяти, относятся к этой цели; адреса в активной
цели файла дампа или выполняемого файла неизвестны, пока активен
целевой процесс.
Используйте команды core-file
и exec-file
для выбора новой
цели файла дампа памяти или выполняемого файла (see section Команды для задания файлов). Для определения в качестве цели
процесса, который уже выполняется, используйте команду attach
(see section Отладка запущенного ранее процесса).
target тип параметры
target
не повторяется при повторном нажатии RET после
ее выполнения.
help target
info target
, либо info
files
(see section Команды для задания файлов).
help target имя
set gnutarget арг
set gnutarget
. В отличие от
большинства команд target
, с gnutarget
, команда target
относится к программе, а не к машине.
See section Команды для задания файлов.Предупреждение: Для определения формата файла посредством
set gnutarget
, вы должны знать фактическое имя BFD.
show gnutarget
show gnutarget
для отображения, какого
формата файлы gnutarget
установлен считывать. Если вы не
установили gnutarget
, GDB определит формат для каждого файла
автоматически, и show gnutarget
выведет `The current BFD target
is "auto"'.
Ниже приведены некоторые наиболее распространенные цели (доступные или нет, в зависимоси от конфигурации GDB):
target exec программа
target core имя-файла
target remote устр
target remote
поддерживает команду load
. Это полезно, только если вы можете
получить заглушку для целевой системы каким-нибудь другим
способом и можете разместить ее в памяти, где она не будет
затерта загрузкой.
target sim
target sim load runработает; однако, вы не можете предположить, что доступны определенное отображение памяти, драйверы устройств, или даже основные функции ввода-вывода, хотя некоторые эмуляторы действительно предоставляют это. Для информации о деталях эмуляторов для конкретного процессора, смотрите соответствующий section Встроенные процессоры.
Некоторые конфигурации могут также включать такие цели:
target nrom устр
Для различных конфигураций GDB доступны различные цели; ваша конфигурация может иметь больше или меньше целей.
Многие удаленные цели требуют, чтобы вы загрузили код выполняемого файла, после того как вы успешно установили соединение.
load имя-файла
load
. Если она существует, ее задачей является сделать
имя-файла (выполняемый файл) доступным для отладки на удаленной
системе---например, путем загрузки или динамической сборки.
load
также записывает таблицу символов имя-файла в
GDB, как команда add-symbol-file
.
Если ваш GDB не имеет команды load
, попытка выполнить ее
выдает сообщение об ошибке "You can't do that when your
target is ...
".
Файл загружается по адресу, указанному в выполняемом файле. Для
некоторых форматов объектных файлов, вы можете задать адрес загрузки при
сборке программы; для других форматов, таких как a.out, формат
объектного файла задает фиксированный адрес.
load
не повторяется, если вы нажимаете RET снова после ее
использования.
Некоторые типы процессоров, такие как MIPS, PowerPC и Hitachi SH, предоставляют возможность выполнения либо с порядком байтов от старшего, либо с порядком байтов от младшего. Обычно, выполняемый файл или символы содержат информацию для определения используемого порядка байтов, и вам не нужно об этом заботиться. Однако, иногда вам все же может пригодиться вручную изменить порядок байтов процессора, определенный GDB.
set endian big
set endian little
set endian auto
show endian
Заметьте, что эти команды управляют только интерпретацией символьных данных в рабочей системе, и они совершенно не оказывают действия на целевую систему.
Если вы пытаетесь отлаживать программу, выполняющуюся на машине, которая не может запустить GDB обычным способом, часто бывает полезна удаленная отладка. Например, вы можете использовать удаленную отладку для ядра операционной системы или для малой системы, которая не имеет достаточно мощной операционной системы общего назначения для вызова отладчика со всеми возможностями.
Некоторые конфигурации GDB имеют специальный последовательный или TCP/IP интерфейсы для того, чтобы это работало с конкретными отладочными целями. Кроме того, GDB распространяется с общим последовательным протоколом (уникальным для GDB, но не для конкретной целевой системы), который вы можете использовать, если пишете удаленные заглушки---код, выполняемый в удаленной системе для связи с GDB.
В вашей конфигурации GDB могут быть доступны другие удаленные
цели; используете help target
, чтобы их перечислить.
Для отладки программы, выполняемой на другой машине (отладочной целевой машине), вы сперва должны создать все обычные предпосылки для самостоятельного выполнения программы. Например, для программы на Си вам нужны:
Следующим шагом будет принятие мер по использованию вашей программой последовательного порта для связи с машиной, где выполняется GDB (рабочей машиной). В общих чертах, схема выглядит следующим образом:
gdbserver
вместо компоновки заглушки вместе с вашей
программой. See section Использование программы gdbserver
,
для детального изучения.
Отладочная заглушка специфична для архитектуры удаленной машины; например, используйте `sparc-stub.c' для отладки программ на машинах SPARC.
Следующие работающие удаленные заглушки распространяются вместе с GDB:
i386-stub.c
m68k-stub.c
sh-stub.c
sparc-stub.c
sparcl-stub.c
Файл `README' в поставке GDB может содержать другие недавно добавленные заглушки.
Отладочная заглушка для вашей архитектуры содержит следующие три подпрограммы:
set_debug_traps
handle_exception
. Вы должны явно вызвать эту
подпрограмму в начале вашей программы.
handle_exception
handle_exception
, когда
вызывается ловушка.
handle_exception
получает управление, когда ваша программа
останавливается во время выполнения (например, в точке останова), и
организует связь с GDB на рабочей машине. Именно здесь
реализуется протокол связи; handle_exception
действует как
представитель GDB на целевой машине. Сперва она посылает
суммарную информацию о состоянии вашей программы, затем продолжает
выполняться, извлекая и передавая любую информацию, требующуюся
GDB, пока вы не выполните команду GDB, возобновляющую
выполнение вашей программы; в этом месте handle_exception
возвращает управление вашему коду на целевой машине.
breakpoint
handle_exception
---в действительности, GDB.
На некоторых машинах простое получение символов на последовательный порт
может также вызвать ловушку; опять, в этой ситуации вам не нужно вызывать
breakpoint
из вашей программы---простое выполнение `target
remote' из рабочего сеанса GDB передаст управление.
Вызывайте breakpoint
, если ни одно из этих предположений не верно,
или вы просто хотите быть уверенным, что ваша программа остановится в
предопределенной точке от начала вашего сеанса отладки.
Отладочные заглушки, поставляемые с GDB, ориентированы на микропроцессоры определенной архитектуры, но они не имеют информации об остальной части вашей целевой отладочной машины.
В первую очередь, вам нужно сообщить заглушке, как связаться с последовательным портом.
int getDebugChar()
getchar
для
вашей целевой системы; разные имена используются, чтобы позволить
вам их различать, если вы этого хотите.
void putDebugChar(int)
putchar
для
вашей целевой системы; разные имена используются, чтобы позволить
вам их различать, если вы этого хотите.
Если вы хотите, чтобы GDB мог остановить вашу программу во
время ее выполнения, вам нужно использовать управляемый прерываниями
последовательный драйвер и настроить его для остановки при получении
^C
(`\003', символ control-C). Это тот символ, который
GDB использует для указания удаленной системе остановиться.
Указание отладочной цели вернуть GDB правильный статус,
вероятно, требует изменений стандартной заглушки; один быстрый и
неаккуратный способ состоит в выполнении лишь инструкции точки останова
("неаккуратность" состоит в том, что GDB выдает
SIGTRAP
вместо SIGINT
).
Вот другие процедуры, которые вы должны обеспечить:
void exceptionHandler (int номер-исключения, void *адрес-исключения)
exceptionHandler
.
void flush_i_cache()
Вы должны также удостовериться, что эта библиотечная процедура доступна:
void *memset(void *, int, int)
memset
, которая
устанавливает область памяти в заданное значение. Если вы имеете
одну из свободных версий libc.a
, memset
может быть найдена
там; иначе вы должны или получить ее от изготовителя аппаратного
обеспечения, или написать свою собственную.
Если вы не используете компилятор GNU Си, вам также могут
понадобиться другие стандартные библиотечные подпрограммы; это
меняется от одной заглушки к другой, но в общем, заглушки
часто используют различные общие библиотечные подпрограммы, которые
gcc
генерирует как встроенный код.
Вкратце, когда ваша программа готова к отладке, вы должны проделать следующие шаги.
getDebugChar
,putDebugChar
,flush_i_cache
,memset
,exceptionHandler
.
set_debug_traps(); breakpoint();
exceptionHook
. Обычно вы используете просто:
void (*exceptionHook)() = 0;если до вызова
set_debug_traps
вы установили ее для
указания на функцию в вашей программе. Эта функция вызывается, когда
GDB продолжает выполнение после останова на ловушке (например,
ошибка шины).
Функция, указанная exceptionHook
, вызывается с одним
параметром типа int
, который является номером исключения.
target remote
. Ее
аргументы определяют, как взаимодействовать с целевой машиной---
либо через устройство, подключенное к последовательной линии,
либо через порт TCP (обычно подключенный к терминальному серверу, который,
в свою очередь, имеет последовательную линию до цели). Например,
чтобы использовать последовательную линию, присоединенную к устройству
`/dev/ttyb', выполните:
target remote /dev/ttybЧтобы использовать TCP-соединение, используйте аргумент в форме
машина:порт
. Например, для соединения с портом 2828 на
терминальном сервере manyfarms
:
target remote manyfarms:2828
Теперь вы можете использовать все обычные команды для исследования и изменения данных, пошагового выполнения и продолжения исполнения удаленной программы.
Для возобновления выполнения удаленной программы и прекращения ее
отладки, используйте команду detach
.
Всякий раз, когда GDB ожидает удаленную программу, если вы вводите символ прерывания (часто C-C), GDB пытается остановить программу. Это может привести или не привести к успеху, частично в зависимости от аппаратных средств и последовательных драйверов, которые использует удаленная система. Если вы снова введете символ прерывания, GDB выведет такое приглашение:
Interrupted while waiting for the program. Give up (and stop debugging it)? (y or n)
Если вы введете y, GDB прекратит сеанс удаленной отладки.
(Если вы решите позже, что хотите попытаться снова, вы можете вновь
использовать target remote
, чтобы соединиться еще раз.) Если вы
введете n, GDB вернется к ожиданию.
Файлы заглушек, поставляемые с GDB, реализуют коммуникационный протокол со стороны целевой машины, а со стороны GDB он реализуется в исходном файле GDB `remote.c'. Обычно вы можете просто позволить этим программам взаимодействовать, и не вдаваться в детали. (Если вы разрабатываете свой собственный файл заглушки, вы также можете игнорировать детали: начните с одного из существующих файлов заглушки. `sparc-stub.c' организован наилучшим образом, и потому его легче всего читать.)
Однако, бывают случаи, когда вам необходимо что-нибудь знать о протоколе---например, если существует только один последовательный порт на вашей целевой машине, вы можете захотеть, чтобы ваша программа делала что-нибудь особенное, если она распознает предназначенный для GDB пакет.
В следующих примерах, `<-' и `->' используются для обозначения переданных и полученных данных соответственно.
Все команды и ответы GDB (не подтверждения), посылаются в виде пакета. Пакет представлен символом `$', реальными данными-пакета завершающим символом `#', за которым следуют две цифры контрольной-суммы:
$
данные-пакета#
контрольная-сумма
Двухциферная контрольная-сумма вычисляется как сумма по модулю 256 всех символов между начальным `$' и конечным `#' (восьмибитная беззнаковая контрольная сумма).
Разработчикам следует учесть, что до GDB версии 5.0 спецификация протокола также включала необязательный двухциферный ид-последов:
$
ид-последов:
данные-пакета#
контрольная-сумма
Этот ид-последов добавлялся к подтверждению. GDB никогда не генерировал ид-последов. Заглушки, занимающиеся обработкой пакетов, добавленные в GDB начиная с версии 5.0, не должны принимать пакеты с ид-последов.
Когда или рабочая, или целевая машина получает пакет, первым ожидаемым ответом является подтверждение: или `+' (для указания, что пакет получен корректно), или `-' (чтобы запросить повторную передачу):
<-$
данные-пакета#
контрольная-сумма ->+
Рабочая машина (GDB) посылает команды, а целевая (отладочная заглушка, включенная в вашу программу) посылает ответ. В случае команд пошагового выполнения и продолжения, ответ посылается только тогда, когда операция закончена (цель снова остановлена).
Данные-пакета состоят из последовательности знаков, за исключением `#' и `$' (для дополнительных исключений, смотрите пакет `X').
Поля внутри пакета должны разделяться при помощи `,', `;' или `:'. Если не оговорено противное, все числа представлены в шестнадцатеричном виде без начальных нулей.
Разработчикам следует учесть, что до GDB версии 5.0, символ `:' не мог появляться третим символом в пакете (так как потенциально это могло привести к конфликту с ид-последов).
Ответ данные может быть закодированным с помощью кодирования
методом длины серий, чтобы
сохранить место. `*' означает, что следующий символ является
ASCII-кодом, который означает количество повторений символа,
предшествующего `*'. Кодировкой является n+29
, что дает печатный
знак для n >=3
(когда кодировка переменной длины дает
преимущества). Печатные знаки `$', `#', `+', `-',
или с номерами, большими 126, использоваться не должны.
Некоторые удаленные системы использовали другой механизм кодировки с переменной длиной, иногда называемый cisco-кодировкой. За `*' следуют две шестнадцатеричные цифры, обозначающие размер пакета.
Итак:
"0*
"
означает то же, что и "0000".
При ошибке, ответ, возвращаемый для некоторых пакетов, включает двухсимвольный номер ошибки. Этот номер определен смутно.
Для любой команды, не поддерживаемой заглушкой, должен быть возвращен пустой ответ (`$#00'). Таким образом, протокол можно расширять. Новые версии GDB могут определить, поддерживается ли пакет, основываясь на ответе.
От заглушки требуется поддержка команд `g', `G', `m', `M', `c' и `s'. Все остальные команды являются необязательными.
Вот полный список всех определенных на данный момент команд, и соответствующих им ответов данные:
Пакет | Запрос | Описание |
расширенные операции | !
| Использовать расширенный удаленный протокол. Имеет постоянное действие---требует установки только один раз. Расширенный удаленный протокол поддерживает пакеты `R'. |
ответ `' | Заглушки, поддерживающие расширенный удаленный протокол, возвращают `', что, к сожалению, совпадает с ответом, возвращаемым заглушками, которые не поддерживают расширения протокола. | |
последний сигнал | ?
| Указывает причину, по которой цель остановилась. Ответ такой же, как для пошагового выполнения и продолжения. |
ответ | смотрите ниже | |
зарезервировано | a
| Зарезервировано для использования в будущем |
установить аргументы программы (зарезервировано) | A длина-арг, число-арг, арг,...
| |
В программу передается инициализированный массив `argv[]'. Длина-арг задает число байт в закодированном в шестнадцатеричный вид потоке байт арг. Смотрите `gdbserver' для дополнительной информации. | ||
ответ OK
| ||
ответ E NN
| ||
установить скорость (не рекомендовано) | b бод
| Установить скорость последовательной линии в бод. |
установить точку останова (не рекомендовано) | B адрес,режим
| Установить (режим `S') или удалить (режим `C') точку останова по адресу адрес. Это было замещено пакетами `Z' и `z'. |
продолжить | c адрес
| Адрес---это адрес для возобновления выполнения. Если он опущен, возобновить с текущего адреса. |
ответ | смотрите ниже | |
продолжить с сигналом | C сиг; адрес
|
Продолжить с сигналом сиг (шестнадцатеричный номер сигнала). Если
`; адрес' опущено, выполнение возобновляется с прежнего
адреса.
|
ответ | смотрите ниже | |
переключить режим отладки (не рекомендовано) | d
| переключить флаг отладки. |
отсоединиться | D
| Отсоединить GDB от удаленной системы. Посылается удаленной системе перед тем, как GDB отсоединится. |
ответ нет ответа | GDB не ждет никакого ответа после посылки этого пакета. | |
зарезервировано | e
| Зарезервировано для использования в будущем |
зарезервировано | E
| Зарезервировано для использования в будущем |
зарезервировано | f
| Зарезервировано для использования в будущем |
зарезервировано | F
| Зарезервировано для использования в будущем |
чтение регистров | g
| Чтение регистров общего назначения. |
ответ XX... | Каждый байт данных регистра описывается двумя шестнадцатеричными цифрами. Они передаются с целевым порядком байтов. Размер каждого регистра и его позиция внутри пакета `g' определяются внутренними макросами GDB REGISTER_RAW_SIZE и REGISTER_NAME. Спецификация нескольких стандартных пакетов `g' приведена ниже. | |
E NN
| в случае ошибки. | |
запись в регистры | G XX...
| Смотрите `g' для описания данных XX... . |
ответ OK
| в случае успеха | |
ответ E NN
| в случае ошибки | |
зарезервировано | h
| Зарезервировано для использования в будущем |
выбрать нить | H ct...
| Установить нить для последующих операций (`m', `M', `g', `G', и другие). c = `c' для нитей, используемых при пошаговом выполнении и продолжении; t... может быть -1 для всех нитей. c = `g' для нитей, используемых в других операциях. Если ноль---выбрать любую нить. |
ответ OK
| в случае успеха | |
ответ E NN
| в случае ошибки | |
пошаговое выполнение по тактовому циклу (черновик) | i адрес, nnn
|
Выполнить один тактовый цикл на удаленной машине. Если
`, nnn' указано, выполнить nnn циклов. Если
указан адрес, пошаговое выполнение по одному тактовому циклу
начинается этого адреса.
|
сигнал, затем выполнение по тактовым циклам (зарезервировано) | I
| Смотрите `i' и `S', там аналогичный синтаксис и семантика. |
зарезервировано | j
| Зарезервировано для использования в будущем |
зарезервировано | J
| Зарезервировано для использования в будущем |
убить | k
| FIXME: Нет описания, как действовать в случае, если был выбран контекст определенной нити (то есть `k' убивает только эту нить?). |
зарезервировано | l
| Зарезервировано для использования в будущем |
зарезервировано | L
| Зарезервировано для использования в будущем |
чтение памяти | m адрес, длина
| Прочитать длину байт памяти, начиная с адреса адрес. Ни GDB, ни заглушка не предполагают, что передача области памяти происходит по адресам, выровненным по границе слова. FIXME: Нужен механизм передачи области памяти, выровненной по границе слова. |
ответ XX... | XX... представляет собой содержимое памяти. Может содержать меньше запрошенного числа байт, если удалось прочитать только часть данных. Ни GDB, ни заглушка не предполагают, что передача области памяти происходит по адресам, выровненным по границе слова. FIXME: Нужен механизм передачи области памяти, выровненной по границе слова. | |
ответ E NN
| NN представляет номер ошибки | |
запись в память | M адрес,длина: XX...
| Записать длину байт памяти, начиная с адреса адрес. XX...---это данные. |
ответ OK
| при успехе | |
ответ E NN
| при ошибке (это включает случай, когда была записана только часть данных). | |
зарезервировано | n
| Зарезервировано для использования в будущем |
зарезервировано | N
| Зарезервировано для использования в будущем |
зарезервировано | o
| Зарезервировано для использования в будущем |
зарезервировано | O
| Зарезервировано для использования в будущем |
чтение регистров (зарезервировано) | p n...
| Смотрите запись регистров. |
возврат r.... | Значение регистра в целевом порядке байт, закодированное в шестнадцатеричном виде. | |
запись регистров | P n...= r...
| Записать в регистр n... значение r..., которое содержит две шестнадцатеричные цифры для каждого байта в регистре (целевой порядок байтов). |
ответ OK
| в случае успеха | |
ответ E NN
| при ошибке | |
общий запрос | q запрос
| Запросить информацию о запросе. Вообще, запросы GDB имеют первую заглавную букву. Специальные запросы от производителей должны использовать приставку компании (из маленьких букв). Например: `qfsf.var'. За запросом может следовать необязательный список, разделенный `,' или `;'. Заглушки должны проверять, что они производят сравнение с полным именем запроса. |
ответ XX...
| Данные от запроса, закодированные шестнадцатеричными цифрами. Ответ не может быть пустым. | |
ответ E NN
| ответ при ошибке | |
ответ `' | Указывает на нераспознанный запрос. | |
общая установка | Q перем= знач
| Установить значение перем в знач. Смотрите `q' для обсуждения соглашений, касающихся имен. |
сброс (не рекомендовано) | r
| Установка всей системы в исходное состояние. |
удаленная перезагрузка | R XX
| Перезапустить удаленный сервер. XX, где оно требуется, не имеет ясного определения. FIXME: Нужен пример взаимодействия, объясняющий как эти пакеты используются в расширенном удаленном режиме. |
пошагавое выполнение | s адрес
| Адрес---это адрес для возобновления выполнения. Если адрес опущен, возобновить выполнение с того же адреса. |
ответ | смотрите ниже | |
пошаговое выполнение с сигналом | S сиг; адрес
|
Как C , но разница такая же, как между step и
continue .
|
ответ | смотрите ниже | |
поиск | t адрес: PP, MM
| Поиск в обратном направлении, начиная с адреса адрес, до совпадения с шаблоном PP и маской MM. PP и MM---4 байта. Адрес должен быть не менее трех цифр. |
жива ли нить | T XX
| Определить, жива ли нить XX. |
ответ OK
| нить все еще жива | |
ответ E NN
| нить мертва | |
зарезервировано | u
| Зарезервировано для использования в будущем |
зарезервировано | U
| Зарезервировано для использования в будущем |
зарезервировано | v
| Зарезервировано для использования в будущем |
зарезервировано | V
| Зарезервировано для использования в будущем |
зарезервировано | w
| Зарезервировано для использования в будущем |
зарезервировано | W
| Зарезервировано для использования в будущем |
зарезервировано | x
| Зарезервировано для использования в будущем |
запись в память (двоичная) | X адрес, длина:XX...
|
Адрес это адрес, длина это число байт, XX... это
двоичные данные. Символы $ , # и 0x7d экранируются
с помощью 0x7d .
|
ответ OK
| в случае успеха | |
ответ E NN
| в случае ошибки | |
зарезервировано | y
| Зарезервировано для использования в будущем |
зарезервировано | Y
| Зарезервировано для использования в будущем |
удалить точку останова или наблюдения (черновик) | z t, адрес, длина
| Смотрите `Z'. |
поместить точку останова или наблюдения (черновик) | Z t, адрес, длина
| t представляет тип: `0' в случае программной точки останова, `1'---аппаратная точка останова, `2'---точка наблюдения за записью, `3'---точка наблюдения за чтением, `4'---точка наблюдения за доступом; адрес---это адрес; длина задается в байтах. Для программной точки останова, длина задает размер инструкции, на которую надо поместить заплату. Для аппаратных точек останова и наблюдения, длина указывает размер области памяти для наблюдения. Чтобы избежать потенциальных проблем с повторными пакетами, операции должны быть идемпотентным образом. |
ответ E NN
| в случае ошибки | |
ответ OK
| в случае успеха | |
`' | Если не поддерживается. | |
зарезервировано | <другое> | Зарезервировано для использования в будущем |
Пакеты `C', `c', `S', `s' и `?' могут получить в качестве ответа все нижеперечисленное. В случае пакетов `C', `c', `S' и `s', этот ответ возвращается только тогда, когда цель останавливается. Ниже, точное значение `номера сигнала' определено нечетко. Вообще, используется одно из соглашений UNIX о номерах сигналов.
S AA |
AA---это номер сигнала |
T AAn...: r...; n...: r...; n...: r...; |
AA = две шестнадцатеричные цифры номера сигнала; n... =
(шестнадцатеричный) номер регистра, r... = содержимое регистра в
целевом порядке байт, размер определяется REGISTER_RAW_SIZE ;
n... = `thread', r... = идентификатор процесса нити, это
шестнадцатеричное целое; n... = другая строка, не начинающаяся с
шестнадцатеричной цифры. GDB должен игнорировать эту пару
n..., r... и переходить к следующей. Таким образом мы можем
расширять протокол.
|
W AA |
Процесс завершается с кодом выхода AA. Это применимо только к определенным типам целей. |
X AA |
Процесс завершается с сигналом AA. |
N AA; t...; d...; b... (устарело) |
AA = номер сигнала; t... = адрес символа "_start"; d... = база раздела данных; b... = база раздела bss. Примечание: используется только целями Cisco Systems. Разница между этим ответом и запросом "qOffsets" заключается в том, что пакет 'N' может прибыть самопроизвольно, тогда как запрос 'qOffsets' инициируется рабочим отладчиком. |
O XX... |
XX...---шестнадцатеричное представление ASCII-данных. Это может произойти в любой момент, пока программа выполняется и отладчик должен продолжать ждать 'W', 'T', и т.п. |
Следующие пакеты для установок и запросов уже были определены.
текущая нить | q C
| Возвратить идентификатор текущей нити. |
ответ QC идент-проц
| Где идент-проц---16-битный идентификатор процесса, представленный шестнадцатеричнами цифрами. | |
ответ * | Любой другой ответ подразумевает старый идентификатор процесса. | |
идентификаторы всех нитей | q fThreadInfo
| |
q sThreadInfo
|
Получить список идентификаторов активных нитей от целевой ОС. Так как
число активных нитей может оказаться слишком большим и не поместиться в
пакет ответа, этот запрос работает итерациями: он может требовать более
одной последовательности запрос/ответ, для получения полного
списка нитей. Первым запросом последовательности будет
qf ThreadInfo ; последующими запросами последовательности
будут запросы qs ThreadInfo .
| |
Замечание: замещает запрос qL (смотрите ниже).
| ||
ответ m <ид>
| Идентификатор одной нити | |
ответ m <ид>,<ид>...
| список идентификаторов нитей, разделенных запятыми | |
ответ l
| (буква 'l' в нижнем регистре) обозначает конец списка. | |
В ответ на каждый запрос, цель будет отвечать списком из разделенных
запятыми идентификаторов нитей, в шестнадцатеричном представлении, с
порядком байт от старшего. GDB будет отвечать на каждый ответ
запросом других идентификаторов (используя форму qs запроса),
пока цель не ответит l (буква 'l' в нижнем регистре, от
английского слова 'last' ).
| ||
дополнительная информация о нити | q ThreadExtraInfo , ид
| |
Здесь ид является идентификатором нити в шестнадцатеричном представлении, в порядке байт от старшего. Получает печатаемое описание строки атрибутов нити от целевой ОС. Эта строка может содержать все что угодно, что целевая ОС сочтет интересным для GDB сообщить пользователю о нити. Эта строка выводится в отображении GDB `info threads'. Примерами возможной дополнительной информации являются "Runnable" или "Blocked on Mutex". | ||
ответ XX... | Где XX...---ASCII-данные в шестнадцатеричном представлении, содержащие печатную строку с дополнительной информацией об атрибутах нити. | |
запрос список или список-нитей (не рекомендовано) | q L нач-флагчисло-нитейслед-нить
| |
Получить информацию о нити от операционной системы, где происходит выполнение. Здесь: нач-флаг (одна шестнадцатеричная цифра) есть единица, что указывает на первый запрос, или ноль, что определяет последующий запрос; число-нитей (две шестнадцатеричные цифры)---максимальное число нитей, которое может содержать пакет ответа; и след-нить (восемь шестнадцатеричных цифр), для последующих запросов (нач-флаг равен нулю), возвращается в ответ как арг-нить. | ||
Замечание: этот запрос был замещен запросом
q fThreadInfo (смотрите выше).
| ||
ответ q M числоконецарг-нитьнить...
| ||
Здесь: число (две шестнадцатеричные цифры)---число возвращаемых
нитей; конец (одна шестнадцатеричная цифра), есть ноль, который
определяет, что есть еще нити, и единица, определяющая, что
больше нитей нет; арг-нить (восемь шестнадцатеричных цифр)
представляет собой след-нить из пакета запроса;
нить...---это последовательность идентификаторов нитей от цели.
Идент-нити (восемь шестнадцатеричных цифр). Смотрите
remote.c:parse_threadlist_response() .
| ||
вычислить CRC блока памяти | q CRC: адрес, длина
| |
ответ E NN
| Ошибка (например, ошибка доступа к памяти) | |
ответ C CRC32
| Лишняя 32-битная циклическая проверка указанной области памяти. | |
запросить смещения разделов | q Offsets
|
Получить смещения разделов, которые целевая машина использовала при
повторном размещении загруженного образа. Замечание: если
смещение Bss включено в ответ, GDB это игнорирует и
вместо этого применяет к разделу Bss смещение Data .
|
ответ Text= xxx;Data= yyy;Bss= zzz
| ||
запросить информацию о нити | q P режимидент-нити
| |
Возвращает информацию об идент-нити. Здесь: режим является 32-битным режимом в шестнадцатеричном представлении; идент-нити---64-битный идентификатор нити в шестнадцатеричном представлении. | ||
ответ * |
Смотрите remote.c:remote_unpack_thread_info_response() .
| |
удаленная команда | q Rcmd, КОМАНДА
| |
КОМАНДА (в шестнадцатеричном представлении) передается для
выполнения локальному интерпретатору. Неверные команды должны
сообщаться при помощи выходной строки. Перед конечным результирующим
пакетом, целевая машина может также ответить некоторым количеством
промежуточных O ВЫВОД пакетов вывода на консоль.
Разработчики должны учесть, что предоставление доступа к
интерпретатору заглушки может иметь последствия для безопасности.
| ||
ответ OK
| Ответ на команду без вывода. | |
ответ ВЫВОД | Ответ на команду со строкой вывода ВЫВОД, в шестнадцатеричном представлении. | |
ответ E NN
| Указывает на неправильно сформированный запрос. | |
reply `' | Когда `q'`Rcmd' не распознана. |
Следующие пакеты `g'/`G' были определены раньше. Ниже, некоторые 32-битные регистры передаются в виде 64 бит. Эти регистры должны быть расширены нулем/знаком (как?), чтобы заполнять выделенное место. Байты регистра передаются в целевом порядке байтов. Две части в байте регистра передаются от более значимого к менее значимому.
MIPS32 | Все регистры передаются как 32-битные величины в таком порядке: 32 общего назначения; sr; lo; hi; bad; cause; pc; 32 регистра с плавающей точкой; fsr; fir; fp. |
MIPS64 |
Все регистры передаются как 64-битные величины (включая такие 32-битные
регистры, как sr ). Порядок такой же, как для MIPS32 .
|
Вот пример последовательности для перезапускаемой цели. Заметьте, что перезапуск не получает никакого непосредственного вывода:
<-R00
->+
target restarts <-?
->+
->T001:1234123412341234
<-+
Пример последовательности при при пошаговом выполнении цели по одной инструкции:
<-G1445...
->+
<-s
->+
time passes ->T001:1234123412341234
<-+
<-g
->+
->1455...
<-+
gdbserver
gdbserver
является управляющей программой для Unix-подобных
систем, которая позволяет вам установить соединение вашей программы с
удаленным GDB посредством target remote
, но без
компоновки с обычной отладочной заглушкой.
gdbserver
не является полной заменой отладочных заглушек, потому что
требует по существу тех же средств операционной системы, что и сам
GDB. Фактически, система, на которой может выполняться
gdbserver
для соединения с удаленным GDB, может также
выполнять GDB локально! Тем не менее, gdbserver
иногда
полезен, так как по размеру эта программа гораздо меньше, чем
GDB. gdbserver
также легче переносить, чем
весь GDB, так что вы сможете быстрее начать работать в новой системе,
используя его. Наконец, если вы разрабатываете программы для
систем реального времени, вы можете обнаружить, что накладные расходы,
связанные с операциями реального времени, делают более удобным
проведение всей возможной разработки на другой системе, например, с помощью
кросс-компиляции. Вы можете использовать gdbserver
, чтобы
реализовать аналогичный выбор для отладки.
GDB и gdbserver
общаются или через последовательную
линию, или через соединение TCP, используя стандартный удаленный
последовательный протокол GDB.
gdbserver
не нуждается в таблице символов вашей программы, так
что вы можете ее исключить, если необходимо сохранить
пространство. Всю обработку символов осуществляет GDB на
рабочей машине.
Чтобы использовать сервер, вы должны сообщить ему, как взаимодействовать с
GDB, имя вашей программы и ее аргументы. Синтаксис следующий:
target> gdbserver comm программа [ арг ... ]comm---это или имя устройства (для использования последовательной линии), или имя рабочей машины и номер порта TCP. Например, для отладки Emacs с параметром `foo.txt' и взаимодействия с GDB через последовательный порт `/dev/com1':
target> gdbserver /dev/com1 emacs foo.txt
gdbserver
пассивно ждет рабочего GDB для связи с ним.
При использовании TCP-соединения вместо последовательной линии:
target> gdbserver host:2345 emacs foo.txtЕдинственное отличие от предыдущего примера состоит в первом параметре, определяющем, что вы связываетесь с рабочим GDB через TCP. Параметр `host:2345' означает, что
gdbserver
должен ожидать
TCP-соединение от машины `host' к локальному порту TCP 2345. (В
настояшее время часть `host' игнорируется.) Вы можете выбрать
любой номер порта, какой захотите, если при этом он не конфликтует с
какими-либо портами TCP, уже использующимися на целевой системе
(например, 23
зарезервирован для telnet
).(15) Вы
должны использовать тот же номер порта с командой рабочего GDB
target remote
.
target remote
,
чтобы установить связь с gdbserver
. Ее параметры---либо
имя устройства (обычно последовательного устройства, такого как
`/dev/ttyb'), либо дескриптор порта TCP в форме
машина:порт
. Например:
(gdb) target remote /dev/ttybвзаимодействует с сервером через последовательную линию `/dev/ttyb', а
(gdb) target remote the-target:2345взаимодействует через TCP-соединение с портом 2345 на рабочей машине `the-target'. Для TCP-соединения, вы должны запустить
gdbserver
до использования команды target remote
. Иначе
вы можете получить ошибку, текст которой зависит от рабочей системы, но
обычно он выглядит примерно так: `Connection refused'.
gdbserve.nlm
gdbserve.nlm
---это управляющая программа для систем NetWare,
которая позволяет вам установить соединение вашей программы с
удаленным GDB посредством target remote
.
GDB и gdbserve.nlm
общаются через последовательную линию,
используя стандартный удаленный последовательный протокол GDB.
gdbserve.nlm
не нуждается в таблице символов вашей программы,
так что вы можете ее исключить, если необходимо сохранить пространство.
GDB осуществляет всю обработку символов на рабочей машине.
Чтобы использовать сервер, вы должны сообщить ему как взаимодействовать с
GDB, имя вашей программы и ее аргументы. Синтаксис следующий:
load gdbserve [ BOARD=плата ] [ PORT=порт ] [ BAUD=бод ] программа [ арг ... ]Плата и порт определяют последовательную линию; бод определяет скорость в бодах, используемую соединением. Значения порт и node по умолчанию равны 0, бод по умолчанию 9600бит/сек. Например, для отладки Emacs с параметром `foo.txt' и взаимодействия с GDB через последовательный порт номер 2 на плате 1, используя соединение 19200бит/сек:
load gdbserve BOARD=1 PORT=2 BAUD=19200 emacs foo.txt
target
remote
для установки связи с gdbserve.nlm
. Ее
аргумент---имя устройства (обычно последовательного устройства,
такого как `/dev/ttyb'). Например:
(gdb) target remote /dev/ttybсоединение с сервером через последовательную линию `/dev/ttyb'.
Некоторые цели поддерживают отображение объектов ядра. При помощи этих возможностей, GDB взаимодействует непосредственно с операционной системой и может выводить информацию об объектах уровня операционной системы, например, о блокировках и других объектах синхронизации. Какие именно объекты могут быть отображены, определяется в зависимости от конкретной ОС.
Используйте команду set os
, чтобы установить тип операционной
системы. Это говорит GDB, какой модуль отображения объектов
ядра инициализировать:
(gdb) set os cisco
Если команда set os
выполнится успешно, GDB выведет
некоторую информацию об операционной системе, и создаст новую команду
info
, которая может быть использована для посылки запросов на
целевую машину. Название команды info
выбирается в зависимости
от операционной системы:
(gdb) info cisco List of Cisco Kernel Objects Object Description any Any and all objects
Дальнейшие подкоманды могут использоваться для запросов о конкретных объектах, информация о которых есть в ядре.
В настоящее время не существует другого способа определить, поддерживается та или иная операционная система, кроме как попробовать.
В то время как почти все команды GDB доступны для всех чистых и кросс-версий отладчика, существуют некоторые исключения. Эта глава описывает вещи, доступные только в определенных конфигурациях.
Существует три основные категории конфигураций: чистые конфигурации, где рабочая и целевая машины совпадают, конфигурации для встроенных операционных систем, которые обычно совпадают для нескольких различных архитектур процессоров, и отдельные встроенные процессоры, которые сильно отличаются друг от друга.
Этот раздел описывает детали, специфичные для определенных чистых конфигураций.
В системах HP-UX, если вы ссылаетесь на функцию или переменную, имя которой начинается со знака доллара, GDB сперва ищет имя пользователя или системы, до поиска вспомогательной переменной.
Многие версии SVR4 предоставляют возможность, называемую
`/proc', которая может быть использована для исследования образа
выполняемого процесса, используя подпрограммы файловой системы. Если
GDB сконфигурирован для операционной системы, поддерживающей
эту возможность, команда info proc
доступна для получения отчета
по некоторым видам информации о процессе, выполняющем вашу программу.
info proc
работает только на системах SVR4, которые включают код
procfs
. Среди этих систем: OSF/1 (Digital Unix), Solaris,
Irix и Unixware, но не HP-UX или Linux, к примеру.
info proc
info proc mappings
info proc times
info proc id
info proc status
info proc all
Этот раздел описывает конфигурации, задействующие отладку встроенных операционных систем, которые доступны для нескольких различных архитектур.
GDB включает возможность отлаживать программы, выполняющиеся в различных операционных системах реального времени.
target vxworks имя-машины
На VxWorks, load
компонует имя-файла динамически на текущей
целевой системе, и добавляет ее символьную информацию в GDB.
GDB позволяет разработчикам запускать и отлаживать с Unix-машин
задачи, выполняющиеся на сетевых целях VxWorks. Уже выполняющиеся
задачи, запущенные из оболочки VxWorks, также могут быть отлажены.
GDB использует код, который может выполняться как на машине
Unix, так и на целевой машине VxWorks. Программа gdb
устанавливается и выполняется на Unix-машине. (Она может быть
установлена под именем vxgdb
, чтобы отличать ее от GDB
для отладки программ на рабочей машине.)
VxWorks-timeout арг
vxworks-timeout
. Этот параметр устанавливается пользователем, и
арг представляют число секунд, в течение которых GDB
ожидает ответы
на вызовы удаленных процедур. Вы можете использовать это, если ваша
целевая машина VxWorks является медленным программным эмулятором, или
находится далеко на другом конце медленного сетевого соединения.
Следующая информация о соединении к VxWorks была свежей, когда это руководство было написано; более новые выпуски VxWorks могут использовать обновленные процедуры.
Для использования GDB с VxWorks, вы должны пересобрать ваше
ядро VxWorks, чтобы включить подпрограммы интерфейса удаленной отладки в
библиотеку VxWorks `rdb.a'. Чтобы это сделать, определите
INCLUDE_RDB
в конфигурационном файле VxWorks `configAll.h' и
пересоберите ядро VxWorks. Получившееся ядро содержит `rdb.a', и
порождает задачу отладки исходного кода tRdbTask
, когда VxWorks
загружается. Для большей информации по конфигурированию и сборке
VxWorks, смотрите руководство изготовителя.
Когда вы включили `rdb.a' в образ вашей системы VxWorks и так
установили ваши пути поиска выполняемых файлов, чтобы можно было найти
GDB, вы готовы к вызову отладчика. Из вашей рабочей
Unix-машины, выполните gdb
(или vxgdb
, в
зависимости от вашей установки).
GDB появляется и показывает приглашение:
(vxgdb)
Команда GDB target
позволяет вам соединяться с целевой
машиной VxWorks в сети. Для соединения с целью, имя которой есть
"tt
", введите:
(vxgdb) target vxworks tt
GDB покажет сообщения, аналогичные этим:
Attaching remote machine across net... Connected to tt.
Затем GDB пытается считать таблицы символов всех объектных модулей, загруженных на целевой машине VxWorks с того момента, как она была включена. GDB находит эти файлы путем поиска в каталогах, перечисленных в путях поиска команд (see section Рабочая среда вашей программы); если ему не удается найти объектный файл, он выводит подобное сообщение:
prog.o: No such file or directory.
Когда это происходит, добавьте соответствующий каталог к путям поиска с
помощью команды GDB path
, и выполните команду
target
снова.
Если вы соединились с целевой машиной VxWorks и хотите отладить объект,
который еще не был загружен, вы можете использовать команду GDB
load
, чтобы загрузить файл из Unix в VxWorks. Объектный файл,
заданный в качестве аргумента к load
, в действительности
открывается дважды: сначала целевой машиной VxWorks, чтобы загрузить код,
а затем GDB, чтобы считать таблицу символов. Это может
привести к проблемам, если текущие рабочие каталоги в этих системах
различаются. Если обе системы монтируют по NFS одинаковые
файловые системы, вы можете избежать этих проблем, используя абсолютные
пути. В противном случае, проще всего установить рабочий каталог на
обеих системах в тот, в котором расположен объектный файл, и затем
ссылаться на него по имени, без пути. Например, программа
`prog.o' может находиться в `vxpath/vw/demo/rdb' на
VxWorks и в `hostpath/vw/demo/rdb' на рабочей машине. Для
загрузки этой программы, введите в VxWorks следующее:
-> cd "vxpath/vw/demo/rdb"
Затем, в GDB, введите:
(vxgdb) cd hostpath/vw/demo/rdb (vxgdb) load prog.o
GDB отобразит ответ, аналогичный этому:
Reading symbol data from wherever/vw/demo/rdb/prog.o... done.
Вы также можете использовать команду load
, чтобы заново загрузить
объектный модуль, после редактирования и повторной компиляции соответствующего
исходного файла. Заметьте, что при этом GDB удаляет все
определенные точки останова, автоматические отображения, вспомогательные
переменные, и очищает историю значений. (Это необходимо для того, чтобы
сохранить целостность структур данных отладчика, которые ссылаются
на таблицу символов целевой системы.)
Вы также можете присоединиться к существующей задаче, используя команду
attach
следующим образом:
(vxgdb) attach задача
где задача является шестнадцатеричным идентификатором задачи VxWorks. Когда вы присоединяетесь к задаче, она может выполняться либо быть приостановленной. Выполняющаяся задача приостанавливается в момент присоединения.
Этот раздел описывает детали, специфичные для определенных встроенных конфигураций.
target adapt устр
target amd-eb устр скорость прог
target remote
; скорость
позволяет вам указать скорость линии; а прог является именем
программы, которая будет отлаживаться, так, как оно появляется в ДОС на ПК.
See section Протокол EBMON для AMD29K.
Для отладки процессоров семейства a29k, GDB поддерживает
протокол AMD UDI ("Universal Debugger
Interface"(16)). Для использования
этой конфигурации с целями AMD, на которых выполняется монитор MiniMON,
вам нужна программа MONTIP
, доступная бесплатно у AMD. Вы можете
также использовать GDB с программой ISSTIP
,
UDI-совместимым эмулятором a29k, также доступным у AMD.
target udi кл-слово
AMD распространяет плату разработки 29K, предназначенную для помещения в
ПК, вместе с программой монитора EBMON
, работающей в ДОС. Коротко эта
система разработки называется "EB29K". Чтобы использовать
GDB из Unix-системы для выполнения программ на плате EB29K, вы
должны сперва соединить последовательным кабелем ПК (в котором
установлена плата EB29K) и последовательный порт на Unix-системе. Далее
мы предполагаем, что вы соединили кабелем порт ПК `COM1' и
`/dev/ttya' на Unix-системе.
Следующим шагом нужно установить параметры порта ПК, сделав в ДОС что-то вроде этого:
C:\> MODE com1:9600,n,8,1,none
Этот пример, выполненный в системе MS DOS 4.0, устанавливает порт ПК в 9600бит/сек, без проверки четности, восьмибитные данные, один стоп-бит и отсутствие действия для "повтора"; вы должны использовать те же параметры связи при установке соединения со стороны Unix.
Чтобы передать управление с ПК стороне Unix, введите следующее в консоли ДОС:
C:\> CTTY com1
(Позже, если вы хотите вернуть управление консоли ДОС, вы можете
использовать команду CTTY con
---но вы должны послать ее через
устройство, имевшее управление, в нашем примере через последовательную
линию `COM1'.)
На Unix-машине, для связи с ПК используйте коммуникационную программу,
такую как tip
или cu
. Например
cu -s 9600 -l /dev/ttya
Показанные ключи для cu
определяют, соответственно, скорость
линии и последовательный порт. Если вместо этого вы используете
tip
, ваша командная строка может выглядеть следующим образом:
tip -9600 /dev/ttya
Ваша система может требовать другого имени в том месте, где мы
показываем `/dev/ttya' в качестве аргумента к tip
.
Параметры связи, включая используемый порт, ассоциированы с аргументом к
tip
в файле описаний "remote"---обычно это `/etc/remote'.
Используя соединение tip
или cu
, измените рабочий каталог
ДОС в тот, который содержит копию вашей программы 29K, затем запустите
на ПК программу EBMON
(управляющая программа EB29K, поставляемая
AMD с вашей платой). Вы должны увидеть начальный вывод EBMON
,
аналогичный следующему, заканчивающийся приглашением EBMON
`#':
C:\> G: G:\> CD \usr\joe\work29k G:\USR\JOE\WORK29K> EBMON Am29000 PC Coprocessor Board Monitor, version 3.0-18 Copyright 1990 Advanced Micro Devices, Inc. Written by Gibbons and Associates, Inc. Enter '?' or 'H' for help PC Coprocessor Type = EB29K I/O Base = 0x208 Memory Base = 0xd0000 Data Memory Size = 2048KB Available I-RAM Range = 0x8000 to 0x1fffff Available D-RAM Range = 0x80002000 to 0x801fffff PageSize = 0x400 Register Stack Size = 0x800 Memory Stack Size = 0x1800 CPU PRL = 0x3 Am29027 Available = No Byte Write Available = Yes # ~.
Затем выйдите из программы cu
или tip
(в этом примере это
сделано при помощи ввода ~.
в приглашении EBMON
).
EBMON
продолжает работать, готовый к тому, что GDB
перехватит управление.
Для этого примера, мы предположили, что существует соединение PC/NFS, которое устанавливает файловую систему Unix-машины как "диск `G:'" на ПК. Это является, вероятно, самым удобным способом удостовериться, что одна и та же программа 29K находится и на ПК, и в Unix-системе. Если у вас нет PC/NFS или чего-нибудь аналогичного, соединяющего две системы, вы должны прибегнуть к другому способу передачи программы 29K из Unix на ПК---возможно переписать ее на дискету. GDB не загружает программы по последовательной линии.
Наконец, перейдите в каталог, содержащий образ вашей программы 29K в Unix-системе, и запустите GDB, указав имя программы в качестве аргумента:
cd /usr/joe/work29k gdb myfoo
Теперь вы можете использовать команду target
:
target amd-eb /dev/ttya 9600 MYFOO
В этом примере мы предполагали, что ваша программа находится в файле
`myfoo'. Заметьте, что имя файла, заданное в качестве последнего
аргумента к target amd-eb
, должно быть таким, каким его видит
ДОС. В нашем примере, это просто MYFOO
, но вообще оно может
включать путь ДОС, и, в зависимости от механизма передачи, может быть
не похоже на имя на Unix-машине.
В этом месте вы можете установить желаемые точки останова; когда вы
будете готовы увидеть вашу программы выполняющейся на плате 29K,
используйте команду GDB run
.
Чтобы остановить отладку удаленной программы, используйте команду
GDB detach
.
Чтобы возвратить управление консоли ПК, используйте tip
или
cu
снова, после завершения вашего сеанса GDB, чтобы
присоединиться к EBMON
. Затем вы можете ввести команду q
,
чтобы завершить работу EBMON
, возвращая управление командному
интерпретатору ДОС. Введите CTTY con, чтобы возвратить командный
ввод основной консоли ДОС, и введите ~., чтобы покинуть tip
или cu
.
Команда target amd-eb
создает в текущем рабочем каталоге файл
`eb.log', чтобы помочь отладить проблемы с соединением.
`eb.log' записывает весь вывод `EBMON', включая эхо
посланных ему команд. Выполнение `tail -f' для этого файла в другом
окне часто помогает понять проблемы с EBMON
, или неожиданные
события на стороне ПК.
target rdi устр
target rdp устр
target hms устр
device
и speed
для управления последовательной линией и
используемой скоростью связи.
target e7000 устр
target sh3 устр
target sh3e устр
Когда вы выбираете удаленную отладку для платы Hitachi SH, H8/300 или
H8/500, команда load
загружает вашу программу на плату Hitachi, и
также открывает ее как текущую выполняемую цель для GDB на
вашей машине (как команда file
).
Для общения с вашим Hitachi SH, H8/300 или H8/500, GDB необходимо знать следующие вещи:
Используйте специальную команду GDB `device порт', если вам нужно явно установить последовательное устройство. По умолчанию используется первый порт, доступный на вашей машине. Это необходимо только на Unix-машинах, где это обычно что-то типа `/dev/ttya'.
GDB имеет другую специальную команду для установки скорости
связи: `speed bps'. Эта команда также используется только на
Unix-машинах; в ДОС, устанавливайте скорость линии как обычно извне
GDB командой mode
(например,
mode com2:9600,n,8,1,p для соединения 9600бит/сек.
Команды `device' и `speed' доступны для отладки программ
микропроцессора Hitachi, только если вы используете рабочую среду Unix.
Если вы используете ДОС, для взаимодействия с платой разработки через
последовательный порт ПК GDB полагается на вспомогательную
резидентную программу asynctsr
. Вы также должны использовать
команду ДОС mode
, чтобы подготовить порт со стороны ДОС.
Следующий пример сеанса иллюстрирует шаги, необходимые для запуска программы на H8/300 под управлением GDB. В нем используется программа H8/300 под названием `t.x'. Для Hitachi SH и H8/500 процедура та же самая.
Сперва подсоедините вашу плату разработки. В этом примере, мы
используем плату, присоединенную к порту COM2
. Если вы
используете другой последовательный порт, подставьте его имя в агрументе
команды mode
. Когда вы вызываете asynctsr
,
вспомогательную программу связи, используемую отладчиком, вы передаете
ей только числовую часть имени последовательного порта; например, ниже
`asynctsr 2' запускает asynctsr
для COM2
.
C:\H8300\TEST> asynctsr 2 C:\H8300\TEST> mode com2:9600,n,8,1,p Resident portion of MODE loaded COM2: 9600, n, 8, 1, p
Предупреждение: Мы обнаружили ошибку в PC-NFS, которая конфликтует с
asynctsr
. Если вы также используете PC-NFS на вашей ДОС-машине, вам может потребоваться отключить его, или даже загрузить машину без него, чтобы использоватьasynctsr
для управления отладочной платой.
Теперь, когда связь установлена и плата разработки присоединена, вы
можете запустить GDB. Вызовите gdb
с именем
вашей программы в качестве аргумента. GDB выводит
обычное приглашение: `(gdb)'. Используйте две специальные
команды для начала сеанса отладки: `target hms' для задания
кросс-отладки для платы Hitachi, и команду load
для загрузки вашей
программы на нее. load
выводит имена разделов программы, и
`*' для каждых двух килобайт загруженных данных. (Если вы хотите
обновить данные GDB для символов или для выполняемого файла без
загрузки, используйте команды GDB file
или
symbol-file
. Для описания этих команд, равно как и самой команды
load
, см. section Команды для задания файлов.)
(eg-C:\H8300\TEST) gdb t.x GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 5.0, Copyright 1992 Free Software Foundation, Inc... (gdb) target hms Connected to remote H8/300 HMS system. (gdb) load t.x .text : 0x8000 .. 0xabde *********** .data : 0xabde .. 0xad30 * .stack : 0xf000 .. 0xf014 *
Теперь вы готовы выполнять или отлаживать вашу программу. С этого
момента, вы можете использовать все обычные команды GDB. Команда
break
устанавливает точки останова; run
запускает вашу
программу; print
или x
отображает данные; команда
continue
возобновляет выполнение после остановки в точке
останова. Вы можете использовать команду help
в любой момент,
чтобы узнать больше о командах GDB.
Помните, однако, что возможности операционной системы не доступны на вашей плате разработки; например, если ваша программа зависает, вы не можете послать сигнал прерывания---но можете нажать кнопку RESET!
Используйте кнопку RESET на вашей плате разработки
В любом случае, GDB видит результат нажатия RESET на плате разработки как "нормальное завершение" вашей программы.
Вы можете использовать встроенный эмулятор E7000 для разработки кода либо для Hitachi SH, либо для H8/300H. Используйте одну из этих форм команды `target e7000' для соединения GDB с вашей E7000:
target e7000 порт скорость
target e7000 имя-узла
telnet
.
Некоторые команды GDB доступны только для H8/300:
set machine h8300
set machine h8300h
set memory мод
show memory
small
, big
, medium
и compact
.
target mon960 устр
target nindy имя-устр
Nindy---это программа ROM Monitor для целевых систем Intel 960. Когда GDB сконфигурирован для управления удаленным Intel 960 с использованием Nindy, вы можете указать ему, как присоединиться к 960 несколькими способами:
target
в любом месте вашего сеанса
GDB. See section Команды для управления целями.
С интерфейсом Nindy к плате Intel 960, команда load
загружает
имя-файла на 960, а также добавляет его символьные данные в
GDB.
Если вы просто запустите gdb
без использования ключей
командной строки, у вас запросят, какой последовательный порт
использовать, до того, как вы получите обычное приглашение
GDB:
Attach /dev/ttyNN -- specify NN, or "quit" to quit:
Ответьте на запрос с любым суффиксом (после `/dev/tty'),
определяющим последовательный порт, который вы хотите использовать. Вы
можете, по своему выбору, просто начать работу без соединения с
Nindy, ответив на приглашение пустой строкой. Если вы сделаете это и позже
захотите присоединиться к Nindy, используйте target
(see section Команды для управления целями).
Вот параметры вызова для начала вашего сеанса GDB с подключенной платой Nindy-960:
-r порт
tty
(например, `-r a').
-O
Предупреждение: если вы определите `-O', но в действительности попытаетесь связаться с системой, которая ожидает более нового протокола, соединение не будет установлено, как будто не соответствуют скорости. GDB неоднократно пытается соединиться снова на нескольких различных скоростях линии. Вы можете остановить этот процесс посредством прерывания.
-brk
BREAK
, пытаясь сбросить ее, перед соединением с целью
Nindy.
Предупреждение: Многие целевые системы не имеют требуемых для этого аппаратных средств; это работает только на немногих платах.
Стандартный ключ `-b' управляет скоростью линии, используемой на последовательном порту.
reset
target m32r устр
Конфигурация Motorola m68k включает поддержку ColdFire, и команду
target
для следующих мониторов ROM.
target abug устр
target cpu32bug устр
target dbug устр
target est устр
target rom68k устр
Если GDB сконфигурирован с m68*-ericsson-*
, то вместо
этого у него будет только одна специальная команда target
:
target es1800 устр
target rombug устр
target bug устр
GDB может использовать удаленный отладочный протокол MIPS для взаимодействия с платой MIPS, присоединенной к последовательной линии. Эта возможность доступна, если вы сконфигурировали GDB с `--target=mips-idt-ecoff'.
Используйте эти команды GDB для определения соединения с вашей целевой платой:
target mips порт
gdb
, задав
имя программы в качестве аргумента. Для соединения с платой,
используйте команду `target mips порт', где порт---имя
последовательного порта, присоединенного к плате. Если программа еще не
была загружена на плату, вы можете использовать команду load
,
чтобы это сделать. Затем вы можете использовать все обычные команды
GDB.
Например, эта последовательность команд устанавливает соединение к
целевой плате через последовательный порт, загружает и начинает
выполнение из отладчика программы с именем prog:
host$ gdb prog GDB is free software and ... (gdb) target mips /dev/ttyb (gdb) load prog (gdb) run
target mips имя-машины:номер-порта
target pmon порт
target ddb порт
target lsi порт
target r3900 устр
target array устр
GDB также поддерживает следующие специальные команды для целей MIPS:
set processor арг
show processor
set processor
для установки типа процессора
MIPS, когда вы хотите обратиться к регистрам, уникальным для данного
типа процессора. Например, set processor r3041
велит
GDB использовать регистры CPO, соответствующие микросхеме
3041. Используйте команду show processor
, чтобы узнать, какой
процессор MIPS используется GDB. Используйте команду
info reg
чтобы узнать, какие регистры использует GDB.
set mipsfpu double
set mipsfpu single
set mipsfpu none
show mipsfpu
mipsfpu
при
помощи `show mipsfpu'.
set remotedebug n
show remotedebug
remotedebug
. Если вы установите ее
в 1
при помощи `set remotedebug 1', будет отображаться
каждый пакет. Если вы установите ее в 2
, то будет отображаться
каждый символ. В любой момент вы можете проверить текущее значение
переменной командой `show remotedebug'.
set timeout секунды
set retransmit-timeout секунды
show timeout
show retransmit-timeout
set timeout секунды
.
Значение по умолчанию---5 секунд. Аналогично, вы можете управлять
временем ожидания, используемом при ожидании подтверждения пакета с
помощью команды set retransmit-timeout секунды
. По
умолчанию 3 секунды. Вы можете узнать обе эти величины с помощью
show timeout
и show retransmit-timeout
. (Эти команды
доступны только если GDB сконфигурирован для цели
`--target=mips-idt-ecoff'.)
Время ожидания, установленное при помощи set timeout
, не имеет
значения, когда GDB ожидает остановки вашей программы. В этом
случае, GDB ждет бесконечно, потому что у него нет способа
узнать, сколько программа будет выполняться, пока не остановится.
target dink32 устр
target ppcbug устр
target ppcbug1 устр
target sds устр
target op50n устр
target w89k устр
target hms устр
device
и
speed
для управления последовательной линией и используемой
скоростью связи.
target e7000 устр
target sh3 устр
target sh3e устр
GDB позволяет разработчикам отлаживать с Unix-машины задачи,
выполняющиеся на целевых системах Sparclet. GDB использует код,
который выполняется как Unix-машине, так и на цели Sparclet. Программа
gdb
устанавливается и работает на Unix-машине.
remotetimeout арг
remotetimeout
. Он
устанавливатся пользователем, а арг представляет число секунд, в
течение которых GDB ожидает ответы.
При компиляции для отладки, используйте ключи `-g' для получения отладочной информации, и `-Ttext' для того, чтобы разместить программу в том месте, в каком вы хотите загрузить ее на целевую машину. Вы также можете добавить ключ `-n' или `-N', чтобы уменьшить размеры разделов. Например:
sparclet-aout-gcc prog.c -Ttext 0x12010000 -g -o prog -N
Для проверки, что адреса в действительности являются теми, которые вы
подразумевали, можно использовать objdump
:
sparclet-aout-objdump --headers --syms prog
После того, как вы установили путь поиска выполняемых файлов, в котором
присутствует GDB, вы готовы запустить отладчик. С вашей
рабочей машины Unix, выполните gdb
(или
sparclet-aout-gdb
, в зависимости от вашей установки).
GDB запустится и покажет приглашение:
(gdbslet)
Команда GDB file
позволяет вам выбрать программу для
отладки.
(gdbslet) file prog
Затем GDB пытается прочитать таблицу символов программы `prog'. Он находит файл путем поиска в каталогах, перечисленных в пути поиска команд. Если файл был скомпилирован с отладочной информацией (ключ `-g'), то также будет произведен поиск исходных файлов. GDB находит исходные файлы, производя поиск в каталогах, перечисленных в пути поиска каталогов (see section Рабочая среда вашей программы). Если ему не удается найти файл, он выводит сообщение, подобное этому:
prog: No such file or directory.
Когда это случается, добавьте соответствующие каталоги в пути поиска с
помощью команд GDB path
и dir
, и выполните
команду target
снова.
Команда GDB target
позволяет вам установить
соединение с целевой машиной Sparclet. Для соединения с
последовательным портом "ttya
", введите:
(gdbslet) target sparclet /dev/ttya Remote target sparclet connected to /dev/ttya main () at ../prog.c:3
GDB выведет сообщение, подобное этому:
Connected to ttya.
Когда вы установили соединение к цели Sparclet, вы можете использовать
команду GDB load
для загрузки файла с рабочей машины на
целевую. Имя файла и смещение загрузки должно быть задано команде
load
в качестве аргумента. Так как формат файла aout, программа
должна быть загружена по начальному адресу. Чтобы определить, чему
равна эта величина, вы можете использовать objdump
. Смещение
загрузки---это смещение, которое добавляется к VMA (Virtual Memory
Address(17))
каждого раздела файла.
Например, если программа `prog' была скомпонована с адресом текста
0x1201000, сегментом данных по адресу 0x12010160 и сегментом стека по
адресу 0x12010170, введите в GDB:
(gdbslet) load prog 0x12010000 Loading section .text, size 0xdb0 vma 0x12010000
Если код загружается по адресу, отличному от того, по которому программа
была скомпонована, вам может потребоваться использовать команды
section
и add-symbol-file
, чтобы сообщить GDB,
куда отобразить таблицу символов.
Теперь вы можете начать отлаживать задачу, используя команды
GDB для управления выполнением, b
, step
,
run
, и так далее. Все такие команды перечислены в этом
руководстве.
(gdbslet) b main Breakpoint 1 at 0x12010000: file prog.c, line 3. (gdbslet) run Starting program: prog Breakpoint 1, main (argc=1, argv=0xeffff21c) at prog.c:3 3 char *symarg = 0; (gdbslet) step 4 char *execarg = "hello!"; (gdbslet)
target sparclite устр
GDB может быть использован с телефонным коммутатором Tandem ST2000, поддерживающим протокол Tandem STDBUG.
Для соединения вашего ST2000 с рабочей машиной, смотрите руководство производителя. После того, как ST2000 физически подключен, вы можете выполнить:
target st2000 устр скорость
чтобы установить его как вашу отладочную среду. Устр---это обычно
имя последовательного устройства, такое как `/dev/ttya',
соединенного с ST2000 через последовательную линию. Вместо этого, вы
можете указать устр как TCP-соединение (например, к
последовательной линии, присоединенной через терминальный концентратор),
используя синтаксис имя-машины:номер-порта
.
Команды load
и attach
не определены для этой цели;
вы должны загрузить вашу программу на ST2000 также, как вы это обычно
делаете для автономных действий. GDB читает отладочную
информацию (например, символы) из отдельной, отладочной версии
программы, которая доступна на вашем рабочем компьютере.
Следующие вспомогательные команды GDB доступны для облегчения работы в среде ST2000:
st2000 команда
connect
Будучи сконфигурированным для отладки целей Zilog Z8000, GDB включает имитатор Z8000.
Для семейства Z8000, `target sim' имитирует либо Z8002 (не сегментированный вариант архитектуры Z8000), либо Z8001 (сегментированный вариант). Имитатор распознает подходящую архитектуру изучая объектный код.
target sim арг
После определения этой цели, вы можете отлаживать программы для
имитированного ЦП таким же образом, как программы для вашего рабочего
компьютера; используйте команду file
для загрузки образа новой
программы, команду run
для запуска вашей программы, и так далее.
Помимо того, что доступны все обычные машинные регистры (see section Регистры), имитатор Z8000 предоставляет три специально названных регистра с дополнительной информацией:
cycles
insts
time
Вы можете ссылаться на эти значения в выражениях GDB с помощью обычных соглашений; например, `b fputc if $cycles>5000' устанавливает условную точку останова, которая срабатывает только после как минимум 5000 имитированных тактовых импульсов.
Этот раздел описывает свойства архитектур, которые воздействуют на все применения GDB с данной архитектурой, как при чистой отладке, так и при кросс-отладке.
set rstack_high_address адрес
set
rstack_high_address
. Аргумент должен быть адресом, который вы,
вероятно, захотите начать с `0x', чтобы задать его в
шестнадцатеричном виде.
show rstack_high_address
Смотрите следующий раздел.
Компьютеры, базирующиеся на архитектурах Alpha и MIPS, используют необычный кадр стека, который иногда требует от GDB поиска в объектном коде в обратном направлении, чтобы найти начало функции.
Чтобы сократить время ответа (особенно для встроенных приложений, где GDB может быть ограничен медленной последовательной линией для этого поиска), вы можете захотеть ограничить область поиска, используя одну из этих команд:
set heuristic-fence-post предел
heuristic-fence-post
должен просмотреть, и,
следовательно, тем дольше он будет выполняться.
show heuristic-fence-post
Эти команды доступны только когда GDB сконфигурирован для отладки программ на процессорах Alpha или MIPS.
Вы можете изменять способы взаимодействия GDB с вами, используя
команду set
. Для команд, управляющих способами отображения
данных GDB, смотрите section Параметры вывода.
Другие установки описаны здесь.
GDB демонстрирует свою готовность считать команду, выводя строку,
называемую приглашением. Обычно это `(gdb)'. Вы
можете изменить строку приглашения командой set prompt
.
Например, при отладке GDB с помощью GDB, полезно
изменить приглашение в одном из сеансов так, чтобы вы всегда могли
понять, с каким из них вы общаетесь.
Замечание: set prompt
не добавляет пробелы после установленного
вами приглашения. Это позволяет устанавливать приглашение,
заканчивающееся пробелом или нет.
set prompt новое-пригл
show prompt
GDB читает входные команды через интерфейс readline. Эта
библиотека GNU обеспечивает согласованное поведение для программ,
которые предоставляют пользователю интерфейс командной строки.
Преимуществами являются стили редактирования командной строки GNU
Emacs или vi, csh
-подобная подстановка истории
и сохранение и повторное использование истории команд между сеансами отладки.
Вы можете управлять поведением редактирования командной строки в
GDB командой set
.
set editing
set editing on
set editing off
show editing
GDB может отслеживать команды, которые вы вводите во время сеансов отладки, чтобы вы могли точно знать, что происходило. Используйте следующие команды для управления возможностями истории команд GDB.
set history filename имя-файла
GDBHISTFILE
, или, если эта переменная не установлена,
`./.gdb_history' (`./_gdb_history' в MS-DOS).
set history save
set history save on
set history filename
. По умолчанию, эта возможность
отключена.
set history save off
set history size размер
HISTSIZE
, или приравнивается 256, если эта переменная не установлена.
Раскрывание истории назначает специальное значение знаку !.
Так как ! является также оператором логического отрицания в Си,
раскрывание истории по умолчанию отключено. Если вы решите включить
раскрывание истории командой set history expansion on
, вы должны
будете снабдить ! (когда он используется как логическое отрицание в
выражении) последующим пробелом или символом табуляции, чтобы предохранить
его от раскрывания. Средства истории Readline не делают попытки подстановки
на строках != и !(, даже когда раскрывание истории включено.
Вот команды управления раскрыванием истории:
set history expansion on
set history expansion
set history expansion off
vi
, могут почитать ее.
show history
show history filename
show history save
show history size
show history expansion
show history
показывает все четыре состояния.
show commands
show commands n
show commands +
Определенные команды GDB могут выводить большое количество информации на экран. Чтобы помочь вам всю ее прочитать, GDB приостанавливает вывод и запрашивает ввод в конце каждой страницы вывода. Нажмите RET, когда вы хотите продолжить вывод, или q для уничтожения оставшегося вывода. Также, установка ширины экрана определяет, когда переносить строки вывода. В зависимости от того, что выводится, GDB пытается разбить стpоку в удобочитаемом месте, вместо того чтобы просто продолжить ее на следующую строчку.
Обычно GDB узнает размер экрана из программы драйвера
терминала. Например, в Unix GDB использует базу данных
termcap, вместе со значением переменной среды TERM
и
установками stty rows
и stty cols
. Если это неправильно,
вы можете заменить эти установки командами set height
и
set width
:
set height lpp
show height
set width cpl
show width
set
определяют высоту экрана в lpp строк и ширину
в cpl знаков. Соответствующие команды show
отображают
текущие установки.
Если вы определите высоту в ноль строк, GDB не будет
останавливаться при выводе, независимо от того, насколько он длинный.
Это полезно, если вывод осуществляется в файл или буфер редактора.
Аналогично, вы можете определить `set width 0', чтобы запретить
GDB переносить строки вывода.
Вы всегда можете вводить в GDB числа в восьмеричной,
десятичной, или шестнадцатеричной системе в соответствии c обычными
соглашениями: восьмеричные числа начинаются с `0', десятичные числа
оканчиваются на `.' и шестнадцатеричные числа начинаются с
`0x'. Числа, которые не начинаются ни c одного из этих знаков, по
умолчанию считаются десятичными; аналогично, отображение чисел по
умолчанию---если не определен никакой конкретный формат---осуществляется
по основанию 10. Командой set radix
вы можете изменять
основание, устанавливаемое по умолчанию для ввода и вывода.
set input-radix основание
set radix 012 set radix 10. set radix 0xaустанавливает десятичное основание. С другой стороны, `set radix 10' оставляет основание системы счисления без изменений независимо от того, каким оно было.
set output-radix основание
show input-radix
show output-radix
По умолчанию, GDB ничего не сообщает о своей внутренней
деятельности. Если вы работаете на медленной машине, то вы можете захотеть
использовать команду set verbose
. Она велит GDB
сообщать вам, когда он выполняет длинную внутреннюю операцию, чтобы вы
не думали, что он завис.
В настоящее время, set verbose
управляет только
сообщениями о чтении таблиц символов исходного файла; смотрите
section Команды для задания файлов, описание symbol-file
.
set verbose on
set verbose off
show verbose
set verbose
в on
или off
.
По умолчанию, если GDB сталкивается с ошибками в таблице символов объектного файла, он не сообщает об этом; но если вы отлаживаете компилятор, эта информация может вам пригодиться (see section Ошибки чтения файлов с символами).
set complaints предел
show complaints
По умолчанию GDB осмотрителен, и задает, как иногда кажется, множество глупых вопросов, чтобы подтвердить определенные команды. Например, если вы пытаетесь выполнить программу, которая уже выполняется:
(gdb) run The program being debugged has been started already. Start it from the beginning? (y or n)
Если вы неуклонно желаете сами разбираться с последствиями ваших собственных команд, вы можете отключить эту "возможность":
set confirm off
set confirm on
show confirm
set debug arch
show debug arch
set debug event
show debug event
set debug expression
show debug expression
set debug overload
show debug overload
set debug remote
show debug remote
set debug serial
show debug serial
set debug target
show debug target
set debug varobj
show debug varobj
Кроме команд точки останова (see section Команды точки останова), GDB предоставляет два способа сохранить последовательности команд для выполнения целиком: определяемые пользователем команды и командные файлы.
Команда, определяемая пользователем---это последовательность команд
GDB, которой вы назначаете имя, как новой команде. Это
осуществляется командой define
. Пользовательские команды могут иметь
до 10 параметров, разделенных пробелами. Внутри команды пользователя,
доступ к параметрам производится посредством $arg0...$arg9.
Вот простой пример:
define adder print $arg0 + $arg1 + $arg2
Для выполнения команды используйте:
adder 1 2 3
Этот пример определяет команду adder
, которая печатает сумму трех
своих параметров. Обратите внимание, что параметры являются текстовыми
подстановками, так что они могут ссылаться на переменные, использовать
сложные выражения или даже выполнять вызовы подчиненных функций.
define имя-команды
define
. Конец этих команд
отмечается стpокой, содержащей end
.
if
else
, сопровождаемая последовательностью команд, которые
выполняются только при ложном значении данного выражения. Конец списка
отмечается стpокой, содержащей end
.
while
if
: команда имеет один параметр, который
является вычисляемым выражением и должен сопровождаться командами,
по одной в стpоке, которые завершаются end
. Выполнение команд
повторяется, пока выражение истинно.
document имя-команды
help
. Команда
имя-команды должна быть определена ранее. Эта команда
считывает стpоки документации точно так же, как define
считывает стpоки определения команды, до строки end
. После
завершения команды document
, написанная вами документация будет
отображаться командой help
для команды имя-команды.
Вы можете использовать команду document
неоднократно, чтобы
изменить документацию команды. Переопределение команды посредством
define
не изменяет документации.
help user-defined
show user
show user имя-команды
При выполнении команд, определенных пользователем, команды определения не печатаются. Ошибка в любой из них останавливает выполнение всей определенной пользователем команды.
При использовании в интерактивном режиме, команды, обычно запрашивающие подтверждение, выполняются без запроса, если они используется внутри определенной пользователем команды. Многие команды GDB, которые обычно печатают сообщения о своих действиях, опускают их при использовании в команде, определенной пользователем.
Вы можете определять ловушки, которые являются специальным видом определяемых пользователем команд. Всякий раз, когда вы выполняете команду `foo', перед ней выполняется определенная пользователем команда `hook-foo' (без параметров), если она существует.
Кроме того, существует псевдокоманда `stop'. Определение (`hook-stop') велит выполняться связанным с ней командам при каждом останове вашей программы: перед выполнением команд точек останова, перед выводом на экран сообщений или кадров стека.
Например, чтобы игнорировать сигналы SIGALRM
во время выполнения
в пошаговом режиме, но обрабатывать их при нормальном выполнении, вы
можете определить:
define hook-stop handle SIGALRM nopass end define hook-run handle SIGALRM pass end define hook-continue handle SIGLARM pass end
Вы можете определить ловушку для любой однословной команды
GDB, но не для синонимов команды; вам следует определить
ловушку для базового имени команды, например, backtrace
, но не
bt
. Если во время выполнения вашей ловушки возникает ошибка,
выполнение команд GDB останавливается, и
он выдает приглашение (до того, как введенная вами
команда начнет выполняться).
Если вы попытаетесь определить ловушку, не соответствующую никакой
известной команде, вы получите предупреждение от команды define
.
Командный файл для GDB---это файл, состоящий из строк с командами GDB. Такие файлы могут также включать комментарии (строки, начинающиеся с #). Пустая строка в командном файле ничего не делает; она не означает повторение последней команды, как это было бы при вводе с терминала.
Когда вы вызываете GDB, он автоматически выполняет команды из своих файлов инициализации. Это файлы, называющиеся `.gdbinit' в Unix и `gdb.ini' в DOS/Windows. Во время старта, GDB делает следующее:
Файл инициализации в вашем домашнем каталоге может устанавливать параметры (такие как `set complaints'), которые влияют на последующую обработку ключей и операндов командной строки. Файлы инициализации не выполняются, если вы используете ключ `-nx' see section Выбор режимов.
В некоторых конфигурациях GDB, файлу инициализации присваивается другое имя (обычно это среды, где специализированная форма GDB должна сосуществовать с другими формами, следовательно должно быть отличное имя для файла инициализации специализированной версии). Следующие среды используют специальные имена файлов инициализации:
Вы также можете запросить выполнение командного файла с помощью команды
source
:
source имя-файла
Строки командного файла выполняются последовательно, при этом они не выводятся. Ошибка в любой команде завершает выполнение всего командного файла.
Команды, запрашивающие подтверждение в интерактивном режиме, при выполнении в командном файле выполняются без запросов. Многие команды GDB, обычно выводящие сообщения о своих действиях, опускают эти сообщения при вызове из командных файлов.
Во время выполнения командного файла или определенной пользователем команды, нормальный вывод GDB подавляется; единственый появляющийся вывод---тот, который производится явно командами из определения. В этом разделе описываются три команды, полезные для получения именно такого вывода, который вы хотите.
echo текст
echo Вот пример текста,\n\ который занимает\n\ несколько строк.\nпроизводит такой же вывод как
echo Вот пример текста,\n echo который занимает\n echo несколько строк.\n
output выражение
output/формат выражение
print
. See section Форматы вывода, для получения большей информации.
printf строка, выражения...
printf (строка, выражения...);Например, вы можете напечатать два шестнадцатеричных значения:
printf "foo, bar-foo = 0x%x, 0x%x\n", foo, bar-fooЕдинственые экранирующие последовательности с обратной косой чертой, которые вы можете использовать в строке формата---простые последовательности, состоящие из обратной косой черты, за которой следует буква.
Специальный интерфейс позволяет вам использовать GNU Emacs для просмотра (и редактирования) исходных файлов программы, которую вы отлаживаете с помощью GDB.
Чтобы использовать этот интерфейс, используйте команду M-x gdb в Emacs. В качестве аргумента задайте выполняемый файл, который вы хотите отладить. Эта команда вызывает GDB как подпроцесс Emacs с вводом и выводом через заново созданный буфер.
Под управлением Emacs, GDB используется точно так же, как обычно, за исключением двух моментов:
Это относится как к командам GDB и их выводу, так и к вводу и выводу, производимыми отлаживаемой программой.
Это полезно, потому что вы можете копировать текст предыдущих команд и вводить их снова; вы даже можете использовать таким образом части вывода.
Все средства режима оболочки Emacs доступны для взаимодействия с вашей программой. В частности, вы можете посылать сигналы обычным путем--- например, C-c C-c для прерывания, C-c C-z для остановки.
Каждый раз, когда GDB отображает кадр стека, Emacs автоматически находит исходный файл для него и помещает стрелку (`=>') на левом крае текущей строки. Emacs использует отдельный буфер для отображения исходного текста, и разделяет экран, чтобы отобразить как сеанс GDB, так и исходный текст.
Тем не менее, явные команды GDB list
и search
производят вывод как обычно, но у вас вероятно не будет причин
использовать их из Emacs.
Предупреждение: Если каталог, в котором находится ваша программа, не является текущим, Emacs легко может ошибиться при определении местонахождения исходных файлов; в этом случае вспомогательный буфер с исходным текстом не появляется. GDB может искать программы, используя переменную среды
PATH
, так что сеансы ввода и вывода происходят нормально; но Emacs не получает достаточно информации от GDB, чтобы найти исходные файлы в такой ситуации. Чтобы избежать этой проблемы, либо запускайте режим GDB из каталога, где находится ваша программа, либо укажите абсолютное имя файла, когда будет запрошен параметр для M-x gdb.Подобная путаница может возникнуть, если вы используете команду GDB
file
, чтобы переключиться к отладке программы, находящейся в каком-нибудь другом месте, из существующего буфера GDB в Emacs.
По умолчанию, M-x gdb вызывает программу с именем `gdb'. Если вам
нужно вызвать GDB под другим именем (например, если вы храните
несколько конфигураций под различными именами), вы можете установить переменную
Emacs gdb-command-name
; например, установка
(setq gdb-command-name "mygdb")
(которой предшествует M-: или ESC :, или если она введена в буфер
*scratch*
или в вашем файле `.emacs'), заставит Emacs вызвать
программу "mygdb
".
В буфере ввода-вывода GDB, вы можете использовать следующие специальные команды Emacs в дополнение к стандартным командам режима оболочки:
step
; также обновляет окно отображения для показа текущего файла и
положения в нем.
next
.
Затем обновить окно отображения, чтобы показать текущий файл и положение
в нем.
stepi
;
обновляет окно отображения.
nexti
; обновляет окно отображения.
finish
.
continue
.
Предупреждение: В Emacs версии 19, эта команда вызывается
посредством C-c C-p.
up
(see section `Числовые аргументы' in Руководство по GNU Emacs).
Предупреждение: В Emacs версии 19, эта команда вызывается
посредством C-c C-u.
down
.
Предупреждение: В Emacs версии 19, эта команда вызывается
посредством C-c C-d.
disassemble
, набрав C-x &.
Вы можете и дальше настраивать это, определяя элементы списка
gdb-print-command
; если он определен, вы можете форматировать или
как-либо иначе обрабатывать числа, задаваемые C-x &, перед их вставкой
в буфер. Числовой аргумент к C-x & показывает, что вам нужно
специальное форматирование, а также действует как индекс для выбора
элемента из списка. Если элемент списка является строкой, то вставляемое
число форматируется с использованием функции Emacs format
; в
противном случае, число передается как параметр соответствующему
элементу списка.
В любом исходном файле, команда Emacs C-x SPC (gdb-break
)
велит GDB установить точку останова на строке исходного текста,
в которой находится точка.
Если вы случайно удалите буфер отображения исходного текста, его можно легко
вернуть обратно, введя команду f
в буфере GDB, чтобы запросить
отображение кадра; когда выполнение происходит под управлением Emacs,
это при необходимости создает исходный буфер заново, чтобы показать вам
текущий кадр.
Исходные файлы, отображаемые в Emacs, находятся в обычных буферах Emacs, которые получают доступ к исходным файлам обычным способом. При желании вы можете редактировать файлы в этих буферах; но помните, что GDB взаимодействует с Emacs в терминах номеров строк. Если вы добавите или удалите строки из текста, известные GDB номера строк больше не будут соответствовать коду.
Эта глава описывает примечания в GDB. Примечания разработаны для согласования GDB с графическими интерфейсами пользователя или другими аналогичными программами, которые хотят взаимодействовать с GDB на относительно высоком уровне.
Чтобы создавать примечания, запустите GDB с ключем
--annotate=2
.
Примечания начинаются с символа новой строки, двух символов `control-z' и имени примечания. Если нет дополнительной информации, связанной с примечанием, непосредственно за его именем следует символ новой строки. Если дополнительная информация есть, за именем примечания следует пропуск, дополнительная информация и символ новой строки. Дополнительная информация не может содержать символа новой строки.
Любой вывод, не начинающийся с символа новой строки и двух `control-z', означает буквальный вывод GDB. В настоящее время GDB не нужно выводить два `control-z' вслед за символом новой строки, но если это понадобится, примечания могут быть расширены `экранирующим' примечанием, которое означает вывод этих трех символов.
Вот простой пример запуска GDB с примечаниями:
$ gdb --annotate=2 GNU GDB 5.0 Copyright 2000 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "sparc-sun-sunos4.1.3" ^Z^Zpre-prompt (gdb) ^Z^Zprompt quit ^Z^Zpost-prompt $
Здесь `quit' является для GDB вводом; остальное---вывод GDB. Три строки, начинающиеся с `^Z^Z' (где `^Z' означает знак `control-z'), суть примечания; остальное является выводом GDB.
Чтобы подать команду GDB, не оказывая влияния на определенные аспекты состояния, видимые для пользователей, начните ее с `server '. Это означает, что данная команда не воздействует на историю команд, а также не влияет на понятие GDB о том, какую команду повторять, если в пустой строке нажата клавиша RET.
Префикс server не влияет на запись значений в историю значений; чтобы
напечатать значение, не занося его в историю, используйте команду
output
вместо print
.
Когда значение выводится в различных контекстах, GDB использует примечания, чтобы отделить его от окружающего текста.
Если значение выводится с помощью print
и добавляется в историю
значений, примечание выглядит так:
^Z^Zvalue-history-begin номер-в-истории флаги-значения строка-истории ^Z^Zvalue-history-value значение ^Z^Zvalue-history-end
где номер-в-истории---номер, который значение получает в истории, строка-истории---строка, такая как `$5 = ', которая представляет значение пользователю, значение является выводом, соответствующим самому значению, а флаги-значения---`*' для значения, которое может быть разыменовано, и `-', если нет.
Если значение не добавляется в историю значений (это может быть или неверное
число с плавающей точкой, или оно выводится командой output
),
примечание выглядит похожим образом:
^Z^Zvalue-begin флаги-значения значение ^Z^Zvalue-end
Когда GDB выводит аргумент функции (например, в выводе команды
backtrace
), он делает такие примечания:
^Z^Zarg-begin имя-аргумента ^Z^Zarg-name-end строка-разделитель ^Z^Zarg-value флаги-значения значение ^Z^Zarg-end
где имя-аргумента есть имя аргумента,
строка-разделитель---текст (такой как `='), который отделяет
имя от значения для удобства пользователя, а флаги-значения и
значение имеют такой же смысл, что и в примечании
value-history-begin
.
При выводе структуры, GDB делает следующие примечания:
^Z^Zfield-begin флаги-значения имя-поля ^Z^Zfield-name-end строка-разделитель ^Z^Zfield-value значение ^Z^Zfield-end
где имя-поля есть имя поля, строка-разделитель---текст
(такой как `='), который отделяет имя от значения для удобства
пользователя, а флаги-значения и значение имеют тот же
смысл, что и в примечании value-history-begin
.
При выводе массива, GDB делает следующие примечания:
^Z^Zarray-section-begin индекс-в-массиве флаги-значения
где индекс-в-массиве---индекс первого аннотируемого элемента, а
флаги-значения имеют такой же смысл, что и в примечании
value-history-begin
. За этим следует произвольное число
элементов. Элемент может быть либо одиночным
`,' пропуск ; опускается для первого элемента значение ^Z^Zelt
либо повторяющимся
`,' пропуск ; опускается для первого элемента значение ^Z^Zelt-rep число-повторений строка-повторений ^Z^Zelt-rep-end
В обоих случаях, значение является выводом значения элемента, а пропуск может содержать пробелы, символы табуляции и новой строки. В случае повторяющихся элементов, число-повторений представляет число последовательных элементов массива, которые содержат данное значение, а строка-повторений является строкой, которая предназначена для уведомления пользователя о том, что выводятся повторяющиеся элементы.
После того, как выведены все элементы массива, примечание к массиву заканчивается так:
^Z^Zarray-section-end
Когда GDB печатает кадр, он делает к нему примечания.
Например, это применяется к кадрам, выводимым при остановке GDB,
в результате вывода командами, такими как backtrace
или
up
, и так далее.
Примечания к кадру начинаются с
^Z^Zframe-begin уровень адрес строка-уровня
где уровень---это номер кадра (0 для самого внутреннего кадра, другие кадры имеют положительные номера), адрес---это адрес кода, выполняющегося в данном кадре, а строка-уровня---строка, предназначенная для передачи уровня пользователю. Адрес имеет форму `0x', за которым следует одна или более шестнадцатеричных цифр в нижнем регистре (заметьте, что это не зависит от языка). Кадр заканчивается так:
^Z^Zframe-end
Между этими комментариями находится основное тело кадра, которое может состоять из
^Z^Zfunction-call строка-вызова-функциигде строка-вызова-функции является текстом, предназначенным для уведомления пользователя, что этот кадр связан с вызовом функции, который GDB сделал в отлаживаемой программе.
^Z^Zsignal-handler-caller строка-вызова-обработчика-сигналагде строка-вызова-обработчика-сигнала---текст, предназначенный для уведомления пользователя, что этот кадр связан с тем механизмом, который использовался операционной системой при вызове обработчика сигнала (это тот кадр, из которого произошел вызов обработчика, а не кадр для самого обработчика).
^Z^Zframe-address адрес ^Z^Zframe-address-end строка-разделительздесь адрес---это адрес, где происходит выполнение в кадре (тот же адрес, что и в примечании
frame-begin
, но выведенный в форме,
предназначенной для пользователя---в частности, синтаксис различается в
зависимости от языка), а строка-разделитель является строкой,
предназначенной для отделения этого адреса от того, что за ним следует
для удобства пользователя.
Затем идет
^Z^Zframe-function-name имя-функции ^Z^Zframe-args аргументыгде имя-функции есть имя функции, выполняющейся в кадре, или `??', если оно не известно, а аргументы---это аргументы к кадру, со скобками вокруг них (каждый аргумент аннотируется также индивидуально, see section Значения). Если доступна информация об исходных текстах, печатается ссылка на них:
^Z^Zframe-source-begin вводная-исходная-строка ^Z^Zframe-source-file имя-файла ^Z^Zframe-source-file-end : ^Z^Zframe-source-line номер-строки ^Z^Zframe-source-endгде вводная-исходная-строка отделяет ссылку от предшествуещего ей текста, для удобства пользователя, имя-файла---это имя исходного файла, номер-строки---номер строки в этом файле (первая строка имеет номер 1). Если GDB печатает некоторую информацию о том, откуда появился этот кадр (какая библиотека, какой сегмент загрузки, и так далее; в настоящее время реализовано только на RS/6000), он делает такие примечания:
^Z^Zframe-where информацияЗатем, если исходный текст действительно должен быть отображен для этого кадра (например, это не верно для вывода от команды
backtrace
),
тогда выводится примечание source
(see section Вывод исходного текста). В отличие от большинства примечаний, этот вывод производится
вместо обычного текста, который был бы напечатан, а не в дополнение к нему.
Когда GDB велят отобразить что-то с помощью команды
display
, к результату отображения делаются примечания:
^Z^Zdisplay-begin номер ^Z^Zdisplay-number-end разделитель-номеров ^Z^Zdisplay-format формат ^Z^Zdisplay-expression выражение ^Z^Zdisplay-expression-end разделитель-выражений ^Z^Zdisplay-value значение ^Z^Zdisplay-end
здесь номер---это номер отображения, разделитель-номеров предназначен для отделения номеров от того, что следует затем для пользователя, формат включает информацию о том, как отображается значение, такую как размер, формат и так далее, выражение---это отображаемое выражение, разделитель-выражений предназначен для отделения выражения от следующего за ним текста для пользователя, и значение---это действительное значение, которое отображается.
Когда GDB выводит приглашение для ввода, он делает к этому примечания, так что становится возможным узнать, когда посылать данные, когда закончен вывод от данной команды, и так далее.
Каждый из различных видов ввода имеет различный тип ввода. Каждый
тип ввода имеет три примечания: примечание pre-
, обозначающее
начало каждого выводимого приглашения, простое примечание, обозначающее
конец приглашения, и затем примечание post-
, обозначающее конец
любого эхо, которое может быть ассоциировано (а может и не быть) со
вводом. Например, характерной чертой типа ввода prompt
являются
следующие примечания:
^Z^Zpre-prompt ^Z^Zprompt ^Z^Zpost-prompt
Существуют следующие типы ввода:
prompt
commands
commands
.
Примечания повторяются для каждой введенной команды.
overload-choice
query
prompt-for-continue
set height 0
для отключения приглашений.
Это происходит потому, что при наличии примечаний подсчет строк
происходит неверно.
^Z^Zquit
Это примечание появляется непосредственно перед тем, как GDB отвечает на прерывание.
^Z^Zerror
Это примечание появляется сразу перед тем, как GDB отвечает на ошибку.
Примечания выхода и ошибки обозначают, что любое примечание, в середине
которого находился GDB, могут внезапно оборваться. Например,
если за примечанием value-history-begin
следует error
, то
не нужно ожидать соответствующий value-history-end
. Однако, не
следует также ожидать, что его точно не будет; примечание об ошибке не
обязательно означает, что GDB немедленно возвращается в начало
на самый верхний уровень.
Примечанию к ошибке или выходу может предшествовать
^Z^Zerror-begin
Весь вывод между этим и примечанием к ошибке или выходу является сообщением об ошибке.
Пока примечаний к предупреждающим сообщениям не делается.
К выводу, производимому командой info breakpoints
, делаются
следующие примечания:
^Z^Zbreakpoints-headers элемент-заголовка ^Z^Zbreakpoints-table
где элемент-заголовка имеет тот же синтаксис, что и элемент (смотрите ниже), но вместо данных, он содержит строки, которые предназначены для разъяснения пользователю значений каждого поля. Затем следует произвольное число элементов. Если поле не подходит к этому элементу, оно опускается. Поля могут содержать завершающие пропуски. Каждое поле состоит из:
^Z^Zrecord ^Z^Zfield 0 номер ^Z^Zfield 1 тип ^Z^Zfield 2 положение ^Z^Zfield 3 включена ^Z^Zfield 4 адрес ^Z^Zfield 5 что ^Z^Zfield 6 кадр ^Z^Zfield 7 условие ^Z^Zfield 8 счетчик-игнорирований ^Z^Zfield 9 команды
Заметьте, что адрес предназначен для использования пользователем---синтаксис различается в зависимости от языка.
Вывод заканчивается так:
^Z^Zbreakpoints-table-end
Следующие примечания говорят о том, что определенные куски информации, описывающие состояние, могли измениться.
^Z^Zframes-invalid
backtrace
) могли измениться.
^Z^Zbreakpoints-invalid
Когда программа начинает выполняться вследствие команды
GDB, такой как step
или continue
, выводится
^Z^Zstarting
Когда программа останавливается, выводится
^Z^Zstopped
Перед примечанием stopped
, множество примечаний описывают, как
программа остановилась.
^Z^Zexited код-выхода
^Z^Zsignalled
^Z^Zsignalled
, примечания
продолжаются:
вступительный-текст ^Z^Zsignal-name имя ^Z^Zsignal-name-end текст-в-середине ^Z^Zsignal-string строка ^Z^Zsignal-string-end заключительный-текстгде имя является именем сигнала, таким как
SIGILL
или
SIGSEGV
, а строка представляет объяснение сигнала, такое как
Illegal Instruction
или Segmentation fault
.
Вступительный-текст, текст-в-середине и заключительный
текст используются для удобства пользователя и не имеют определенного
формата.
^Z^Zsignal
signalled
, но
GDB сообщает, что программа лишь получила сигнал, а не то, что
она остановилась из-за него.
^Z^Zbreakpoint номер
^Z^Zwatchpoint номер
Следующие примечания используются вместо вывода исходного текста:
^Z^Zsource имя-файла:строка:символ:middle:адрес
где имя-файла указывает абсолютное имя файла, строка---это номер строки в этом файле (первая строка имеет номер 1), символ---позиция символа в файле (первый символ в исходном файле имеет номер 0) (для большинства отладочных форматов это будет обязательно указывать на начало строки), middle есть `middle', если адрес находится в середине строки, или `beg', если адрес находится в начале строки, а адрес является адресом в целевой программе, ассоциированным с выводимым исходным текстом. Адрес записан в форме `0x', за которым следует одна или несколько шестнадцатеричных цифр в нижнем регистре (заметьте, что это не зависит от языка).
- target-invalid цель могла измениться (регистры, содержимое памяти или статус выполнения). Для эффективности выполнения, мы можем захотеть определять `register-invalid' и `all-register-invalid' с большей точностью - систематические примечания к параметрам set/show (включая сообщения о недостоверности). - аналогично, `info' возвращает список кандидатов на сообщение о недостоверности.
GDB/MI является построчным, машинно-ориентированным текстовым интерфейсом к GDB. Он предназначен специально для поддержки разработки систем, которые используют отладчик лишь как одну маленькую компоненту большой системы.
Эта глава является спецификацией интерфейса GDB/MI. Она написана в форме справочного руководства.
Заметьте, что GDB/MI все еще находится в стадии разработки, так что некоторые описанные ниже возможности являются неполными и могут быть изменены.
Эта глава использует следующую систему обозначений:
|
разделяет две альтернативы.
[ нечто ]
указывает, что нечто является
необязательным: оно может быть задано, а может и нет.
( группа )*
означает, что группа в скобках может
повторяться ноль и более раз.
( группа )+
означает, что группа в скобках может
повторяться один и более раз.
"строка"
обозначает текст строка.
В алфавитном порядке: Елена Заннони, Эндрю Кагни, Фернандо Нассер и Стан Шебс.
команда ==>
команда-cli | команда-mi
команда-cli ==>
[ лексема ] команда-cli nl
, где
команда-cli есть любая существующая команда GDB CLI.
команда-mi ==>
[ лексема ] "-" действие ( " " ключ )*
[
" --" ]
( " " параметр )* nl
лексема ==>
ключ ==>
"-" параметр [ " " параметр ]
параметр ==>
непустая-последовательность | строка-си
действие ==>
непустая-последовательность ==>
строка-си ==>
""" содержимое-семибитной-строки-iso-си """
nl ==>
CR | CR-LF
Замечания:
Лексема
, если присутствует, передается назад, когда
выполнение команды завершается.
Прагматические соображения:
Вывод GDB/MI состоит из нуля или более внеочередных записей, за которыми может следовать одна результирующая запись. Эта запись относится к самой последней команде. Последовательность выводимых записей завершается `(gdb)'.
Если входная команда начиналась с префикса лексема
, то
соответствующий вывод для этой команды также будет начинаться с того же
префикса лексема.
вывод ==>
( внеочередная-запись )* [ результирующая-запись ] "(gdb)" nl
результирующая-запись ==>
[ лексема ] "^" результирующий-класс ( "," результат )* nl
внеочередная-запись ==>
асинхр-запись | поточн-запись
асинхр-запись ==>
асинхр-вывод-выполн | асинхр-вывод-статуса | асинхр-вывод-уведомл
асинхр-вывод-выполн ==>
[ лексема ] "*" асинхр-вывод
асинхр-вывод-статуса ==>
[ лексема ] "+" асинхр-вывод
асинхр-вывод-уведомл ==>
[ лексема ] "=" асинхр-вывод
асинхр-вывод ==>
асинхр-класс ( "," результат )* nl
результ-класс ==>
"done" | "running" | "connected" | "error" | "exit"
асинхр-класс ==>
"stopped" | другое
(где другое будет добавлено
по необходимости---это все еще находится в стадии разработки).
результат ==>
[ строка "=" ] значение
значение ==>
константа | "{" результат ( "," результат )* "}"
константа ==>
строка-си
поточн-запись ==>
консольн-поточн-вывод | целев-поточн-вывод | журн-поточн-вывод
консольн-поточн-вывод ==>
"~" строка-си
целев-поточн-вывод ==>
"@" строка-си
журн-поточн-вывод ==>
"&" строка-си
nl ==>
CR | CR-LF
лексема ==>
Кроме того, следующее все еще находится в стадии разработки:
запрос
Замечания:
Лексема
берется из соответствующего запроса. Если
выполнение команды прерывается командой `-exec-interrupt',
лексема, ассоциированная с сообщением `*stopped', является
лексемой исходной выполняемой команды, а не лексемой
команды прерывания.
See section Поточные записи GDB/MI, для более подробной информации о различных выводимых записях.
See section Черновик изменений к выходному синтаксису GDB/MI, для предлагаемых изменений к выходному синтаксису.
Этот подраздел представляет несколько простых примеров взаимодействия с использованием интерфейса GDB/MI. В этих примерах, `->' означает, что следующая строка передается GDB/MI в качестве ввода, а `<-' означает вывод, полученный от GDB/MI.
Вот пример останова подчиненного процесса:
-> -stop <- (gdb)
и затем:
<- *stop,reason="stop",address="0x123",source="a.c:123" <- (gdb)
Вот пример простой команды CLI, передаваемой ему через GDB/MI.
-> print 1+2 <- ~3\n <- (gdb)
-> -symbol-file xyz.exe <- *breakpoint,nr="3",address="0x123",source="a.c:123" <- (gdb)
Вот что происходит, если вы передаете несуществующую команду:
-> -rubbish <- error,"Rubbish not found" <- (gdb)
Чтобы помочь пользователям, знакомым с существующим в GDB интерфейсом CLI, GDB/MI принимает существующие команды CLI. Как определено синтаксисом, такие команды могут быть непосредственно введены в интерфейс GDB/MI, и GDB будет отвечать.
Этот механизм предоставляется для помощи разработчикам клиентов GDB/MI, а не как надежный интерфейс к CLI. Так как команда интерпретируется в среде, которая подразумевает поведение GDB/MI, точные результаты таких команд в конечном итоге скорее всего станут неудобоваримой смесью вывода GDB/MI и CLI.
В дополнение к множеству внеочередных уведомлений, ответ на команду GDB/MI включает один из следующих указателей результата:
"^done" [ "," результаты ]
результаты
.
"^running"
"^error" "," строка-си
Строка-си
содержит
соответствующее сообщение об ошибке.
GDB хранит число выходных потоков: консоль, цель и журнал. Вывод, предназначенный для этих потоков, пропускается через интерфейс GDB/MI при помощи поточных записей.
Каждая поточная запись начинается с уникального префиксного
символа, который идентифицирует свой поток (see section Выходной синтаксис GDB/MI). Помимо префикса, каждая
поточная запись содержит строку-вывод
. Это либо простой
текст (с подразумеваемым знаком новой строки), или Си-строка в кавычках
(которая не содержит подразумеваемого знака новой строки).
"~" строка-вывод
"@" строка-вывод
"&" строка-вывод
Внеочередные записи используются для уведомления клиента GDB/MI о произошедших дополнительных изменениях. Эти изменения могут либо исходить от GDB/MI (например, измененная точка останова), либо быть результатом действий цели (например, цель остановилась).
Ниже приведен предварительный список возможных внеочередных записей.
"*" "stop"
Оставшиеся разделы описывают блоки команд. Каждый блок команд схематично аналогичен этому разделу.
Заметьте, что разбиения строк в примерах присутствуют только для удобства чтения. Они не появляются в реальном выводе. Учтите также, что команды с недоступными примерами (Н.П.) еще не реализованы.
Мотивация для этого набора команд.
Краткое введение в этот набор команд в целом.
Для каждой команды в блоке, описано следующее:
-command арг...
Соответствующая команда CLI GDB.
Этот раздел описывает команды GDB/MI для управления точками останова.
-break-after
-break-after номер число
Точка останова с номером номер не срабатывает, пока она не будет достигнута число раз. Чтобы увидеть, как это отражается на выводе команды `-break-list', смотрите ниже описание команды `-break-list'.
Соответствующей командой GDB является `ignore'.
(gdb) -break-insert main ^done,bkpt={number="1",addr="0x000100d0",file="hello.c",line="5"} (gdb) -break-after 1 3 ~ ^done (gdb) -break-list ^done,BreakpointTable={hdr={"Num","Type","Disp","Enb","Address","What"}, bkpt={number="1",type="breakpoint",disp="keep",enabled="y", addr="0x000100d0",func="main",file="hello.c",line="5",times="0", ignore="3"}} (gdb)
-break-condition
-break-condition номер выраж
Точка останова номер остановит программу, только если условие выраж истино. Условие становится частью вывода `-break-list' (смотрите ниже описание команды `-break-list').
Соответствующей командой GDB является `condition'.
(gdb) -break-condition 1 1 ^done (gdb) -break-list ^done,BreakpointTable={hdr={"Num","Type","Disp","Enb","Address","What"}, bkpt={number="1",type="breakpoint",disp="keep",enabled="y", addr="0x000100d0",func="main",file="hello.c",line="5",cond="1", times="0",ignore="3"}} (gdb)
-break-delete
-break-delete ( точка-останова )+
Удалить точки останова, чьи номера указаны в списке аргументов. Это, очевидно, отражается на списке точек останова.
Соответствующей командой GDB является `delete'.
(gdb) -break-delete 1 ^done (gdb) -break-list ^done,BreakpointTable={} (gdb)
-break-disable
-break-disable ( точка-останова )+
Отключить упомянутые точки-останова. Для указанных точек-останова поле `enabled' в списке точек останова теперь установлено в `n'.
Соответствующей командой GDB является `disable'.
(gdb) -break-disable 2 ^done (gdb) -break-list ^done,BreakpointTable={hdr={"Num","Type","Disp","Enb","Address","What"}, bkpt={number="2",type="breakpoint",disp="keep",enabled="n", addr="0x000100d0",func="main",file="hello.c",line="5",times="0"}} (gdb)
-break-enable
-break-enable ( точка-останова )+
Включить (ранее отключенные) точки-останова.
Соответствующей командой GDB является `enable'.
(gdb) -break-enable 2 ^done (gdb) -break-list ^done,BreakpointTable={hdr={"Num","Type","Disp","Enb","Address","What"}, bkpt={number="2",type="breakpoint",disp="keep",enabled="y", addr="0x000100d0",func="main",file="hello.c",line="5",times="0"}} (gdb)
-break-info
-break-info точка-останова
Получить информацию об одной точке останова.
Соответствующей командой GDB является `info break точка-останова'.
Н.П.
-break-insert
-break-insert [ -t ] [ -h ] [ -r ] [ -c условие ] [ -i счетчик-игнорирований ] [ -p нить ] [ строка | адрес ]
Строка, если указана, может быть одной из:
Вот возможные необязательные параметры этой команды:
Результат имеет форму:
^done,bkptno="номер",func="имя-функции", file="имя-файла",line="ном-строки"
где номер является номером этой точки останова в GDB, имя-функции---имя функции, в которой была вставлена точка останова, имя-файла---имя исходного файла, в котором находится эта функция, а ном-строки является номером строки исходного текста в этом файле.
Замечание: этот формат может изменяться.
Соответстующими командами GDB являются `break', `tbreak', `hbreak', `thbreak' и `rbreak'.
(gdb) -break-insert main ^done,bkpt={number="1",addr="0x0001072c",file="recursive2.c",line="4"} (gdb) -break-insert -t foo ^done,bkpt={number="2",addr="0x00010774",file="recursive2.c",line="11"} (gdb) -break-list ^done,BreakpointTable={hdr={"Num","Type","Disp","Enb","Address","What"}, bkpt={number="1",type="breakpoint",disp="keep",enabled="y", addr="0x0001072c", func="main",file="recursive2.c",line="4",times="0"}, bkpt={number="2",type="breakpoint",disp="del",enabled="y", addr="0x00010774",func="foo",file="recursive2.c",line="11",times="0"}} (gdb) -break-insert -r foo.* ~int foo(int, int); ^done,bkpt={number="3",addr="0x00010774",file="recursive2.c",line="11"} (gdb)
-break-list
-break-list
Отображает список установленных точек останова, показывая следующие поля:
Если точек останова или наблюдения нет, поле BreakpointTable
является
пустым списком.
Соответствующей командой GDB является `info break'.
(gdb) -break-list ^done,BreakpointTable={hdr={"Num","Type","Disp","Enb","Address","What"}, bkpt={number="1",type="breakpoint",disp="keep",enabled="y", addr="0x000100d0",func="main",file="hello.c",line="5",times="0"}, bkpt={number="2",type="breakpoint",disp="keep",enabled="y", addr="0x00010114",func="foo",file="hello.c",line="13",times="0"}} (gdb)
Вот пример результата, когда точек останова нет:
(gdb) -break-list ^done,BreakpointTable={} (gdb)
-break-watch
-break-watch [ -a | -r ]
Создать точку наблюдения. С ключем `-a' будет создана точка наблюдения за доступом, то есть такая точка наблюдения, которая срабатывает либо при чтении, либо при записи в определенное местоположение в памяти. С ключем `-r' созданная точка наблюдения будет точкой наблюдения за чтением, то есть она будет срабатывать только когда к определенному местоположению в памяти осуществляется доступ на чтение. Без этих ключей будет создана обычная точка наблюдения, то есть она будет срабатывать, когда к местоположению в памяти осуществляется доступ для записи. See section Установка точек наблюдения.
Заметьте, что `-break-list' выдаст единый список установленных точек наблюдения и останова.
Соответствующими командами GDB являются `watch', `awatch' и `rwatch'.
Установка точки наблюдения за переменной в функции main
:
(gdb) -break-watch x ^done,wpt={number="2",exp="x"} (gdb) -exec-continue ^running ^done,reason="watchpoint-trigger",wpt={number="2",exp="x"}, value={old="-268439212",new="55"}, frame={func="main",args={},file="recursive2.c",line="5"} (gdb)
Установка точки наблюдения за локальной переменной функции. GDB дважды остановит выполнение программы: сначала при изменении значения переменной, затем при выходе точки наблюдения из области видимости.
(gdb) -break-watch C ^done,wpt={number="5",exp="C"} (gdb) -exec-continue ^running ^done,reason="watchpoint-trigger", wpt={number="5",exp="C"},value={old="-276895068",new="3"}, frame={func="callee4",args={}, file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="13"} (gdb) -exec-continue ^running ^done,reason="watchpoint-scope",wpnum="5", frame={func="callee3",args={{name="strarg", value="0x11940 \"A string argument.\""}}, file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"} (gdb)
Список точек останова и наблюдения, в разных местах выполнения программы. Заметьте, что как только точка наблюдения выходит из области видимости, она удаляется.
(gdb) -break-watch C ^done,wpt={number="2",exp="C"} (gdb) -break-list ^done,BreakpointTable={hdr={"Num","Type","Disp","Enb","Address","What"}, bkpt={number="1",type="breakpoint",disp="keep",enabled="y", addr="0x00010734",func="callee4", file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"}, bkpt={number="2",type="watchpoint",disp="keep", enabled="y",addr="",what="C",times="0"}} (gdb) -exec-continue ^running ^done,reason="watchpoint-trigger",wpt={number="2",exp="C"}, value={old="-276895068",new="3"}, frame={func="callee4",args={}, file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="13"} (gdb) -break-list ^done,BreakpointTable={hdr={"Num","Type","Disp","Enb","Address","What"}, bkpt={number="1",type="breakpoint",disp="keep",enabled="y", addr="0x00010734",func="callee4", file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"}, bkpt={number="2",type="watchpoint",disp="keep", enabled="y",addr="",what="C",times="-5"}} (gdb) -exec-continue ^running ^done,reason="watchpoint-scope",wpnum="2", frame={func="callee3",args={{name="strarg", value="0x11940 \"A string argument.\""}}, file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"} (gdb) -break-list ^done,BreakpointTable={hdr={"Num","Type","Disp","Enb","Address","What"}, bkpt={number="1",type="breakpoint",disp="keep",enabled="y", addr="0x00010734",func="callee4", file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"}} (gdb)
Этот раздел описывает команды GDB/MI для управления данными: исследование памяти и регистров, вычисление выражений, и так далее.
-data-disassemble
-data-disassemble [ -s нач-адр -e кон-адр ] | [ -f имя-файла -l ном-строки [ -n ст ] ] -- режим
Где:
$pc
)
Вывод для каждой инструкции состоит из четырех полей:
Заметьте, что то, что включено в поле инструкции, не обрабатывается непосредственно GDB/MI, то есть изменить его формат невозможно.
Непосредственного отображения этой команды в CLI нет.
Дисассемблирование от текущего значения $pc
до $pc + 20
:
(gdb) -data-disassemble -s $pc -e "$pc + 20" -- 0 ^done, asm_insns={ {address="0x000107c0",func-name="main",offset="4", inst="mov 2, %o0"}, {address="0x000107c4",func-name="main",offset="8", inst="sethi %hi(0x11800), %o2"}, {address="0x000107c8",func-name="main",offset="12", inst="or %o2, 0x140, %o1\t! 0x11940 <_lib_version+8>"}, {address="0x000107cc",func-name="main",offset="16", inst="sethi %hi(0x11800), %o2"}, {address="0x000107d0",func-name="main",offset="20", inst="or %o2, 0x168, %o4\t! 0x11968 <_lib_version+48>"}} (gdb)
Дисассемблирование всей функции main
. Строка 32 является частью
main
.
-data-disassemble -f basics.c -l 32 -- 0 ^done,asm_insns={ {address="0x000107bc",func-name="main",offset="0", inst="save %sp, -112, %sp"}, {address="0x000107c0",func-name="main",offset="4", inst="mov 2, %o0"}, {address="0x000107c4",func-name="main",offset="8", inst="sethi %hi(0x11800), %o2"}, [...] {address="0x0001081c",func-name="main",offset="96",inst="ret "}, {address="0x00010820",func-name="main",offset="100",inst="restore "}} (gdb)
Дисассемблирование 3 инструкций от начала main
:
(gdb) -data-disassemble -f basics.c -l 32 -n 3 -- 0 ^done,asm_insns={ {address="0x000107bc",func-name="main",offset="0", inst="save %sp, -112, %sp"}, {address="0x000107c0",func-name="main",offset="4", inst="mov 2, %o0"}, {address="0x000107c4",func-name="main",offset="8", inst="sethi %hi(0x11800), %o2"}} (gdb)
Дисассемблирование 3 инструкций от начала main
в смешаном режиме:
(gdb) -data-disassemble -f basics.c -l 32 -n 3 -- 1 ^done,asm_insns={ src_and_asm_line={line="31", file="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb/ \ testsuite/gdb.mi/basics.c",line_asm_insn={ {address="0x000107bc",func-name="main",offset="0", inst="save %sp, -112, %sp"}}}, src_and_asm_line={line="32", file="/kwikemart/marge/ezannoni/flathead-dev/devo/gdb/ \ testsuite/gdb.mi/basics.c",line_asm_insn={ {address="0x000107c0",func-name="main",offset="4", inst="mov 2, %o0"}, {address="0x000107c4",func-name="main",offset="8", inst="sethi %hi(0x11800), %o2"}}}} (gdb)
-data-evaluate-expression
-data-evaluate-expression выраж
Вычислить выражение выраж. Выражение может содержать подчиненный вызов функции. Вызов функции быдет выполнен синхронно. Если выражение содержит пробелы, оно должно быть заключено в двойные кавычки.
Соответствующими командами GDB являются `print',
`output' и `call'. В gdbtk
есть
соответствующая команда `gdb_eval'.
В следующем примере числа, предшествующие командам, суть лексемы. Для их описания, см. section Синтаксис команд GDB/MI. Обратите внимание на то, как GDB/MI возвращает те же лексемы в своем выводе.
211-data-evaluate-expression A 211^done,value="1" (gdb) 311-data-evaluate-expression &A 311^done,value="0xefffeb7c" (gdb) 411-data-evaluate-expression A+3 411^done,value="4" (gdb) 511-data-evaluate-expression "A + 3" 511^done,value="4" (gdb)
-data-list-changed-registers
-data-list-changed-registers
Выводит список регистров, которые изменились.
GDB не имеет прямого аналога этой команды; соответствующей
командой gdbtk
является `gdb_changed_register_list'.
На плате PPC MBX:
(gdb) -exec-continue ^running (gdb) *stopped,reason="breakpoint-hit",bkptno="1",frame={func="main", args={},file="try.c",line="5"} (gdb) -data-list-changed-registers ^done,changed-registers={"0","1","2","4","5","6","7","8","9", "10","11","13","14","15","16","17","18","19","20","21","22","23", "24","25","26","27","28","30","31","64","65","66","67","69"} (gdb)
-data-list-register-names
-data-list-register-names [ ( ном-рег )+ ]
Показать список имен регистров текущей цели. Если аргументы не заданы, показывается список имен всех регистров. Если в качестве аргументов заданы целые числа, команда напечатает список имен регистров, соответствующих аргументам.
В GDB нет команды, которая соответствует
`-data-list-register-names'. В gdbtk
соответствующей
командой является `gdb_regnames'.
Для платы PPC MBX:
(gdb) -data-list-register-names ^done,register-names={"r0","r1","r2","r3","r4","r5","r6","r7", "r8","r9","r10","r11","r12","r13","r14","r15","r16","r17","r18", "r19","r20","r21","r22","r23","r24","r25","r26","r27","r28","r29", "r30","r31","f0","f1","f2","f3","f4","f5","f6","f7","f8","f9", "f10","f11","f12","f13","f14","f15","f16","f17","f18","f19","f20", "f21","f22","f23","f24","f25","f26","f27","f28","f29","f30","f31", "pc","ps","cr","lr","ctr","xer"} (gdb) -data-list-register-names 1 2 3 ^done,register-names={"r1","r2","r3"} (gdb)
-data-list-register-values
-data-list-register-values фмт [ ( ном-рег )*]
Отобразить содержимое регистров. Фмт является форматом, в соответствии с которым должно быть возвращено содержимое регистров, за которым следует необязательный список чисел, указывающих регистры, подлежащие отображению. Отсутствие списка чисел означает, что должно быть возвращено содержимое всех регистров.
Вот допустимые форматы для фмт:
x
o
t
d
r
N
Соответствующими командами GDB являются `info reg',
`info all-reg' и (в gdbtk
) `gdb_fetch_registers'.
Для платы PPC MBX (имейте ввиду: переносы строк даны только для удобства чтения, они не появляются в реальном выводе):
(gdb) -data-list-register-values r 64 65 ^done,register-values={{number="64",value="0xfe00a300"}, {number="65",value="0x00029002"}} (gdb) -data-list-register-values x ^done,register-values={{number="0",value="0xfe0043c8"}, {number="1",value="0x3fff88"},{number="2",value="0xfffffffe"}, {number="3",value="0x0"},{number="4",value="0xa"}, {number="5",value="0x3fff68"},{number="6",value="0x3fff58"}, {number="7",value="0xfe011e98"},{number="8",value="0x2"}, {number="9",value="0xfa202820"},{number="10",value="0xfa202808"}, {number="11",value="0x1"},{number="12",value="0x0"}, {number="13",value="0x4544"},{number="14",value="0xffdfffff"}, {number="15",value="0xffffffff"},{number="16",value="0xfffffeff"}, {number="17",value="0xefffffed"},{number="18",value="0xfffffffe"}, {number="19",value="0xffffffff"},{number="20",value="0xffffffff"}, {number="21",value="0xffffffff"},{number="22",value="0xfffffff7"}, {number="23",value="0xffffffff"},{number="24",value="0xffffffff"}, {number="25",value="0xffffffff"},{number="26",value="0xfffffffb"}, {number="27",value="0xffffffff"},{number="28",value="0xf7bfffff"}, {number="29",value="0x0"},{number="30",value="0xfe010000"}, {number="31",value="0x0"},{number="32",value="0x0"}, {number="33",value="0x0"},{number="34",value="0x0"}, {number="35",value="0x0"},{number="36",value="0x0"}, {number="37",value="0x0"},{number="38",value="0x0"}, {number="39",value="0x0"},{number="40",value="0x0"}, {number="41",value="0x0"},{number="42",value="0x0"}, {number="43",value="0x0"},{number="44",value="0x0"}, {number="45",value="0x0"},{number="46",value="0x0"}, {number="47",value="0x0"},{number="48",value="0x0"}, {number="49",value="0x0"},{number="50",value="0x0"}, {number="51",value="0x0"},{number="52",value="0x0"}, {number="53",value="0x0"},{number="54",value="0x0"}, {number="55",value="0x0"},{number="56",value="0x0"}, {number="57",value="0x0"},{number="58",value="0x0"}, {number="59",value="0x0"},{number="60",value="0x0"}, {number="61",value="0x0"},{number="62",value="0x0"}, {number="63",value="0x0"},{number="64",value="0xfe00a300"}, {number="65",value="0x29002"},{number="66",value="0x202f04b5"}, {number="67",value="0xfe0043b0"},{number="68",value="0xfe00b3e4"}, {number="69",value="0x20002b03"}} (gdb)
-data-read-memory
-data-read-memory [ -o смещение ] адрес формат-слова размер-слова число-строк число-колонок [ asсимв ]
где:
print
(see section Форматы вывода).
Эта команда отображает содержимое памяти в виде таблицы из
число-строк на число-колонок слов, причем каждое слово
занимает размер-слова байт. В общей сложности считывается
число-строк * число-колонок * размер-слова
байт (возвращается как `total-bytes'). Если цель должна возвратить
меньше запрошенного числа байт, отсутствующие слова идентифицируются при
помощи `N/A'. Число байт, прочитанное с цели, возвращается в
`nr-bytes', а начальный адрес, использованный для чтении памяти, в
`addr'.
Адрес следующей/предыдущей строки или страницы доступен в `next-row' и `prev-row', `next-page' и `prev-page'.
Соответствующей командой GDB является `x'. gdbtk
имеет команду чтения памяти `gdb_get_mem'.
Прочитать шесть байт памяти, начиная с bytes+6
, но сместиться на
-6
байт. Форматировать в три ряда по две колонки. Один байт на
слово. Отображать каждое слово в шестнадцатеричном виде.
(gdb) 9-data-read-memory -o -6 -- bytes+6 x 1 3 2 9^done,addr="0x00001390",nr-bytes="6",total-bytes="6", next-row="0x00001396",prev-row="0x0000138e",next-page="0x00001396", prev-page="0x0000138a",memory={ {addr="0x00001390",data={"0x00","0x01"}}, {addr="0x00001392",data={"0x02","0x03"}}, {addr="0x00001394",data={"0x04","0x05"}}} (gdb)
Прочитать два байта памяти, начиная с адреса shorts + 64
и
отобразить в виде одного слова в десятичном виде.
(gdb) 5-data-read-memory shorts+64 d 2 1 1 5^done,addr="0x00001510",nr-bytes="2",total-bytes="2", next-row="0x00001512",prev-row="0x0000150e", next-page="0x00001512",prev-page="0x0000150e",memory={ {addr="0x00001510",data={"128"}}} (gdb)
Прочитать тридцать два байта памяти, начиная с bytes+16
, и
форматировать на восемь рядов по четыре колонки. Включить строку,
закодированную с использованием `x' в качестве непечатного символа.
(gdb) 4-data-read-memory bytes+16 x 1 8 4 x 4^done,addr="0x000013a0",nr-bytes="32",total-bytes="32", next-row="0x000013c0",prev-row="0x0000139c", next-page="0x000013c0",prev-page="0x00001380",memory={ {addr="0x000013a0",data={"0x10","0x11","0x12","0x13"},ascii="xxxx"}, {addr="0x000013a4",data={"0x14","0x15","0x16","0x17"},ascii="xxxx"}, {addr="0x000013a8",data={"0x18","0x19","0x1a","0x1b"},ascii="xxxx"}, {addr="0x000013ac",data={"0x1c","0x1d","0x1e","0x1f"},ascii="xxxx"}, {addr="0x000013b0",data={"0x20","0x21","0x22","0x23"},ascii=" !\"#"}, {addr="0x000013b4",data={"0x24","0x25","0x26","0x27"},ascii="$%&'"}, {addr="0x000013b8",data={"0x28","0x29","0x2a","0x2b"},ascii="()*+"}, {addr="0x000013bc",data={"0x2c","0x2d","0x2e","0x2f"},ascii=",-./"}} (gdb)
-display-delete
-display-delete число
Удалить элемент номер из списка выражений, подлежащих отображению.
Соответствующей командой GDB является `delete display'.
Н.П.
-display-disable
-display-disable номер
Отключить элемент номер списка выражений, подлежащих отображению.
Соответствующей командой GDB является `disable display'.
Н.П.
-display-enable
-display-enable номер
Включить элемент номер списка выражений, подлежащих отображению.
Соответствующей командой GDB является `enable display'.
Н.П.
-display-insert
-display-insert выражение
Отображать выражение всякий раз, когда программа останавливается.
Соответствующей командой GDB является `display'.
Н.П.
-display-list
-display-list
Перечислить элементы списка выражений, подлежащих автоматическому отображению. Текущие значения не показывать.
Соответствующей командой GDB является `info display'.
Н.П.
-environment-cd
-environment-cd кат
Установить рабочий каталог GDB.
Соответствующей командой GDB является `cd'.
(gdb) -environment-cd /kwikemart/marge/ezannoni/flathead-dev/devo/gdb ^done (gdb)
-environment-directory
-environment-directory кат
Добавить каталог кат в начало пути поиска исходных файлов.
Соответствующей командой GDB является `dir'.
(gdb) -environment-directory /kwikemart/marge/ezannoni/flathead-dev/devo/gdb ^done (gdb)
-environment-path
-environment-path ( кат )+
Добавить каталоги кат в начало пути поиска объектных файлов.
Соответствующей командой GDB является `path'.
(gdb) -environment-path /kwikemart/marge/ezannoni/flathead-dev/ppc-eabi/gdb ^done (gdb)
-environment-pwd
-environment-pwd
Показать текущий рабочий каталог.
Соответствующей командой GDB является `pwd'.
(gdb) -environment-pwd ~Working directory /kwikemart/marge/ezannoni/flathead-dev/devo/gdb. ^done (gdb)
В процессе выполнения, подчиненная программа может достигнуть конца, если она не встретит ни одной точки останова. В этом случае вывод будет включать код завершения, если программа завершилась ненормально.
Программа завершилась нормально:
(gdb) -exec-run ^running (gdb) x = 55 *stopped,reason="exited-normally" (gdb)
Программа завершилась ненормально:
(gdb) -exec-run ^running (gdb) x = 55 *stopped,reason="exited",exit-code="01" (gdb)
Кроме того, программа может завершиться так, как если бы она получила
сигнал, например SIGINT
. В этом случае, GDB/MI отображает
следующее:
(gdb) *stopped,reason="exited-signalled",signal-name="SIGINT", signal-meaning="Interrupt"
-exec-abort
-exec-abort
Убить выполняющуюся подчиненную программу.
Соответствующей командой GDB является `kill'.
Н.П.
-exec-arguments
-exec-arguments арг
Установить аргументы подчиненной программы, которые должны быть использованы при следующем `-exec-run'.
Соответствующей командой GDB является `set args'.
Пока нет.
-exec-continue
-exec-continue
Асинхронная команда. Возобновляет выполнение подчиненной программы до тех пор, пока не будет встречена точка останова, или пока подчиненная программа не завершится.
Соответствующей командой GDB является `continue'.
-exec-continue ^running (gdb) @Hello world *stopped,reason="breakpoint-hit",bkptno="2",frame={func="foo",args={}, file="hello.c",line="13"} (gdb)
-exec-finish
-exec-finish
Асинхронная команда. Возобновляет выполнение подчиненной программы до тех пор, пока не завершится текущая функция. Отображает результаты, возвращенные функцией.
Соответствующей командой GDB является `finish'.
Функция, возвращающая void
.
-exec-finish ^running (gdb) @hello from foo *stopped,reason="function-finished",frame={func="main",args={}, file="hello.c",line="7"} (gdb)
Функция, возвращающая что-либо отличное от void
. Печатается имя
внутренней переменной GDB, хранящей результат, а также и сам
результат.
-exec-finish ^running (gdb) *stopped,reason="function-finished",frame={addr="0x000107b0",func="foo", args={{name="a",value="1"},{name="b",value="9"}}, file="recursive2.c",line="14"}, gdb-result-var="$1",return-value="0" (gdb)
-exec-interrupt
-exec-interrupt
Асинхронная команда. Прерывает фоновое исполнение цели. Заметьте, что лексема, ассоциированная с сообщением об останове, совпадает с лексемой для выполнения команды, которая была прервана. Лексема для самого прерывания появляется только в выводе `^done'. Если пользователь пытается прервать невыполняющуюся программу, будет выведено сообщение об ошибке.
Соответствующей командой GDB является `interrupt'.
(gdb) 111-exec-continue 111^running (gdb) 222-exec-interrupt 222^done (gdb) 111*stopped,signal-name="SIGINT",signal-meaning="Interrupt", frame={addr="0x00010140",func="foo",args={},file="try.c",line="13"} (gdb) (gdb) -exec-interrupt ^error,msg="mi_cmd_exec_interrupt: Inferior not executing." (gdb)
-exec-next
-exec-next
Асинхронная команда. Возобновляет выполнение подчиненной программы, останавливая ее, когда достигается начало следующей строки исходного текста.
Соответствующей командой GDB является `next'.
-exec-next ^running (gdb) *stopped,reason="end-stepping-range",line="8",file="hello.c" (gdb)
-exec-next-instruction
-exec-next-instruction
Асинхронная команда. Выполняет одну машинную инструкцию. Если инструкция является вызовом функции, выполнение продолжается до возврата из функции. Если программа останавливается на инструкции в середине строки исходного текста, печатается также адрес.
Соответствующей командой GDB является `nexti'.
(gdb) -exec-next-instruction ^running (gdb) *stopped,reason="end-stepping-range", addr="0x000100d4",line="5",file="hello.c" (gdb)
-exec-return
-exec-return
Велит текущей функции немедленно вернуться. Не выполняет подчиненную программу. Отображает новый текущий кадр.
Соответствующей командой GDB является `return'.
(gdb) 200-break-insert callee4 200^done,bkpt={number="1",addr="0x00010734", file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"} (gdb) 000-exec-run 000^running (gdb) 000*stopped,reason="breakpoint-hit",bkptno="1", frame={func="callee4",args={}, file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"} (gdb) 205-break-delete 205^done (gdb) 111-exec-return 111^done,frame={level="0 ",func="callee3", args={{name="strarg", value="0x11940 \"A string argument.\""}}, file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"} (gdb)
-exec-run
-exec-run
Асинхронная команда. Начинает выполнение подчиненной программы с начала. Она выполняется до тех пор, пока либо не встретится точка останова, либо программа не завершится.
Соответствующей командой GDB является `run'.
(gdb) -break-insert main ^done,bkpt={number="1",addr="0x0001072c",file="recursive2.c",line="4"} (gdb) -exec-run ^running (gdb) *stopped,reason="breakpoint-hit",bkptno="1", frame={func="main",args={},file="recursive2.c",line="4"} (gdb)
-exec-show-arguments
-exec-show-arguments
Печатает аргументы программы.
Соответствующей командой GDB является `show args'.
Н.П.
-exec-step
-exec-step
Асинхронная команда. Возобновляет выполнение подчиненной программы, останавливая ее, когда будет достигнуто начало следующей строки исходного файла, при условии, что она не является вызовом функции. Если же следующая строка является вызовом функции, программа останавливается на первой инструкции этой функции.
Соответствующей командой GDB является `step'.
Пошаговый вход в функцию:
-exec-step ^running (gdb) *stopped,reason="end-stepping-range", frame={func="foo",args={{name="a",value="10"}, {name="b",value="0"}},file="recursive2.c",line="11"} (gdb)
Обычное пошаговое выполнение:
-exec-step ^running (gdb) *stopped,reason="end-stepping-range",line="14",file="recursive2.c" (gdb)
-exec-step-instruction
-exec-step-instruction
Асинхронная команда. Возобновляет выполнение подчиненной программы, выполняя одну машинную инструкцию. Вывод, когда GDB остановится, будет различаться в зависимости от того, остановились мы в середине исходной строки или нет. В первом случае, адрес, по которому программа остановлена, также будет напечатан.
Соответствующей командой GDB является `stepi'.
(gdb) -exec-step-instruction ^running (gdb) *stopped,reason="end-stepping-range", frame={func="foo",args={},file="try.c",line="10"} (gdb) -exec-step-instruction ^running (gdb) *stopped,reason="end-stepping-range", frame={addr="0x000100f4",func="foo",args={},file="try.c",line="10"} (gdb)
-exec-until
-exec-until [ местоположение ]
Асинхронная команда. Выполняет подчиненную программу до тех пор, пока не будет достигнуто указанное в аргументе местоположение. Если аргумента нет, подчиненная программа выполняется, пока не будет достигнута строка исходного текста, превышающая текущую. В этом случае, причиной остановки будет `location-reached'.
Соответствующей командой GDB является `until'.
(gdb) -exec-until recursive2.c:6 ^running (gdb) x = 55 *stopped,reason="location-reached",frame={func="main",args={}, file="recursive2.c",line="6"} (gdb)
-file-exec-and-symbols
-file-exec-and-symbols файл
Указать выполняемый файл для отладки. Это тот файл, из которого также читается таблица символов. Если файл не указан, команда очищает информацию о выполняемом файле и символах. Если при использовании этой команды без аргументов установлены точки останова, GDB выдаст сообщение об ошибке. В противном случае, никакого вывода не будет, за исключением уведомления о завершении.
Соответствующей командой GDB является `file'.
(gdb) -file-exec-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx ^done (gdb)
-file-exec-file
-file-exec-file файл
Указать выполняемый файл для отладки. В отличие от `-file-exec-and-symbols', таблица символов не считывается из этого файла. При использовании без аргумента, GDB очищает информацию о выполняемом файле. Никакого вывода не производится, за исключением уведомления о завершении.
Соответствующей командой GDB является `exec-file'.
(gdb) -file-exec-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx ^done (gdb)
-file-list-exec-sections
-file-list-exec-sections
Перечисляет разделы текущего выполняемого файла.
Команда GDB `info file' показывает, помимо всего прочего,
ту же информацию, что и эта команда. gdbtk
имеет соответствующую
команду `gdb_load_info'.
Н.П.
-file-list-exec-source-files
-file-list-exec-source-files
Перечисляет исходные файлы для текущего выполняемого файла.
В GDB нет команды, непосредственно соответсвующей этой.
gdbtk
имеет аналогичную команду `gdb_listfiles'.
Н.П.
-file-list-shared-libraries
-file-list-shared-libraries
Перечисляет используемые программой разделяемые библиотеки.
Соответствующей командой GDB является `info shared'.
Н.П.
-file-list-symbol-files
-file-list-symbol-files
Перечисляет файлы символов.
Соответствующей командой GDB является `info file' (ее часть).
Н.П.
-file-symbol-file
-file-symbol-file файл
Прочитать информацию символьной таблицы из указанного в аргументе файла. Будучи использованной без аргументов, очищиет таблицу символьной информации GDB. Никакого вывода не производится, кроме уведомления о завершении.
Соответствующей командой GDB является `symbol-file'.
(gdb) -file-symbol-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx ^done (gdb)
-gdb-exit
-gdb-exit
Немедленно выйти из GDB.
Примерно соответствует команде `quit'.
(gdb) -gdb-exit
-gdb-set
-gdb-set
Установить внутреннюю переменную GDB.
Соответствующей командой GDB является `set'.
(gdb) -gdb-set $foo=3 ^done (gdb)
-gdb-show
-gdb-show
Показать текущее значение переменной GDB.
Соответствующей командой GDB является `show'.
(gdb) -gdb-show annotate ^done,value="0" (gdb)
-gdb-version
-gdb-version
Вывести информацию о версии GDB. Используется преимущественно при тестировании.
Эквивалентной команды GDB нет. По умолчанию, GDB показывает эту информацию, когда вы вызываете интерактивный сеанс.
(gdb) -gdb-version ~GNU gdb 5.2.1 ~Copyright 2000 Free Software Foundation, Inc. ~GDB is free software, covered by the GNU General Public License, and ~you are welcome to change it and/or distribute copies of it under ~ certain conditions. ~Type "show copying" to see the conditions. ~There is absolutely no warranty for GDB. Type "show warranty" for ~ details. ~This GDB was configured as "--host=sparc-sun-solaris2.5.1 --target=ppc-eabi". ^done (gdb)
-stack-info-frame
-stack-info-frame
Получить информацию о текущем кадре.
Соответствующей командой GDB является `info frame' или `frame' (без аргументов).
Н.П.
-stack-info-depth
-stack-info-depth [ макс-глуб ]
Возвращает глубину стека. Если указан целочисленный аргумент макс-глуб, не считать более макс-глуб кадров.
Эквивалентной команды GDB нет.
Для стека с уровнями кадров от 0 до 11:
(gdb) -stack-info-depth ^done,depth="12" (gdb) -stack-info-depth 4 ^done,depth="4" (gdb) -stack-info-depth 12 ^done,depth="12" (gdb) -stack-info-depth 11 ^done,depth="11" (gdb) -stack-info-depth 13 ^done,depth="12" (gdb)
-stack-list-arguments
-stack-list-arguments показ-знач [ нижн-кадр верхн-кадр ]
Отобразить список аргументов для кадров от нижн-кадр до верхн-кадр (включительно). Если нижн-кадр и верхн-кадр не указаны, перечислить аргументы для всего стека вызовов.
Аргумент показ-знач должен иметь значение 0 или 1. Значение 0 означает, что выводятся только имена аргументов, а 1,---что печатаются как имена, так и значения аргументов.
GDB не имеет эквивалентной команды. В gdbtk
есть
команда `gdb_get_args', которая частично перекрывается с действием
`-stack-list-arguments'.
(gdb) -stack-list-frames ^done, stack={ frame={level="0 ",addr="0x00010734",func="callee4", file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"}, frame={level="1 ",addr="0x0001076c",func="callee3", file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="17"}, frame={level="2 ",addr="0x0001078c",func="callee2", file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="22"}, frame={level="3 ",addr="0x000107b4",func="callee1", file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="27"}, frame={level="4 ",addr="0x000107e0",func="main", file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="32"}} (gdb) -stack-list-arguments 0 ^done, stack-args={ frame={level="0",args={}}, frame={level="1",args={name="strarg"}}, frame={level="2",args={name="intarg",name="strarg"}}, frame={level="3",args={name="intarg",name="strarg",name="fltarg"}}, frame={level="4",args={}}} (gdb) -stack-list-arguments 1 ^done, stack-args={ frame={level="0",args={}}, frame={level="1", args={{name="strarg",value="0x11940 \"Строковый аргумент.\""}}}, frame={level="2",args={ {name="intarg",value="2"}, {name="strarg",value="0x11940 \"Строковый аргумент.\""}}}, {frame={level="3",args={ {name="intarg",value="2"}, {name="strarg",value="0x11940 \"Строковый аргумент.\""}, {name="fltarg",value="3.5"}}}, frame={level="4",args={}}} (gdb) -stack-list-arguments 0 2 2 ^done,stack-args={frame={level="2",args={name="intarg",name="strarg"}}} (gdb) -stack-list-arguments 1 2 2 ^done,stack-args={frame={level="2", args={{name="intarg",value="2"}, {name="strarg",value="0x11940 \"Строковый аргумент.\""}}}} (gdb)
-stack-list-frames
-stack-list-frames [ нижн-кадр верхн-кадр ]
Перечисляет кадры, находящиеся в данный момент в стеке. Для каждого кадра, команда отображает следующую информацию:
$pc
для этого кадра.
$pc
.
Будучи вызванной без аргументов, эта команда печатает цепочку вызовов для всего стека. Если задано два целочисленных аргумента, она показывает кадры с уровнями между этими аргументами (включительно). Если аргументы равны, она показывает один единственный кадр соответствующего уровня.
Соответствующими командами GDB являются `backtrace' и `where'.
Цепочка вызовов стека целиком:
(gdb) -stack-list-frames ^done,stack= {frame={level="0 ",addr="0x0001076c",func="foo", file="recursive2.c",line="11"}, frame={level="1 ",addr="0x000107a4",func="foo", file="recursive2.c",line="14"}, frame={level="2 ",addr="0x000107a4",func="foo", file="recursive2.c",line="14"}, frame={level="3 ",addr="0x000107a4",func="foo", file="recursive2.c",line="14"}, frame={level="4 ",addr="0x000107a4",func="foo", file="recursive2.c",line="14"}, frame={level="5 ",addr="0x000107a4",func="foo", file="recursive2.c",line="14"}, frame={level="6 ",addr="0x000107a4",func="foo", file="recursive2.c",line="14"}, frame={level="7 ",addr="0x000107a4",func="foo", file="recursive2.c",line="14"}, frame={level="8 ",addr="0x000107a4",func="foo", file="recursive2.c",line="14"}, frame={level="9 ",addr="0x000107a4",func="foo", file="recursive2.c",line="14"}, frame={level="10",addr="0x000107a4",func="foo", file="recursive2.c",line="14"}, frame={level="11",addr="0x00010738",func="main", file="recursive2.c",line="4"}} (gdb)
Показать кадры между нижн-кадр и верхн-кадр:
(gdb) -stack-list-frames 3 5 ^done,stack= {frame={level="3 ",addr="0x000107a4",func="foo", file="recursive2.c",line="14"}, frame={level="4 ",addr="0x000107a4",func="foo", file="recursive2.c",line="14"}, frame={level="5 ",addr="0x000107a4",func="foo", file="recursive2.c",line="14"}} (gdb)
Показать один кадр:
(gdb) -stack-list-frames 3 3 ^done,stack= {frame={level="3 ",addr="0x000107a4",func="foo", file="recursive2.c",line="14"}} (gdb)
-stack-list-locals
-stack-list-locals печатать-значения
Вывести имена локальных переменных для текущего кадра. С параметром 0 выводит только имена переменных, с параметром 1 выводит также их значения.
`info locals' в GDB, `gdb_get_locals' в gdbtk
.
(gdb) -stack-list-locals 0 ^done,locals={name="A",name="B",name="C"} (gdb) -stack-list-locals 1 ^done,locals={{name="A",value="1"},{name="B",value="2"}, {name="C",value="3"}} (gdb)
-stack-select-frame
-stack-select-frame ном-кадра
Изменить текущий кадр. Выбрать другой кадр ном-кадра в стеке.
Соответствующими командами GDB являются `frame', `up', `down', `select-frame', `up-silent' и `down-silent'.
(gdb) -stack-select-frame 2 ^done (gdb)
-symbol-info-address
-symbol-info-address символ
Описать, где хранится символ.
Соответствующей командой GDB является `info address'.
Н.П.
-symbol-info-file
-symbol-info-file
Показать файл для символа.
Эквивалентной команды GDB нет. В gdbtk
есть команда
`gdb_find_file'.
Н.П.
-symbol-info-function
-symbol-info-function
Показать, в какой функции находится символ.
`gdb_get_function' в gdbtk
.
Н.П.
-symbol-info-line
-symbol-info-line
Показать адреса памяти кода для текущей строки.
Соответствующей командой GDB является `info line'. В
gdbtk
есть команды `gdb_get_line' и `gdb_get_file'.
Н.П.
-symbol-info-symbol
-symbol-info-symbol адрес
Описать, какой символ находится в местоположении адрес.
Соответствующей командой GDB является `info symbol'.
Н.П.
-symbol-list-functions
-symbol-list-functions
Перечислить функции, находящиеся в выполняемом файле.
`info functions' в GDB, `gdb_listfunc' и
`gdb_search' в gdbtk
.
Н.П.
-symbol-list-types
-symbol-list-types
Перечислить все имена типов.
Соответствующими командами являются `info types' в GDB и
`gdb_search' в gdbtk
.
Н.П.
-symbol-list-variables
-symbol-list-variables
Перечислить имена всех глобальных и статических переменных.
`info variables' в GDB, `gdb_search' в gdbtk
.
Н.П.
-symbol-locate
-symbol-locate
`gdb_loc' в gdbtk
.
Н.П.
-symbol-type
-symbol-type переменная
Показать тип переменной.
Соответствующей командой GDB является `ptype', в
gdbtk
есть команда `gdb_obj_variable'.
Н.П.
-target-attach
-target-attach ид-проц | файл
Присоединиться к процессу ид-проц или файлу файл вне GDB.
Соответствующей командой GDB является `attach'.
Н.П.
-target-compare-sections
-target-compare-sections [ раздел ]
Сравнить данные раздела раздел на цели с выполняемым файлом. Без аргумента сравниваются все разделы.
Эквивалентной командой в GDB является `compare-sections'.
Н.П.
-target-detach
-target-detach
Отсоединиться от удаленной цели. Никакого вывода не производится.
Соответствующей командой GDB является `detach'.
(gdb) -target-detach ^done (gdb)
-target-download
-target-download
Загружает выполняемый файл на удаленную цель. Команда два раза в секунду обновляет сообщение, которое включает поля:
Каждое сообщение посылается в виде сообщения статуса (see section Выходной синтаксис GDB/MI).
Кроме того, команда печатает имена и размеры разделов, по мере их загрузки. Эти сообщения включают следующие поля:
В конце печатается суммарная информация.
Соответствующей командой GDB является `load'.
Замечание: каждое сообщение статуса появляется на одной строке. Здесь сообщения были разбиты на несколько строк, чтобы они могли влезть на страницу.
(gdb) -target-download +download,{section=".text",section-size="6668",total-size="9880"} +download,{section=".text",section-sent="512",section-size="6668", total-sent="512",total-size="9880"} +download,{section=".text",section-sent="1024",section-size="6668", total-sent="1024",total-size="9880"} +download,{section=".text",section-sent="1536",section-size="6668", total-sent="1536",total-size="9880"} +download,{section=".text",section-sent="2048",section-size="6668", total-sent="2048",total-size="9880"} +download,{section=".text",section-sent="2560",section-size="6668", total-sent="2560",total-size="9880"} +download,{section=".text",section-sent="3072",section-size="6668", total-sent="3072",total-size="9880"} +download,{section=".text",section-sent="3584",section-size="6668", total-sent="3584",total-size="9880"} +download,{section=".text",section-sent="4096",section-size="6668", total-sent="4096",total-size="9880"} +download,{section=".text",section-sent="4608",section-size="6668", total-sent="4608",total-size="9880"} +download,{section=".text",section-sent="5120",section-size="6668", total-sent="5120",total-size="9880"} +download,{section=".text",section-sent="5632",section-size="6668", total-sent="5632",total-size="9880"} +download,{section=".text",section-sent="6144",section-size="6668", total-sent="6144",total-size="9880"} +download,{section=".text",section-sent="6656",section-size="6668", total-sent="6656",total-size="9880"} +download,{section=".init",section-size="28",total-size="9880"} +download,{section=".fini",section-size="28",total-size="9880"} +download,{section=".data",section-size="3156",total-size="9880"} +download,{section=".data",section-sent="512",section-size="3156", total-sent="7236",total-size="9880"} +download,{section=".data",section-sent="1024",section-size="3156", total-sent="7748",total-size="9880"} +download,{section=".data",section-sent="1536",section-size="3156", total-sent="8260",total-size="9880"} +download,{section=".data",section-sent="2048",section-size="3156", total-sent="8772",total-size="9880"} +download,{section=".data",section-sent="2560",section-size="3156", total-sent="9284",total-size="9880"} +download,{section=".data",section-sent="3072",section-size="3156", total-sent="9796",total-size="9880"} ^done,address="0x10004",load-size="9880",transfer-rate="6586", write-rate="429" (gdb)
-target-exec-status
-target-exec-status
Предоставить информацию о состоянии цели (например, выполняется она или нет).
Эквивалентной команды GDB нет.
Н.П.
-target-list-available-targets
-target-list-available-targets
Перечислить цели, к которым можно установить соединение.
Соответствующей командой GDB является `help target'.
Н.П.
-target-list-current-targets
-target-list-current-targets
Описать текущую цель.
Соответствующая информация (вместе с другой) печатается командой `info file'.
Н.П.
-target-list-parameters
-target-list-parameters
Эквивалента нет.
Н.П.
-target-select
-target-select тип параметры ...
Соединить GDB с удаленной целью. Эта команда допускает два аргумента:
Результатом является уведомление о соединении, за которым следует адрес, по которому находится целевая программа, в следующей форме:
^connected,addr="адрес",func="имя функции", args={список аргументов}
Соответствующей командой GDB является `target'.
(gdb) -target-select async /dev/ttya ^connected,addr="0xfe00a300",func="??",args={} (gdb)
-thread-info
-thread-info
Эквивалента нет.
Н.П.
-thread-list-all-threads
-thread-list-all-threads
Эквивалентной командой GDB является `info threads'.
Н.П.
-thread-list-ids
-thread-list-ids
Выводит список известных GDB в данный момент идентификаторов нитей. В конце списка также выводится общее число таких нитей.
Часть `info threads' предоставляет ту же информацию.
Кроме основного процесса нет ни одной нити:
(gdb) -thread-list-ids ^done,thread-ids={},number-of-threads="0" (gdb)
Несколько нитей:
(gdb) -thread-list-ids ^done,thread-ids={thread-id="3",thread-id="2",thread-id="1"}, number-of-threads="3" (gdb)
-thread-select
-thread-select номер-нити
Сделать нить номер-нити текущей. Команда выводит номер новой текущей нити и самый верхний кадр для нее.
Соответствующей командой GDB является `thread'.
(gdb) -exec-next ^running (gdb) *stopped,reason="end-stepping-range",thread-id="2",line="187", file="../../../devo/gdb/testsuite/gdb.threads/linux-dp.c" (gdb) -thread-list-ids ^done, thread-ids={thread-id="3",thread-id="2",thread-id="1"}, number-of-threads="3" (gdb) -thread-select 3 ^done,new-thread-id="3", frame={level="0 ",func="vprintf", args={{name="format",value="0x8048e9c \"%*s%c %d %c\\n\""}, {name="arg",value="0x2"}},file="vprintf.c",line="31"} (gdb)
Команды для точек трассировки еще не реализованы.
Для реализации изменяемого отладочного окна (локальные переменные,
наблюдаемые выражения, и т.д.), мы предлагаем модификацию существующего
кода, используемого в Insight
.
Вот две основные причины для этого:
Первоначальный интерейс был разработан для использование кодом Tcl, так что он был немного изменен, чтобы его можно было использовать через GDB/MI. Этот раздел описывает операции GDB/MI, которые будут доступны, и дает некоторые советы по их использованию.
Замечание: В дополнение к описанному здесь набору операций, мы ожидаем, что GUI-реализация изменяемого окна будет требовать, как минимум, следующие операции:
-gdb-show
output-radix
-stack-list-arguments
-stack-list-locals
-stack-select-frame
Основной идеей изменяемых объектов является создание именованного объекта для представления переменной, выражения, местоположения в памяти или даже регистра ЦП. Для каждого созданного объекта существует набор операций для изучения или изменения его свойств.
Более того, сложные типы данных, такие как структуры Си, представлены в
древовидном формате. Например, переменная типа struct
является
корнем, а потомки будут представлять элементы этой структуры. Если
потомок сам является сложным типом, он также будет иметь своих потомков.
Соответствующие различия языков учитываются для Си, Си++ и Java.
При возврате реальных значений объектов, эта возможность позволяет
отдельно выбирать формат отображения, используемый при создании
результата. Он может быть выбран из: двоичный, десятичный,
шестнадцатеричный, восьмеричный и обычный. Обычный ссылается на формат
по умолчанию, выбираемый автоматически в зависимости от типа переменной
(например, десятичный для int
, шестнадцатеричный для указателей,
и т.д.).
Далее следует полный набор операций GDB/MI, определенный для доступа к этим возможностям:
Операция | Описание |
-var-create |
создать изменяемый объект |
-var-delete |
удалить изменяемый объект и его потомков |
-var-set-format |
установить формат отображения для этой переменной |
-var-show-format |
показать формат отображения для этой переменной |
-var-info-num-children |
сообщает, сколько потомков имеет данный объект |
-var-list-children |
возвращает список потомков объекта |
-var-info-type |
показать тип этого изменяемого объекта |
-var-info-expression |
напечатать, что представляет этот изменяемый объект |
-var-show-attributes |
является ли эта переменная редактируемой? она здесь существует? |
-var-evaluate-expression |
получить значение этой переменной |
-var-assign |
установить значение этой переменной |
-var-update |
скорректировать переменную и ее потомков |
В следующем подразделе мы подробно описываем каждую операцию и предлагаем возможный способ ее использования.
-var-create
-var-create {имя | "-"} {адрес-кадра | "*"} выражение
Данная операция создает изменяемый объект. Это позволяет наблюдать за переменной, результатом выражения, ячейкой памяти или регистром ЦП.
Параметр имя является строкой, по которой можно ссылаться на объект. Она должен быть уникальной. Если указан `-', система изменяемых объектов автоматически сгенерирует строку "varNNNNNN". Она будет уникальной, при условии, что имя не будет указано в этом формате. Команда завершается ошибкой, если найдено повторяющееся имя.
В адресе-кадра может быть задан кадр, в котором должно быть вычислено выражение. `*' указывает, что должен использоваться текущий кадр.
Выражение---это произвольное выражение, правильное в текущем наборе языков (не должно начинаться со `*'), или одно из следующего:
Эта операция возвращает имя, число потомков и тип созданного объекта. Тип возвращается как строка, как будто она создана GDB CLI:
name="имя",numchild="N",type="тип"
-var-delete
-var-delete имя
Удаляет созданный ранее изменяемый объект и всех его потомков.
Возвращает ошибку, если объект с именем имя не найден.
-var-set-format
-var-set-format имя специф-формата
Устанавливает формат вывода в специф-формата для значения объекта имя.
Синтаксис специф-формата следующий:
специф-формата ==> {binary | decimal | hexadecimal | octal | natural}
-var-show-format
-var-show-format имя
Возвращает формат, используемый для отображения значений объекта имя.
формат ==> специф-формата
-var-info-num-children
-var-info-num-children имя
Возвращает число потомков изменяемого объекта с именем имя:
numchild=n
-var-list-children
-var-list-children имя
Возвращает список потомков указанного изменяемого объекта:
numchild=n,children={{name=имя, numchild=n,type=тип},(повторяется N раз)}
-var-info-type
-var-info-type имя
Возвращает тип указанного изменяемого объекта имя. Тип возвращается как строка в том же формате, в котором она выдается GDB CLI:
type=имя-типа
-var-info-expression
-var-info-expression имя
Возвращает то, что представляет изменяемый объект с именем имя:
lang=специф-языка,exp=выражение
где специф-языка есть {"C" | "C++" | "Java"}
.
-var-show-attributes
-var-show-attributes имя
Перечисляет атрибуты заданного изменяемого объекта имя:
status=атр [ ( ,атр )* ]
где атр есть { { editable | noneditable } | TBD }
.
-var-evaluate-expression
-var-evaluate-expression имя
Вычисляет выражение, которое представлено указанным изменяемым объектом и возвращает его значение в виде строки в текущем формате, определенном для объекта:
value=значение
-var-assign
-var-assign имя выражение
Присваивает значение выражения изменяемому объекту, заданному именем. Объект должен быть в состоянии `editable'.
-var-update
-var-update {имя | "*"}
Обновить значение изменяемого объекта с именем имя путем вычисления его выражения, после получения всех новых значений из памяти или регистров. `*' приводит к обновлению всех существующих изменяемых объектов.
Одной проблемой, обнаруженной в существующем синтаксисе вывода GDB/MI, была трудность в нахождении отличий между наборами вроде этого:
{number="1",type="breakpoint",disp="keep",enabled="y"}
где каждое значение имеет уникальную метку, и таким списком:
{"1","2","4"} {bp="1",bp="2",bp="4"}
где значения не имеют меток, или метки повторяются.
Далее представлен черновик изменений к спецификации вывода, который решает эту проблему.
Вывод GDB/MI состоит из нуля или более внеочередных записей, за которыми может следовать одна результирующая запись, причем она относится к самой последней введенной команде. Последовательность завершается `gdb'.
Асинхронный вывод GDB/MI такой же.
Каждая выходная запись, непосредственно связанная с входной командой,
начинается с префикса лексема
входной команды.
вывод ==>
[
рез-запись ]
"(gdb)
" nl
рез-запись ==>
[
лексема ]
"^" рез-класс { "," результат } nl
внеочередная-запись ==>
|
поточн-запись
асинхр-запись ==>
|
асинхр-вывод-статуса |
асинхр-вывод-уведомл
асинхр-вывод-выполн ==>
[
лексема ]
"*" асинхр-вывод
асинхр-вывод-статуса ==>
[
лексема ]
"+" асинхр-вывод
асинхр-вывод-уведомл ==>
[
лексема ]
"=" асинхр-вывод
асинхр-вывод ==>
результ-класс ==>
|
"running" |
"connected" |
"error" |
"exit"
асинхр-класс ==>
|
другое по необходимости, т.к. находится в
стадии разработки
результат ==>
значение ==>
|
набор |
список
набор ==>
|
"{" результат { "," результат } "}"
список ==>
[]
" |
"[
" значение { "," значение } "]
"
строка ==>
строка-си ==>
поточн-запись ==>
|
целев-поточн-вывод |
журн-поточн-вывод
консольн-поточн-вывод ==>
целев-поточн-вывод ==>
журн-поточн-вывод ==>
nl ==>
|
CR-LF
лексема ==>
Кроме того, следующее находится в стадии разработки.
запрос
Замечания:
Лексема
берется из соответствующего запроса. Если
выполняющаяся команда прерывается командой -exec-interrupt
,
лексема, ассоциированная с сообщением `*stopped', берется из исходной
выполнявшейся команды, а не из команды прерывания.
Ваши отчеты об ошибках играют существенную роль в обеспечении надежности GDB.
Сообщение об ошибке может помочь вам найти решение вашей проблемы, а может и не помочь. Но в любом случае, основная функция отчета об ошибке---помочь всему обществу сделать следующую версию GDB лучше. Отчеты об ошибках---это ваш вклад в поддержку GDB.
Чтобы отчет об ошибке сделал свое дело, вы должны включить в него информацию, которая даст нам возможность ее устранить.
Если вы не уверены, нашли ли вы ошибку, вот несколько руководящих принципов:
Некоторые компании и частные лица предлагают поддержку для программных продуктов GNU. Если вы получили GDB из организации поддержки, мы рекомендуем вам сперва связаться с ней.
Вы можете найти контактную информацию для многих организаций поддержки и частных лиц в файле `etc/SERVICE' в дистрибутиве GNU Emacs.
В любом случае, мы также рекомендуем вам послать отчет об ошибке в GDB по этому адресу:
bug-gdb@gnu.org
Не посылайте отчеты об ошибках в `info-gdb', или в `help-gdb', или в какую-либо группу новостей. Большинство пользователей GDB не хотят получать отчеты об ошибках. Те, кто этого действительно хочет, должны получать `bug-gdb'.
Список рассылки `bug-gdb' имеет группу новостей `gnu.gdb.bug', которая служит как повторитель. Список рассылки и группа новостей имеют в точности одинаковые сообщения. Часто люди посылают сообщения об ошибках в группу новостей, вместо отправки по электронной почте. Это работает, но имеется одна проблема, которая может быть решающей: группа новостей часто не имеет информации об обратном адресе отправителя. Таким образом, если нам потребуется запросить дополнительную информацию, мы можем не иметь возможности связаться с вами. По этой причине, лучше посылать отчеты об ошибках в список рассылки.
В крайнем случае, посылайте отчеты об ошибках на бумаге по адресу:
GNU Debugger Bugs Free Software Foundation Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307 USA
Основной принцип действенного составления отчетов об ошибках: сообщайте все факты. Если вы не уверены, оставить факт или исключить, оставьте его!
Часто люди опускают факты, потому что думают, что знают причины проблемы, и полагают, что некоторые детали не имеют значения. Таким образом, вы можете считать, что имя переменной, которую вы используете в примере, не имеет значения. Возможно это так, но нельзя быть уверенным в этом. Может быть ошибкой является неверное обращение к памяти, которое выбрало данные из ячеек, где хранилось это имя; возможно, если бы имя было другим, содержимое этих ячеек ввело бы отладчик в заблуждение, и ошибка не была бы замечена. Относитесь к этому осторожно, и приводите конкретные, полные примеры. Это самое простое что вы можете сделать, и наиболее полезное.
Помните, что цель отчета об ошибке состоит в том, чтобы дать нам возможность установить дефект. Может случиться, что об этой ошибке нам уже сообщали, но не вы, не мы не можем этого знать, если отчет об ошибке не будет полным и самодостаточным.
Иногда люди дают несколько поверхностных фактов и спрашивают, "не говорит ли это об ошибке?". Такие сообщения о дефектах бесполезны, и мы убеждаем всех отказываться отвечать на них, за исключением того, чтобы побудить автора отчета послать его правильно.
Чтобы дать нам возможность устранить ошибку, вы должны включить в сообщение следующее:
show version
.
Без этого мы не будем знать, имеет ли смысл поиск ошибки в текущей
версии отладчика.
gcc --version
чтобы получить эту информацию; для
других компиляторов, смотрите их документацию.
make
) достаточно.
Если мы должны будем угадывать аргументы, мы возможно сделаем это
неправильно и можем не столкнуться с ошибкой.
Вот некоторые вещи, не являющиеся обязательными:
Эта глава описывает основные возможности интерфейса редактирования командной строки GNU.
Следующие параграфы описывают нотацию, используемую для обозначения нажатия клавиш.
Текст C-k читается как `Control-K' и описывает знак, полученный нажатием клавиши k при нажатой клавише Control.
Текст M-k читается как `Meta-K' и описывает знак, введенный нажатием клавиши k при нажатой клавише Meta (если у вас она имеется). На многих клавиатурах клавиша Meta отмечается с помощью ALT. На клавиатурах с двумя клавишами, отмеченными ALT (обычно по разные стороны от пробела), ALT на левой стороне обычно устанавливается для работы клавишей Meta. Правый ALT также может быть сконфигурирован для работы Meta, или он может быть сконфигурирован как другой модификатор, например как клавиша Compose для ввода символов с акцентами.
Если у вас нет клавиши Meta или ALT, или другой клавиши, работающей как Meta, идентичное нажатие клавиш можно получить нажав сначала ESC, а затем k. Эти процессы называются метафикацией клавиши k.
Текст M-C-k читается как `Meta-Control-k' и описывает знак, полученный посредством метафикации C-k.
Кроме того, некоторые клавиши имеют собственные имена. Именно, DEL, ESC, LFD, SPC, RET и TAB в этом тексте или в файле инициализации обозначают сами себя (see section Файл инициализации Readline). Если на вашей клавиатуре нет клавиши LFD, нажатие C-j приведет к вводу желаемого символа. Клавиша RET на некоторых клавиатурах может быть отмечена как Return или Enter.
Часто во время интерактивного сеанса вы вводите длинную строку текста только для того, чтобы заметить, что первое слово набрано неправильно. Библиотека Readline дает вам набор команд для управления текстом во время ввода, позволяя вам лишь исправить опечатку, а не набирать заново большую часть строки. С помощью этих команд редактирования, вы перемещаете курсор в место, требующее исправления, и удаляете или вставляете текст для коррекции. Затем, когда строка полностью исправлена, вы просто нажимаете RET. Чтобы нажать RET вам не обязательно находиться в конце строки; вся строка вводится независимо от расположения в ней курсора.
Для того, чтобы ввести знак в строку, просто нажмите его. Введенный знак появляется там, где был курсор, и затем курсор перемещается на одну позицию вправо. Если вы неверно набрали знак, вы можете использовать ваш знак уничтожения, чтобы вернуться и удалить неверный знак.
Иногда вы можете набрать символ ошибочно, и не заметить ошибки, пока не напечатаете несколько других знаков. В этом случае, вы можете набрать C-b, чтобы переместить курсор влево, и затем исправить вашу ошибку. После этого, вы можете переместить курсор вправо нажатием C-f.
Когда вы добавляете текст в середину строки, символы справа от курсора `сдвигаются вперед', чтобы освободить место для вставляемого текста. Аналогично, когда вы удаляете текст за курсором, символы справа от него `сдвигаются назад', занимая пустое пространство, созданное в результате удаления текста. Ниже следует список команд первой необходимости для редактирования вводимого текста.
(В зависимости от вашей конфигурации, клавиша Backspace может быть настроена удалять знак слева от курсора, а DEL удалять знак под курсором, как C-d, вместо символа, расположенного от курсора слева.)
Приведенная выше таблица описывает только самые базовые последовательности клавиш, которые могут вам понадобиться для редактирования строки ввода. Для удобства, в дополнение к C-b, C-f, C-d и DEL были добавлены многие другие команды. Вот некоторые из них, предназначенные для более быстрого перемещения по строке.
Заметьте, что C-f перемещает курсор вперед на символ, в то время как M-f перемещает вперед на слово. Это своего рода соглашение, что при нажатии клавиши Сontrol производятся действия над символами, при нажатии клавиши Meta---над словами.
Уничтожение текста означает уничтожение текста из строки, но сохранение его для дальнейшего использования, обычно для восстановления (повторной вставки) обратно в строку. (`Вырезать' и `вставить' являются более свежими жаргонными синонимами для `уничтожить' и `восстановить'.)
Если в описании команды сказано, что она `уничтожает' текст, то вы можете быть уверены, что позже его можно будет получить обратно в другом (или том же самом) месте.
Когда вы используете команду уничтожения, текст сохраняется в кольцевом списке уничтожений. Любое число последовательных уничтожений сохраняет весь уничтоженный текст вместе, так что когда вы восстанавливаете его назад, вы получите все. Список уничтожений не имеет привязки к строкам; текст, уничтоженный вами в предыдущей строке ввода, доступен для восстановления позже, когда вы вводите другую строку.
Вот список команд для уничтожения текста.
Вот как можно восстановить текст обратно в строку. Восстановление означает копирование последнего уничтоженного текста из буфера уничтожений.
Вы можете передавать числовые параметры командам Readline. Иногда параметр действует как счетчик повторений, иногда он является знаком, если аргумент имеет знак. Если вы передаете отрицательный параметр команде, которая обычно действует в прямом направлении, то она будет действовать в обратном направлении. Например, чтобы уничтожить текст до начала строки, вы можете набрать `M-- C-k'.
Общий способ передачи числовых параметров команде состоит в наборе Meta-цифр перед командой. Если первая набранная `цифра' есть знак минус (`-'), тогда знак аргумента будет отрицательным. Если вы набрали одну мета-цифру для начала параметра, вы можете набрать оставшиеся цифры, и потом команду. Например, чтобы передать команде C-d параметр 10, вы можете набрать `M-1 0 C-d'.
Readline предоставляет команды для поиска в истории команд строк, содержащих указанную подстроку. Существует два режима поиска: наращиваемый и ненаращиваемый.
Наращиваемый поиск начинается до того, как пользователь закончит ввод
строки поиска. По мере ввода очередных символов строки поиска, Readline
отображает следующий элемент из истории, соответствующий строке,
введенной на данный момент. Наращиваемый поиск требует ровно столько
символов, сколько требуется для нахождения желаемого элемента истории.
Для поиска определенной строки в истории в обратном направлении, введите
C-r. Ввод C-s производит поиск в прямом направлении.
Символы, присутствующие в значении переменной isearch-terminators
,
используются для завершения наращиваемого поиска. Если этой переменной
не было присвоено значение, знаки ESC и C-J будут завершать
наращиваемый поиск. C-g прерывает наращиваемый поиск и
восстанавливает исходную строку. Когда поиск завершается, элемент
истории, содержащий искомую строку, становится текущей строкой.
Для нахождения других подходящих элементов списка истории, введите соответственно C-r или C-s. Это произведет поиск вперед или назад в истории до следующего элемента, соответствующего введенной строке поиска. Любая другая последовательность клавиш, привязанная к команде Readline, завершит поиск и выполнит эту команду. Например, RET завершит поиск и примет эту строку, таким образом выполняя команду из списка истории.
Ненаращиваемый поиск считывает строку поиска целиком, до начала поиска соответствующих строк истории. Строка поиска может быть введена пользователем или являться частью содержимого текущей строки.
Хотя библиотека Readline поставляется с установленным по умолчанию набором
привязок клавиш, аналогичному Emacs, возможно использование
другого набора привязок. Любой пользователь может настраивать
программы, которые используют Readline, помещая команды в файл
inputrc, обычно в своем домашнем каталоге. Имя этого
файла берется из переменной среды INPUTRC
. Если
эта переменная не установлена, по умолчанию берется файл `~/.inputrc'.
Когда запускается программа, использующая библиотеку Readline, файл инициализации считывается и устанавливаются привязки клавиш.
Кроме того, команда C-x C-r считывает файл инициализации заново, так что изменения, которые вы могли cделать к этому времени, вступают в силу.
Существуют всего несколько конструкций, которые допускаются в файле инициализации Readline. Пустые строки игнорируются. Строки, начинающиеся с `#', являются комментариями. Строки, начинающиеся с `$', обозначают условные конструкции (see section Условные конструкции инициализации). Другие строки обозначают установку переменных и привязки клавиш.
set
в
файле инициализации. Вот как можно изменить привязку клавиш Emacs,
используемую по умолчанию, для использования команд редактирования
строки vi
:
set editing-mode viОсновная часть поведения при выполнении изменяется с помощью следующих переменных.
bell-style
comment-begin
"#"
.
completion-ignore-case
completion-query-items
100
.
convert-meta
disable-completion
self-insert
. По умолчанию `off'.
editing-mode
editing-mode
контролирует, какой набор привязок клавиш
используется. По умолчанию, Readline запускается в режиме
редактирования Emacs, где нажатия клавиш очень похожи на Emacs. Эта
переменная может быть установлена или в `emacs', или в `vi'.
enable-keypad
expand-tilde
horizontal-scroll-mode
input-meta
meta-flag
является синонимом для этой переменной.
isearch-terminators
keymap
keymap
: emacs
,
emacs-standard
, emacs-meta
, emacs-ctlx
, vi
,
vi-command
и vi-insert
. vi
эквивалентно
vi-command
; emacs
эквивалентно emacs-standard
.
Значение по умолчанию emacs
. Значение переменной
editing-mode
также влияет на раскладку по умолчанию.
mark-directories
mark-modified-lines
output-meta
print-completions-horizontally
show-all-if-ambiguous
visible-stats
Control-u: universal-argument Meta-Rubout: backward-kill-word Control-o: "> output"В этом примере, C-u привязана к функции
universal-argument
,
а C-o привязана к выполнению макрокоманды, записанной с правой
стороны (то есть, вставить текст `> output' в строку).
"\C-u": universal-argument "\C-x\C-r": re-read-init-file "\e[11~": "Function Key 1"В этом примере, C-u привязывается к функции
universal-argument
(как это было в первом примере),
`C-x C-r' привязывается к функции
re-read-init-file
и `ESC [ 1 1 ~' привязывается к
вставке текста `Function Key 1'.
\C-
\M-
\e
\\
\"
\'
\a
\b
\d
\f
\n
\r
\t
\v
\nnn
ASCII
которого есть nnn
(от одной до трех цифр)
\xnnn
ASCII
которого есть nnn
(от одной до трех цифр)
"\C-x\\": "\\"
Readline реализует возможности, аналогичные по смыслу возможностям условной компиляции препроцессора Си, позволяющие производить привязки клавиш и установку переменных в результате тестов. Вот четыре директивы, используемые анализатором.
$if
$if
позволяет производить привязки в зависимости от
режима редактирования, используемого терминала, или приложения,
использующего Readline. Содержимое теста продолжается до конца строки;
для его ограничения не требуются никакие знаки.
mode
mode=
директивы $if
используется для проверки в
каком из режимов находится Readline: emacs
или vi
. Это
может быть использовано, например, вместе с командой `set keymap'
для установки привязок в наборы emacs-standard
и
emacs-ctlx
, только если Readline запускается в режиме
emacs
.
term
term=
может использоваться для включения привязок клавиш,
уникальных для какого-либо терминала, возможно для привязки вывода
последовательности клавиш к функциональным клавишам терминала. Слово,
стоящее справа от `=', сравнивается как с полным названием
терминала, так и с частью названия, идущей до первого `-'. Это
позволяет, например, опознавать как sun
, так и sun-cmd
.
application
$if Bash # Quote the current or previous word "\C-xq": "\eb\"\ef\"" $endif
$endif
$if
.
$else
$if
выполняются, если проверка
заканчивается неудачей.
$include
$include /etc/inputrc
Вот пример файла inputrc. Он иллюстрирует привязки клавиш, присвоение значений переменным и синтаксис условий.
# Этот файл управляет поведением редактирования строки ввода в # программах, использующих библиотеку Gnu Readline. Среди таких программ # FTP, Bash, и Gdb. # # Вы можете заново считать файл inputrc с помощью C-x C-r. # Строки, начинающиеся с '#', являются комментариями. # # Сначала, включим все общесистемные привязки и переменные из # /etc/Inputrc $include /etc/Inputrc # # Установка различных привязок для режима emacs. set editing-mode emacs $if mode=emacs Meta-Control-h: backward-kill-word Текст после имени функции игнорируется # # Стрелки в режиме малой клавиатуры # #"\M-OD": backward-char #"\M-OC": forward-char #"\M-OA": previous-history #"\M-OB": next-history # # Стрекли в режиме ANSI # "\M-[D": backward-char "\M-[C": forward-char "\M-[A": previous-history "\M-[B": next-history # # Стрелки в восьмибитном режиме малой клавиатуры # #"\M-\C-OD": backward-char #"\M-\C-OC": forward-char #"\M-\C-OA": previous-history #"\M-\C-OB": next-history # # Стрелки в восьмибитовом режиме ANSI # #"\M-\C-[D": backward-char #"\M-\C-[C": forward-char #"\M-\C-[A": previous-history #"\M-\C-[B": next-history C-q: quoted-insert $endif # Привязки старого стиля. Устанавливается по умолчанию. TAB: complete # Макрокоманды, удобные при взаимодействии с оболочкой $if Bash # редактирование пути "\C-xp": "PATH=${PATH}\e\C-e\C-a\ef\C-f" # Подготовка к вводу слова в кавычках -- вставляет открывающуюся и # закрывающуюся двойные кавычки и помещает курсор сразу за открывающей "\C-x\"": "\"\"\C-b" # вставляет обратную косую черту (testing backslash escapes in sequences # and macros) "\C-x\\": "\\" # Заключает в кавычки текущее или предыдущее слово "\C-xq": "\eb\"\ef\"" # Добавляет привязку для обновления строки, которая непривязана "\C-xr": redraw-current-line # Редактирование переменной в текущей строке "\M-\C-v": "\C-a\C-k$\C-y\M-\C-e\C-a\C-y=" $endif # использовать визуальный звонок, если он доступен set bell-style visible # не урезать символы при чтении до 7 бит set input-meta on # позволяет ввод символов iso-latin1, вместо из преобразования к # последовательностям с Meta-префиксом # prefix-meta sequences set convert-meta off # отображает символы непосредственно с установленным восьмым битом, а не # в виде знаков с Meta-префиксом set output-meta on # если существует более 150 возможных завершений слова, запросить # пользователя, хочет ли он видеть их все set completion-query-items 150 # Для FTP $if Ftp "\C-xg": "get \M-?" "\C-xt": "put \M-?" "\M-.": yank-last-arg $endif
Этот раздел описывает команды Readline, которые могут быть привязаны к последовательностям клавиш.
beginning-of-line (C-a)
end-of-line (C-e)
forward-char (C-f)
backward-char (C-b)
forward-word (M-f)
backward-word (M-b)
clear-screen (C-l)
redraw-current-line ()
accept-line (Newline, Return)
previous-history (C-p)
next-history (C-n)
beginning-of-history (M-<)
end-of-history (M->)
reverse-search-history (C-r)
forward-search-history (C-s)
non-incremental-reverse-search-history (M-p)
non-incremental-forward-search-history (M-n)
history-search-forward ()
history-search-backward ()
yank-nth-arg (M-C-y)
yank-last-arg (M-., M-_)
yank-nth-arg
. Последовательные вызовы yank-last-arg
перемещают назад по списку истории, вставляя последний аргумент каждой
строки по очереди.
delete-char (C-d)
delete-char
, возвращает EOF.
backward-delete-char (Rubout)
forward-backward-delete-char ()
quoted-insert (C-q, C-v)
tab-insert (M-TAB)
self-insert (a, b, A, 1, !, ...)
transpose-chars (C-t)
transpose-words (M-t)
upcase-word (M-u)
downcase-word (M-l)
capitalize-word (M-c)
kill-line (C-k)
backward-kill-line (C-x Rubout)
unix-line-discard (C-u)
kill-whole-line ()
kill-word (M-d)
forward-word
.
backward-kill-word (M-DEL)
backward-word
.
unix-word-rubout (C-w)
delete-horizontal-space ()
kill-region ()
copy-region-as-kill ()
copy-backward-word ()
backward-word
. Эта команда по умолчанию не
привязана.
copy-forward-word ()
forward-word
. Эта команда по умолчанию не
привязана.
yank (C-y)
yank-pop (M-y)
yank
или yank-pop
.
digit-argument (M-0, M-1, ... M--)
universal-argument ()
universal-argument
заканчивает числовой аргумент, а в
противном случае он игнорируется.
В особом случае, если непосредственно за этой командой следует или
цифра, или знак минус, аргумент для следующей команды умножается на
четыре. Изначально аргумент равен единице, так что выполнение этой
функции первый раз делает его равным четырем, второй раз---шестнадцати,
и так далее. По умолчанию эта функция не привязана к клавише.
complete (TAB)
possible-completions (M-?)
insert-completions (M-*)
possible-completions
.
menu-complete ()
complete
, но замещает завершаемое слово одним
совпадением из списка возможных завершений. Повторяемое выполнение
menu-complete
обходит список возможных завершений, вставляя
каждое совпадение по очереди. В конце списка завершений издается
звуковой сигнал и восстанавливается исходный текст. Аргумент n
перемещает на n позиций вперед в списке совпадений; отрицательный
аргумент может использоваться для перемещения по списку назад. Эта
команда предназначается для привязки к TAB, но по умолчанию не
привязана.
delete-char-or-list ()
delete-char
). Если курсор находится в конце строки,
поведение аналогично possible-completions
. Эта команда по
умолчанию не привязана.
start-kbd-macro (C-x ()
end-kbd-macro (C-x ))
call-last-kbd-macro (C-x e)
re-read-init-file (C-x C-r)
abort (C-g)
bell-style
).
do-uppercase-version (M-a, M-b, M-x, ...)
prefix-meta (ESC)
undo (C-_, C-x C-u)
revert-line (M-r)
undo
, чтобы вернуться в
начало.
tilde-expand (M-~)
set-mark (C-@)
exchange-point-and-mark (C-x C-x)
character-search (C-])
character-search-backward (M-C-])
insert-comment (M-#)
comment-begin
вставляется в начало текущей
строки, и строка вводится, так как если бы был введен знак ввода строки.
dump-functions ()
dump-variables ()
dump-macros ()
Хотя библиотека Readline не имеет полного набора функций редактирования
vi
, она все же содержит достаточно для простого редактирования
строки. Режим vi
Readline функционирует так, как определено в
стандарте POSIX 1003.2.
Для интерактивного переключения между режимами редактирования
emacs
и vi
, используйте команду M-C-j
(toggle-editing-mode
).
По умолчанию, Readline использует режим emacs
.
Когда вы вводите строку в режиме vi
, вы уже находитесь в режиме
`вставки', как если бы вы набрали `i'. Нажатие ESC
переключает вас в `командный' режим, в котором вы можете редактировать
текст строки стандартными клавишами перемещения vi
, перемещаться
к предыдущим строкам истории посредством `k' и к последующим
строкам посредством `j', и так далее.
Эта глава описывает, как использовать библиотеку GNU History интерактивно, c точки зрения пользователя. Она должна рассматриваться как руководство пользователя.
Библиотека History обеспечивает средства раскрывания истории, подобные
предоставляемым csh
. Этот раздел описывает
синтаксис, использующийся для управления информацией истории.
Раскрывание истории вводит слова из списка истории во входной поток, облегчая повторение команд, вставку аргументов предыдущей команды в текущую строку ввода, или быстрое устранение ошибок в предыдущей команде.
Раскрывание истории происходит в два этапа. Первый заключается в определении, какая из строк списка истории должна использоваться в процессе замены. На втором этапе выбираются части этой строки для включения в текущую. Строка, выбранная из истории, называется событием, а использованные части называются словами. Существуют различные модификаторы для манипулирования выбранными словами. Строка разбивается на слова так же, как это делает Bash, так что несколько слов, заключенных в кавычки, рассматриваются как одно слово. Раскрывания истории вводятся появлением знака раскрывания истории, по умолчанию `!'.
Указатель событий является ссылкой на запись командной строки в списке истории.
!
!
не следует пробел,
знак табуляции, знак конца строки, `=' или `('.
!n
!-n
!!
!строка
!?строка[?]
^строка1^строка2^
!!:s/строка1/строка2/
.
!#
Указатели слов используются для выбора желаемых слов из события. Спецификация события отделяется от указателя слова двоеточием. Его можно опустить, если указатель слова начинается с `^', `$', `*', `-' или `%'. Слова нумеруются от начала строки, причем первому слову присваивается номер 0 (ноль). Слова вставляются в текущую строку, разделенные одиночными пробелами.
Например,
!!
!!:$
!$
.
!fi:2
fi
.
Вот указатели слов:
0 (ноль)
n
^
$
%
x-y
*
x*
x-
Если указатель слова задается без указания события, в качестве события используется предыдущая команда.
После необязательного указателя слова, вы можете добавить последовательность из одного или более следующих модификаторов, перед каждым из которых ставится двоеточие.
h
r
e
p
s/старое/новое/
&
g
gs/старое/новое/
, или с `&'.
Выпуск 4 GDB содержит уже отформатированную справочную карточку, готовую к печати с PostScript или Ghostscript, в подкаталоге `gdb' главного исходного каталога(19). Если вы можете использовать PostScript или Ghostscript с вашим принтером, вы можете распечатать справочную карточку немедленно из `refcard.ps'.
Выпуск также включает исходный текст справочной карточки. Вы можете отформатировать ее при помощи TeX, набрав:
make refcard.dvi
Справочная карточка GDB разработана для печати в режиме landscape на бумаге американского размера "letter"; то есть на листе шириной 11 и высотой 8.5 дюймов. Вы должны будете указать этот формат печати в качестве ключа к вашей программе вывода DVI.
Вся документация для GDB поставляется как часть машинно-считываемого
дистрибутива. Документация написана в формате Texinfo, который
является системой построения документации, использующей один исходный файл,
для создания как интерактивного, так и печатного руководства. Вы
можете использовать одну из команд форматирования Info, чтобы создать
интерактивную версию документации, и TeX (или texi2roff
) для
создания печатной версии.
GDB включает уже отформатированную копию интерактивной версии Info
этого руководства в подкаталоге `gdb'. Основной файл Info---
`gdb-5.0/gdb/gdb.info', он ссылается на подчиненные файлы
`gdb.info*' в том же каталоге. В случае необходимости,
вы можете распечатать эти файлы, или прочитать их в любом редакторе; но
их легче прочитать, используя подсистему info
в GNU Emacs или
автономную программу info
, доступную как часть дистрибутива GNU
Texinfo.
Если вы хотите форматировать эти Info-файлы самостоятельно, вам
нужна одна из программ форматирования Info, например
texinfo-format-buffer
или makeinfo
.
Если у вас установлена программа makeinfo
, и вы находитесь на верхнем
уровне иерархии каталогов GDB (`gdb-5.0' в
случае версии 5.0), вы можете создать файл Info, набрав:
cd gdb make gdb.info
Если вы хотите сформировать и распечатать копии этого руководства, вам нужен TeX, программа печати его выходных DVI-файлов и файл определений Texinfo `texinfo.tex'.
TeX---это программа форматирования; она не печатает файлы непосредственно, а создает выходные файлы, называемые DVI-файлами. Чтобы напечатать сформатированный документ, вам нужна программа печати DVI-файлов. Если в вашей системе установлен TeX, в ней, возможно, есть такая программа. Какую точно команду нужно использовать зависит от вашей системы; lpr -d является общей; другая программа (для PostScript-устройств)---это dvips. Команда печати DVI-файлов может требовать имя файла без расширения или с расширением `.dvi'.
TeX также требует файл макроопределений `texinfo.tex'. Этот файл сообщает TeX, как форматировать документ, написанный в формате Texinfo. Сам по себе TeX не может читать или форматировать файл Texinfo. `texinfo.tex' распространяется с GDB и размещается в каталоге `gdb-номер-версии/texinfo'.
Если у вас установлены TeX и программа печати DVI, вы можете отформатировать и распечатать это руководство. Сначала перейдите в подкаталог `gdb' главного исходного каталога (например, в `gdb-5.0/gdb'), и наберите:
make gdb.dvi
Это передаст `gdb.dvi' вашей программе печати DVI.
GDB поставляется вместе со сценарием configure
, который
автоматизирует процесс подготовки GDB к установке; затем вы можете
использовать make
для построения программы gdb
.
(20)
Дистрибутив GDB включает весь исходный код, который вам понадобится для GDB, в одном каталоге, имя которого обычно составляется добавлением номера версии к `gdb'.
Например, дистрибутив GDB версии 5.0 находится в каталоге `gdb-5.0'. Этот каталог содержит:
gdb-5.0/configure (и файлы поддержки)
gdb-5.0/gdb
gdb-5.0/bfd
gdb-5.0/include
gdb-5.0/libiberty
gdb-5.0/opcodes
gdb-5.0/readline
gdb-5.0/glob
gdb-5.0/mmalloc
Простейший способ сконфигурировать и собрать GDB состоит в
выполнении configure
из исходного каталога
`gdb-номер-версии', который в этом примере есть
`gdb-5.0'.
Сперва перейдите в исходный каталог `gdb-номер-версии', если вы
еще не находитесь в нем; затем запустите configure
. Передайте в
качестве аргумента идентификатор платформы, на которой будет выполняться
GDB.
Например:
cd gdb-5.0 ./configure платформа make
где платформа---идентификатор, такой как `sun4' или
`decstation', задающий платформу, на которой будет выполняться
GDB. (Часто вы
можете опустить платформу; configure
пытается определить
корректное значение, изучая вашу систему.)
Выполнение `configure платформа' и затем make
строят
библиотеки `bfd', `readline', `mmalloc' и
`libiberty', и затем сам gdb
. Сконфигурированные исходные
файлы, а также двоичные файлы, остаются в соответствующих исходных каталогах.
configure
является сценарием оболочки Bourne (/bin/sh
); если
ваша система не распознает это автоматически, когда вы находитесь в
другой оболочке, вам может потребоваться выполнить sh
явно:
sh configure платформа
Если вы выполните configure
из каталога, содержащего исходные
каталоги для нескольких библиотек или программ, например
`gdb-5.0' для версии 5.0, configure
создает файлы конфигурации для всех подкаталогов низшего уровня (если вы не
велите ему не этого делать ключем `--norecursion').
Вы можете выполнить сценарий configure
из любого подкаталога из
поставки GDB, если вы хотите сконфигурировать только этот
подкаталог, но убедитесь, что указали путь к нему.
Например, для версии 5.0, чтобы сконфигурировать только подкаталог
bfd
, введите:
cd gdb-5.0/bfd ../configure платформа
Вы можете установить gdb
куда угодно; он не имеет никаких
жестко заданных путей. Однако, вы должны удостовериться, что ваша оболочка
(определяемая переменной среды `SHELL') доступна всем для чтения.
Помните, что GDB использует оболочку для запуска вашей программы---
некоторые системы не позволяют GDB отлаживать дочерние
процессы, чьи программы недоступны для чтения.
Если вы хотите запускать версии GDB на нескольких рабочих или
целевых машинах, вам нужны различные gdb
, скомпилированные для
каждой комбинации рабочей и целевой машины. configure
разработан
так, чтобы облегчить это, позволяя вам создавать каждую конфигурацию в
отдельном подкаталоге, а не в исходном каталоге. Если ваша программа
make
поддерживает возможности `VPATH' (GNU make
это делает), вызов make
в каждом из этих каталогов строит
программу gdb
, определенную там.
Чтобы построить gdb
в отдельном каталоге, запустите configure
с
ключем `--srcdir', для определения, где искать источник. (Вам также
нужно определить путь для поиска configure
из вашего рабочего каталога.
Если путь к configure
совпадает с параметром `--srcdir',
ключ `--srcdir' можно опустить; он подразумевается.)
Например, в версии 5.0, вы можете построить GDB в отдельном каталоге для Sun 4 так:
cd gdb-5.0 mkdir ../gdb-sun4 cd ../gdb-sun4 ../gdb-5.0/configure sun4 make
Когда configure
строит конфигурацию, используя удаленный
каталог с источниками, он создает дерево для двоичных файлов с той же
структурой (и используя те же имена), что и дерево каталогов с
исходными текстами. В этом примере, вы бы нашли библиотеку Sun 4
`libiberty.a' в каталоге `gdb-sun4/libiberty', и сам
GDB в `gdb-sun4/gdb'.
Одна из распространенных причин построения нескольких конфигураций
GDB в отдельных каталогах состоит в том, чтобы конфигурировать
GDB для кросс-компиляции (где GDB запускается на
одной машине---рабочей, в то время как отлаживаемые программы
выполняются на другой машине---целевой). Вы определяете целевую
машину кросс-отладки ключем configure
`--target=цель'.
Когда вы выполняете make
для построения программы или библиотеки,
вы должны выполнять ее из сконфигурированного каталога---того каталога,
из которого вы вызывали configure
(или из одного из его подкаталогов).
Makefile
, который создает configure
в каждом исходном
каталоге, также выполняется рекурсивно. Если вы ввели
make
в каталоге с исходными файлами, например в
`gdb-5.0' (или в каталоге, сконфигурированном отдельно
посредством `--srcdir=имя-каталога/gdb-5.0'),
вы построите все требуемые библиотеки, и затем GDB.
Когда у вас имеется несколько рабочих или целевых конфигураций в
отдельных каталогах, вы можете запустить make
для них параллельно
(например, если они смонтированы по NFS на каждой рабочей машине); они
не будут конфликтовать друг с другом.
Спецификации, использованные для рабочих и целевых машин в сценарии
configure
, именуются в соответствии со схемой наименования,
состоящей из трех частей, но поддерживаются также некоторые короткие
предопределенные синонимы. Полная схема наименования кодирует три
фрагмента информации по следующему образцу:
архитектура-производитель-ОС
Например, вы можете использовать синоним sun4
как параметр
платформа, или как значение цель в ключе
--target=цель
.
Эквивалентное полное имя---`sparc-sun-sunos4'.
Сценарий configure
, сопровождающий GDB, не предоставляет
никаких средств для запроса вывода всех поддерживаемых имен рабочих и
целевых машин или их сокращений. configure
вызывает скрипт
оболочки Bourne config.sub
для отображения сокращений в полные
имена; при желании, вы можете посмотреть сценарий или использовать его
для проверки ваших предположений о сокращениях. Например:
% sh config.sub i386-linux i386-pc-linux-gnu % sh config.sub alpha-linux alpha-unknown-linux-gnu % sh config.sub hp9k700 hppa1.1-hp-hpux % sh config.sub sun4 sparc-sun-sunos4.1.1 % sh config.sub sun3 m68k-sun-sunos4.1.1 % sh config.sub i986v Invalid configuration `i986v': machine `i986v' not recognized
config.sub
также распространяется в исходном каталоге
GDB (`gdb-5.0', для версии 5.0).
configure
Здесь приводится обзор ключей и параметров configure
, которые
наиболее часто используются для построения GDB.
configure
также имеет несколько других ключей, не представленных
здесь. See Info file `configure.info', node `What Configure Does', для полного
объяснения configure
.
configure [--help] [--prefix=каталог] [--exec-prefix=каталог] [--srcdir=имя-каталога] [--norecursion] [--rm] [--target=цель] платформа
Если хотите, можете вводить ключи с одним `-', а не с `--'; но вы можете сокращать имена ключей, если используете `--'.
--help
configure
.
--prefix=каталог
--exec-prefix=каталог
--srcdir=имя-каталога
make
или другой программы make
, реализующей возможности
VPATH
.configure
записывает файлы, относящиеся к конфигурации, в текущий
каталог, но принимает меры, чтобы можно было использовать источники в
каталоге имя-каталога. configure
создает каталоги внутри
рабочего каталога параллельно с исходными каталогами внутри имя-каталога.
--norecursion
configure
; не распространять конфигурацию на подкаталоги.
--target=цель
платформа ...
Существует также много других ключей, но обычно они требуются только для специальных целей.
Jump to: " - # - $ - - - . - / - : - @ - ^ - a - b - c - d - e - f - g - h - i - j - k - l - m - n - o - p - q - r - s - t - u - v - w - x - y - z - { - а - ц - д - ф - г - и - к - л - м - н - о - п - я - р - с - т - у - ж - в - з - ч - Ф - М - П - С
#
в Модуле-2
$
$$
$_
и info breakpoints
$_
и info line
$_
, $__
и история значений
--annotate
--async
--batch
--baud
--cd
--command
--core
--directory
--epoch
--exec
--fullname
--interpreter
--mapped
--noasync
--nowindows
--nx
--quiet
--readnow
--se
--silent
--statistics
--symbols
--tty
--version
--windows
--write
-b
-c
-d
-e
-f
-m
-n
-nw
-q
-r
-s
-t
-w
-x
.
, оператор области видимости Модулы-2
::
, контекст для переменных/функций
break
)
backtrace
)
продолжить
)
delete
)
disable
)
down
)
frame
)
g++
, компилятор GNU Си++
help
)
heuristic-fence-post
(Alpha, MIPS)
info
)
info frame
)
info stack
)
info list
)
next
)
nexti
)
quit
)
run
)
remotedebug
, протокол MIPS
retransmit-timeout
, протокол MIPS
step
)
stepi
)
target remote
timeout
, протокол MIPS
until
)
breakpoint
, удаленная
target remote
remotedebug
This document was generated on 2 April 2002 using texi2html 1.56k.