Цель -- это среда выполнения, занятая вашей программой.
Часто GDB выполняется в той же рабочей среде, что и ваша
программа; в этом случае отладочная цель задается неявно в момент
использования команд file
или core
. Когда вам нужна
большая гибкость -- например, выполнение GDB на другой машине, или
управление автономной системой через последовательный порт или системой
реального времени через соединение TCP/IP -- вы можете использовать
команду target
для определения цели одного из типов,
сконфигурированных для GDB (см. раздел 13.2 Команды для управления целями).
Существует три класса целей: процессы, файлы дампов памяти и выполняемые файлы. GDB может обрабатывать одновременно до трех активных целей, по одной в каждом классе. Это позволяет вам (например) запустить процесс и проверять его действия, не прерывая вашу работу над файлом дампа.
Например, если вы выполняете `gdb a.out', то исполняемый файл
a.out
является единственной активной целью. Если вы назначите также
файл дампа -- возможно, от предыдущего выполнения, завершившегося ошибкой
и создавшего дамп, ---
тогда GDB имеет две активные цели и использует их вместе,
просматривая сначала файл дампа, а затем исполняемый файл, для выполнения
запросов к адресам памяти. (Обычно эти два класса целей дополняют друг
друга, так как файлы дампа памяти содержат только память программы,
доступную для чтения и записи
(переменные и тому подобное), и машинное состояние, в то время как исполняемые
файлы содержат только текст программы и инициализированные данные.)
Когда вы вводите run
, ваш исполняемый файл становится также активным
целевым процессом. Когда целевой процесс активен, все команды GDB,
запрашивающие адреса памяти, относятся к этой цели; адреса в активной
цели файла дампа или выполняемого файла неизвестны, пока активен
целевой процесс.
Используйте команды core-file
и exec-file
для выбора новой
цели файла дампа памяти или выполняемого файла (см. раздел 12.1 Команды для задания файлов). Для определения в качестве цели
процесса, который уже выполняется, используйте команду attach
(см. раздел 4.7 Отладка запущенного ранее процесса).
target тип параметры
target
не повторяется при повторном нажатии RET после
ее выполнения.
help target
info target
, либо info
files
(см. раздел 12.1 Команды для задания файлов).
help target имя
set gnutarget арг
set gnutarget
. В отличие от
большинства команд target
, в команде gnutarget
слово target
относится к программе, а не к машине.
См. раздел 12.1 Команды для задания файлов.Предупреждение: Для определения формата файла посредством
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работает; однако, вы не можете предполагать, что доступны какое-то отображение памяти, драйверы устройств или даже элементарные функции ввода-вывода, хотя некоторые эмуляторы действительно предоставляют это. Для информации о деталях эмуляторов для конкретного процессора, смотрите соответствующий раздел 14.3 Встроенные процессоры.
Некоторые конфигурации могут также включать такие цели:
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
вместо компоновки заглушки вместе с вашей
программой. См. раздел 13.4.1.5 Использование программы 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
Дальнейшие подкоманды могут использоваться для запросов о конкретных объектах, информация о которых есть в ядре.
В настоящее время не существует другого способа определить, поддерживается та или иная операционная система, кроме как попробовать.