Цель---это среда выполнения, занятая вашей программой.
Часто 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, предоставляют возможность выполнения либо с порядком байтов big-endian, либо с little-endian. Обычно, выполняемый файл или символы содержат информацию для определения используемого порядка байтов, и вам не нужно об этом заботиться. Однако, иногда вам все же может пригодиться вручную изменить порядок байтов процессора, определенный 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 не выводит идент-последовательности.
Когда или рабочая, или целевая машина получает пакет, первым ожидаемым ответом является подтверждение: или `+' (для указания, что пакет получен корректно), или `-' (чтобы запросить повторную передачу):
<-$
данные-пакета#
контрольная-сумма ->+
Если полученный пакет включает идент-последовательности, то он добавляется к положительному подтверждению:
<-$
идент-последовательности:
данные-пакета#
контрольная-сумма ->+
идент-последовательности
Рабочая машина (GDB) посылает команды, а целевая (отладочная заглушка, включенная в вашу программу) посылает ответ. В случае команд пошагового выполнения и продолжения, ответ посылается только тогда, когда операция закончена (цель снова остановлена).
Данные-пакета состоят из последовательности знаков, за исключением `#' и `$' (для исключения, смотрите пакет `X'). `:' не может появляться третим символом в пакете. Поля внутри пакета должны разделяться при помощи `,' и `;' (к сожалению, некоторые пакеты использовали `:'). Если не оговорено противное, все числа представлены в шестнадцатеричном виде без начальных нулей.
Ответ данные может быть закодированным с помощью кодировки
переменной длины, чтобы
сохранить место. `*' означает, что следующий символ является
ASCII-кодом, который означает количетсво повторений символа,
предшествующего `*'. Кодировкой является n+29
, что дает печатный
знак для n >=3
(когда кодировка переменной длины дает
преимущества). Печатные знаки `$', `#', `+', `-',
или с номерами, большими 126, использоваться не должны.
Некоторые удаленные системы использовали другой механизм кодировки с переменной длиной, иногда называемый cisco-кодировкой. За `*' следуют две шестнадцатеричные цифры, обозначающие размер пакета.
Итак:
"0*
"
означает то же, что и "0000".
При ошибке ответ, возвращаемый для некоторых пакетов, включает двухсимвольный номер ошибки. Этот номер определен смутно.
Для любой команды, не поддерживаемой заглушкой, должен быть возвращен пустой ответ (`$#00'). Таким образом, протокол можно расширять. Новые версии GDB могут определить, поддерживается ли пакет, основываясь на ответе.
Вот полный список всех определенных на данный момент команд, и соответствующих им ответов данные:
Пакет | Запрос | Описание |
extended ops (необязательно) | !
| Использовать расширенный удаленный протокол. Имеет постоянное действие--требует установки только один раз. Расширенный удаленный протокол поддерживает пакеты `R'. |
reply `' | Заглушки, поддерживающие расширенный удаленный протокол, возвращают `', что, к сожалению, совпадает с ответом, возвращаемым заглушками, которые не поддерживают расширения протокола. | |
last signal | ?
| Указывает причину, по которой цель остановилась. Ответ такой же, как для пошагового выполнения и продолжения. |
reply | смотрите ниже | |
зарезервировано | a
| Зарезервировано для использования в будущем |
set program arguments (зарезервировано) (необязательно) | A длина-арг, число-арг, арг,...
| Инициализированный массив `argv[]' передается в программу. Длина-арг задает число байт в закодированном в шестнадцатеричный вид потоке байт арг. Смотрите `gdbserver' для дополнительной информации. |
reply OK
| ||
reply E NN
| ||
set baud (не рекомендовано) | b бод
| Изменить скорость последовательной линии в бод. |
set breakpoint (не рекомендовано) | B адрес,режим
| Установить (режим `S') или удалить (режим `C') точку останова по адресу адрес. Это было замещено пакетами `Z' и `z'. |
continue | c адрес
| адрес---это адрес для возобновления выполнения. Если адрес опущен, возобновить с текущего адреса. |
reply | смотрите ниже | |
продолжить с сигналом (необязательно) | C сиг; адрес
|
Продолжить с сигналом сиг (шестнадцатеричный номер сигнала). Если
; адрес опущено, выполнение возобновляется с прежнего
адреса.
|
reply | смотрите ниже | |
toggle debug (не рекомендовано) | d
| переключить флаг отладки. |
detach (необязательно) | D
| Отсоединить GDB от удаленной системы. Посылается удаленной системе перед тем, как GDB отсоединится. |
reply нет ответа | GDB не ждет никакого ответа после посылки этого пакета | |
зарезервировано | e
| Зарезервировано для использования в будущем |
зарезервировано | E
| Зарезервировано для использования в будущем |
зарезервировано | f
| Зарезервировано для использования в будущем |
зарезервировано | F
| Зарезервировано для использования в будущем |
read registers | g
| Чтение регистров общего назначения. |
reply XX... | Каждый байт данных регистра описывается двумя шестнадцатеричными цифрами. Они передаются с целевым порядком байтов. Размер каждого регистра и его позиция внутри пакета `g' определяются внутренними макросами GDB REGISTER_RAW_SIZE и REGISTER_NAME. Спецификация нескольких стандартных пакетов `g' приведена ниже. | |
E NN
| для ошибки. | |
write regs | G XX...
| Смотрите `g' для описания данных XX... . |
reply OK
| в случае успеха | |
reply E NN
| в случае ошибки | |
зарезервировано | h
| Зарезервировано для использования в будущем |
set thread (необязательно) | H ct...
| Установить нить для последующих операций (`m', `M', `g', `G', и другие). c = `c' для нитей, используемых при пошаговом выполнении и продолжении; t... может быть -1 для всех нитей. c = `g' для нитей, используемых в других операциях. Если ноль--выбрать любую нить. |
reply OK
| в случае успеха | |
reply E NN
| для ошибки | |
cycle step (черновик) (необязательно) | i адрес, nnn
|
Выполнить один тактовый цикл на удаленной машине. Если
, nnn указано, выполнить nnn циклов. Если
указан адрес, пошаговое выполнение по одному тактовому циклу
начинается этого адреса.
|
signal then cycle step (зарезервировано) (необязательно) | I
| Смотрите `i' и `S', там аналогичный синтаксис и семантика. |
зарезервировано | j
| Зарезервировано для использования в будущем |
зарезервировано | J
| Зарезервировано для использования в будущем |
kill request (необязательно) | k
| FIXME: Нет описания, как действовать в случае, если был выбран контекст определенной нити (то есть, `k' убивает только эту нить?). |
зарезервировано | l
| Зарезервировано для использования в будущем |
зарезервировано | L
| Зарезервировано для использования в будущем |
чтение памяти | m адрес, длина
| Прочитать длину байт памяти, начиная с адреса адрес. Ни GDB, ни заглушка не предполагают, что передача области памяти происходит по адресам, выровненным по границе слова. FIXME: Нужен механизм передачи области памяти, выровненной по границе слова. |
reply XX... | XX... представляет собой содержимое памяти. Может содержать меньше запрошенного числа байт, если удалось прочитать только часть данных. Ни GDB, ни заглушка не предполагают, что передача области памяти происходит по адресам, выровненным по границе слова. FIXME: Нужен механизм передачи области памяти, выровненной по границе слова. | |
reply E NN
| NN представляет номер ошибки | |
write mem | M адрес,длина: XX...
| Записать длину байт памяти, начиная с адреса адрес. XX...---это данные. |
reply OK
| при успехе | |
reply E NN
| при ошибке (это включает случай, когда была записана только часть данных). | |
зарезервировано | n
| Зарезервировано для использования в будущем |
зарезервировано | N
| Зарезервировано для использования в будущем |
зарезервировано | o
| Зарезервировано для использования в будущем |
зарезервировано | O
| Зарезервировано для использования в будущем |
read reg (зарезервировано) | p n...
| Смотрите write register. |
return r.... | Значение регистра в целевом порядке байт, закодированное в шестнадцатеричном виде. | |
write reg (необязательно) | P n...= r...
| Записать в регистр n... значение r..., которое содержит две шестнадцатеричные цифры для каждого байта в регистре (целевой порядок байтов). |
reply OK
| в случае успех | |
reply E NN
| при ошибке | |
general query (необязательно) | q запрос
| Запросить информацию о запросе. Вообще, запросы GDB имеют первую заглавную букву. Специальные запросы от производителей должны использовать приставку компании (из маленьких букв). Например: `qfsf.var'. За запросом может следовать необязательный список, разделенный `,' или `;'. Заглушки должны проверять, что они производят сравнение с полным именем запроса. |
reply XX...
| Данные от запроса, закодированные шестнадцатеричными цифрами. Ответ не может быть пустым. | |
reply E NN
| ответ при ошибке | |
reply `' | Указывает на нераспознанный запрос. | |
general set (необязательно) | Q перем= знач
| Установить значение перем в знач. Смотрите `q' для обсуждения соглашений, касающихся имен. |
reset (не рекомендовано) | r
| Установка всей системы в исходное состояние. |
remote restart (необязательно) | R XX
| Перезапустить удаленный сервер. XX, где оно требуется, не имеет ясного определения. FIXME: Нужен пример взаимодействия, объясняющий как эти пакеты используются в расширенном удаленном режиме. |
step (необязательно) | s адрес
| адрес---это адрес для возобновления выполнения. Если адрес опущен, возобновить выполнение с того же адреса. |
reply | смотрите ниже | |
step with signal (необязательно) | S сиг; адрес
|
Как C , но step это не continue.
|
reply | смотрите ниже | |
search (необязательно) | t адрес: PP, MM
| Поиск в обратном направлении, начиная с адреса адрес, до совпадения с шаблоном PP и маской MM. PP и MM---4 байта. Адрес должен быть не менее трех цифр. |
thread alive (необязательно) | T XX
| Определить, жива ли нить XX. |
reply OK
| нить все еще жива | |
reply E NN
| нить мертва | |
зарезервировано | u
| Зарезервировано для использования в будущем |
зарезервировано | U
| Зарезервировано для использования в будущем |
зарезервировано | v
| Зарезервировано для использования в будущем |
зарезервировано | V
| Зарезервировано для использования в будущем |
зарезервировано | w
| Зарезервировано для использования в будущем |
зарезервировано | W
| Зарезервировано для использования в будущем |
зарезервировано | x
| Зарезервировано для использования в будущем |
write mem (binary) (необязательно) | X адрес, длина:XX...
|
адрес это адрес, длина это число байт, XX... это
двоичные данные. Символы $ , # и 0x7d экранируются
при помощи 0x7d .
|
reply OK
| в случае успеха | |
reply E NN
| в случае ошибки | |
зарезервировано | y
| Зарезервировано для использования в будущем |
зарезервировано | Y
| Зарезервировано для использования в будущем |
remove break or watchpoint (черновик) (необязательно) | z t, адрес, длина
| Смотрите `Z'. |
insert break or watchpoint (черновик) (необязательно) | Z t, адрес, длина
| t представляет тип: `0'---программная точка останова, `1'---аппаратная точка останова, `2'---точка наблюдения за записью, `3'---точка наблюдения за чтением, `4'---точка наблюдения за доступом; адрес---это адрес; длина задается в байтах. Для программной точки останова, длина задает размер инструкции, на которую надо поместить заплату. Для аппаратных точек останова и точек наблюдения, длина указывает размер области памяти для наблюдения. Чтобы избежать потенциальных проблем с повторными пакетами, операции должны быть реализованы |
reply E NN
| в случае ошибки | |
reply 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; tttttttt; dddddddd; bbbbbbbb (устарело) |
AA = номер сигнала; tttttttt = адрес символа "_start"; dddddddd = база раздела данных; bbbbbbbb = база раздела bss. Примечание: используется только целями Cisco Systems. Разница между этим ответом и запросом "qOffsets" заключается в том, что пакет 'N' может прибыть самопроизвольно, тогда как запрос 'qOffsets' инициируется рабочим отладчиком. |
O XX... |
XX...---шестнадцатеричное представление ASCII-данных. Это может произойти в любой момент, пока программа выполняется и отладчик должен продолжать ждать 'W', 'T', и т.п. |
Следующие пакеты для установок и запросов уже были определены.
current thread | q C
| Возвратить идентификатор текущей нити. |
reply QC идент-проц
| Где идент-проц---16-битный идентификатор процесса, представленный шестнадцатеричнами цифрами. | |
reply * | Любой другой ответ подразумевает старый идентификатор процесса. | |
вычислить CRC блока памяти | q CRC: адрес, длина
| |
reply E NN
| Ошибка (например, ошибка доступа к памяти) | |
reply C CRC32
| Лишняя 32-битная циклическая проверка указанной области памяти. | |
query список или список-нитей (не рекомендовано) | q L нач-флагчисло-нитейслед-нить
| |
Получить информацию о нити от операционной системы, где происходит выполнение. Здесь: нач-флаг (одна шестнадцатеричная цифра) есть единица, что указывает на первый запрос, или ноль, что определяет последующий запрос; число-нитей (две шестнадцатеричные цифры)---максимальное число нитей, которое может содержать пакет ответа; и след-нить (восемь шестнадцатеричных цифр), для последующих запросов (нач-флаг равен нулю), возвращается в ответ как арг-нить. | ||
reply q M числоконецарг-нитьнить...
| ||
Здесь: число (две шестнадцатеричные цифры)---число возвращаемых
нитей; конец (одна шестнадцатеричная цифра), есть ноль, который
определяет, что есть еще нити, и единица, которая определяет, что
больше нитей нет; арг-нить (восемь шестнадцатеричных цифр)
представляет собой след-нить из пакета запроса;
нить...---это последовательность идентификаторов нитей от цели.
Идент-нити (восемь шестнадцатеричных цифр). Смотрите
remote.c:parse_threadlist_response() .
| ||
query sect offs | q Offsets
|
Получить смещения разделов, которые целевая машина использовала при
повторном размещении загруженного образа. Замечание: если
смещение Bss включено в ответ, GDB это игнорирует и
вместо этого применяет к разделу Bss смещение Data .
|
reply Text= xxx;Data= yyy;Bss= zzz
| ||
thread info request | q P режимидент-нити
| Возвращает информацию об идент-нити. Здесь: режим является 32-битным режимом в шестнадцатеричном представлении; идент-нити---64-битный идентификатор нити в шестнадцатеричном представлении. |
reply * |
Смотрите remote.c:remote_unpack_thread_info_response() .
| |
удаленная команда | q Rcmd, КОМАНДА
|
КОМАНДА (в шестнадцатеричном представлении) передается для
выполнения локальному интерпретатору. Неверные команды должны
сообщаться при помощи выходной строки. Перед конечным результирующим
пакетом, целевая машина может также ответить числом промежуточных
O ВЫВОД
Разработчики должны учесть, что предоставление доступа к
интерпретатору заглушки может иметь последствия, касающиеся безопасности.
|
reply OK
| Ответ на команду без вывода. | |
reply ВЫВОД | Ответ на команду со строкой вывода ВЫВОД, в шестнадцатеричном представлении. | |
reply 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...
<-+
Если у вас возникают проблемы с последовательным соединением, вы можете
использовать команду set remotedebug
. Это велит GDB
сообщать о всех пакетах, посылаемых назад и вперед по последовательному каналу
удаленной машине. Отладочная информация о пакетах печатается в
стандартный выходной поток GDB. set remotedebug off
выключает это, и show remotedebug
показывает вам текущее
состояние.
gdbserver
gdbserver
является управляющей программой для Unix-подобных
систем, которая позволяет вам установить соединение вашей программы с
удаленным GDB посредством target remote
, но без
компоновки с обычной отладочной заглушкой.
gdbserver
не является полной заменой отладочных заглушек, потому что
требует по существу тех же средств операционной системы, что и сам
GDB. Фактически, система, на которой может выполняться
gdbserver
для соединения с удаленным GDB, может также
выполнять GDB локально! Тем не менее, gdbserver
иногда
полезен, так как по размеру эта программа гораздо меньше, чем
GDB. gdbserver
также легче переносить, чем
весь GDB, так что вы сможете быстрее начать работать в новой системе,
используя gdbserver
. Наконец, если вы разрабатываете программы для
систем реального времени, вы можете обнаружить, что накладные расходы,
связанные с операциями реального времени, делают более удобным
проведение всей возможной разработки на другой системе, например, с помощью
кросс-компиляции. Вы можете использовать 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
).(5) Вы
должны использовать тот же номер порта с командой рабочего GDB
target remote
.
target remote
,
чтобы установить связь с gdbserver
. Ее параметры--либо
имя устройства (обычно последовательного устройства, такого как
`/dev/ttyb'), либо дескриптор порта TCP в форме
машина:порт
. Например:
(gdb) target remote /dev/ttybвзаимодействует с сервером через последовательную линию `/dev/ttyb', а
(gdb) target remote the-target:2345взаимодействует через TCP-соединение с портом 2345 на рабочей машине `цель'. Для 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
Дальнейшие подкоманды могут использоваться для запросов о конкретных объектах, информация о которых есть в ядре.
В настоящее время не существует другого способа определения, поддерживается та или иная операционная система, кроме как попробовать.