Отладка с помощью GDB - 13. Определение отладочной цели
[Содержание] [Назад] [Пред] [Вверх] [След] [Вперед]
Цель---это среда выполнения, занятая вашей программой.
Часто 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 тип параметры
-
Соединяет рабочую среду GDB с целевой машиной или процессом.
Целью обычно является протокол для взаимодействия со средствами отладки.
Параметр тип используется, чтобы определить тип или протокол
целевой машины.
Дальнейшие параметры интерпретируются целевым
протоколом, но обычно включают такие вещи, как имена
устройств или имена рабочих машин, с которыми осуществляется
связь, номера процессов и скорости в бодах.
Команда
target не повторяется при повторном нажатии RET после
ее выполнения.
help target
-
Отображает имена всех доступных целей. Чтобы отобразить выбранные в
данный момент цели, используйте либо
info target , либо info
files (см. раздел 12.1 Команды для задания файлов).
help target имя
-
Описывает определенную цель, включая любые параметры, необходимые для ее
выбора.
set gnutarget арг
-
GDB использует свою собственную библиотеку BFD@transnote{от
`Binary File Descriptor'. Это библиотека описания двоичных файлов.} для чтения ваших
файлов. GDB знает, читает ли он выполняемый файл,
файл дампа памяти или объектный (.o) файл; однако вы можете
определить формат файла командой
set gnutarget . В отличие от
большинства команд target , с gnutarget , команда target
относится к программе, а не к машине.
Предупреждение: Для определения формата файла посредством set
gnutarget , вы должны знать фактическое имя BFD.
См. раздел 12.1 Команды для задания файлов.
show gnutarget
-
Используйте команду
show gnutarget для отображения, какого
формата файлы gnutarget установлен считывать. Если вы не
установили gnutarget , GDB определит формат для каждого файла
автоматически, и show gnutarget выведет `The current BFD target
is "auto"'.
Ниже приведены некоторые наиболее распространенные цели (доступные или нет, в
зависимоси от конфигурации GDB):
target exec программа
-
Выполняемый файл. `target exec программа' то же самое, что и
`exec-file программа'.
target core имя-файла
-
Файл дампа памяти. `target core имя-файла' то же самое, что и
`core-file имя-файла'.
target remote устр
-
Удаленная последовательная цель является уникальным для GDB
протоколом. Параметр устр определяет, какое последовательное
устройство использовать для соединения (например, `/dev/ttya').
См. раздел 13.4 Удаленная отладка.
target remote
поддерживает команду load . Это полезно, только если вы можете
получить заглушку для целевой системы каким-нибудь другим
способом и можете разместить ее в памяти, где она не будет
затерта загрузкой.
target sim
-
Встроенный эмулятор ЦП. GDB включает эмуляторы для большинства
архитектур. Вообще,
target sim
load
run
работает; однако, вы не можете предположить, что доступны определенное
отображение памяти, драйверы устройств, или даже основные функции
ввода-вывода, хотя некоторые эмуляторы действительно предоставляют это. Для
информации о деталях эмуляторов для конкретного процессора, смотрите
соответствующий раздел 14.3 Встроенные процессоры.
Некоторые конфигурации могут также включать такие цели:
target nrom устр
-
Эмулятор NetROM ROM. Эта цель поддерживает только загрузку.
Для различных конфигураций GDB доступны различные цели; ваша
конфигурация может иметь больше или меньше целей.
Многие удаленные цели требуют, чтобы вы загрузили код выполняемого
файла, после того как вы успешно установили соединение.
load имя-файла
-
В зависимости от того, какие возможности удаленной отладки
сконфигурированы в GDB, может быть доступна команда
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
-
Велит GDB считать, что целевой порядок байтов big-endian.
set endian little
-
Велит GDB считать, что целевой порядок байтов little-endian.
set endian auto
-
Велит GDB использовать порядок байтов, указанный в выполняемом
файле.
show endian
-
Отображает текущую установку GDB для целевого порядка байтов.
Заметьте, что эти команды управляют только интерпретацией символьных
данных в рабочей системе, и они совершенно не оказывают действия на
целевую систему.
Если вы пытаетесь отлаживать программу, выполняющуюся на машине,
которая не может запустить GDB обычным способом, часто бывает полезна
удаленная отладка. Например, вы можете использовать удаленную
отладку для ядра операционной системы или для малой системы, которая не
имеет достаточно мощной операционной системы общего назначения для
запуска отладчика со всеми возможностями.
Некоторые конфигурации GDB имеют специальный последовательный или
TCP/IP интерфейсы для того, чтобы это работало с конкретными отладочными
целями. Кроме того, GDB распространяется с общим
последовательным протоколом (уникальным для GDB, но не для
конкретной целевой системы), который вы можете использовать, если пишете
удаленные заглушки--код, выполняемый в удаленной системе для связи с
GDB.
В вашей конфигурации GDB могут быть доступны другие удаленные
цели; используете help target , чтобы их перечислить.
Для отладки программы, выполняемой на другой машине (отладочной
целевой машине), вы сперва должны создать все обычные
предпосылки для самостоятельного выполнения программы. Например, для
программы на Си вам нужны:
-
Процедура запуска для установки среды выполнения Си; она обычно
имеет имя типа `crt0'. Процедура запуска может быть
обеспечена вашими аппаратными средствами, или вы должны
написать свою собственную.
-
Библиотека подпрограмм Си для поддержки вызовов подпрограмм вашей
программы, особенно для управления вводом и выводом.
-
Способ установки вашей программы на другую машину--например,
программа загрузки. Такие программы часто предоставляются поставщиками
аппаратных средств, но вам может потребоваться написать вашу
собственную, пользуясь документацией к аппаратному обеспечению.
Следующим шагом будет принятие мер по использованию вашей
программой последовательного порта для связи с машиной, где
выполняется GDB (рабочей машиной). В общих чертах, схема
выглядит следующим образом:
- На рабочей машине
-
GDB уже понимает, как использовать этот протокол; после установки
всего остального, вы можете просто использовать
команду `target remote' (см. раздел 13. Определение отладочной цели).
- На целевой машине
-
вы должны скомпоновать вместе с вашей программой несколько подпрограмм
специального назначения, которые реализуют удаленный последовательный
протокол GDB. Файл, содержащий эти подпрограммы, называется
отладочной заглушкой.
На некоторых удаленных целях, вы можете использовать вспомогательную
программу
gdbserver вместо компоновки заглушки вместе с вашей
программой. См. раздел 13.4.1.5 Использование программы gdbserver ,
для детального изучения.
Отладочная заглушка специфична для архитектуры удаленной машины;
например, используйте `sparc-stub.c' для отладки программ на
машинах SPARC.
Следующие работающие удаленные заглушки распространяются вместе с GDB:
i386-stub.c
-
Для Intel 386 и совместимых архитектур.
m68k-stub.c
-
Для архитектур Motorola 680x0.
sh-stub.c
-
Для архитектур Hitachi SH.
sparc-stub.c
-
Для архитектур SPARC.
sparcl-stub.c
-
Для архитектур Fujitsu SPACRLITE.
Файл `README' в поставке GDB может содержать другие
недавно добавленные заглушки.
Отладочная заглушка для вашей архитектуры содержит следующие
три подпрограммы:
set_debug_traps
-
Когда ваша программа останавливается, эта подпрограмма организует
выполнение
handle_exception . Вы должны явно вызвать эту
подпрограмму в начале вашей программы.
handle_exception
-
Это главная рабочая лошадка, но ваша программа никогда не вызывает ее
явно--установочный код организует запуск
handle_exception , когда
вызывается ловушка.
handle_exception получает управление, когда ваша программа
останавливается во время выполнения (например, в точке останова), и
организует связь с GDB на рабочей машине. Именно здесь
реализуется протокол связи; handle_exception действует как
представитель GDB на целевой машине. Сперва она посылает
суммарную информацию о состоянии вашей программы, затем продолжает
выполняться, извлекая и передавая любую информацию, требующуюся
GDB, пока вы не выполните команду GDB, возобновляющую
выполнение вашей программы; в этом месте handle_exception
возвращает управление вашему коду на целевой машине.
breakpoint
-
Используйте эту вспомогательную подпрограмму для установки в вашей
программе точек останова. В зависимости от конкретной ситуации, это
может быть единственным способом для GDB получить управление.
Например, если ваша целевая машина имеет некую клавишу прерывания, вам
не нужно вызывать эту подпрограмму; нажатие клавиши прерывания передаст
управление
handle_exception ---в действительности, GDB.
На некоторых машинах простое получение символов на последовательный порт
может также вызвать ловушку; опять, в этой ситуации вам не нужно вызывать
breakpoint из вашей программы--простое выполнение `target
remote' из рабочего сеанса GDB передаст управление.
Вызывайте breakpoint , если ни одно из этих предположений не верно,
или вы просто хотите быть уверенным, что ваша программа остановится в
предопределенной точке от начала вашего сеанса отладки.
Отладочные заглушки, поставляемые с GDB, ориентированы на
микропроцессоры определенной архитектуры, но они не имеют информации
об остальной части вашей целевой отладочной машины.
В первую очередь, вам нужно сообщить заглушке, как связаться с
последовательным портом.
int getDebugChar()
-
Напишите эту подпрограмму для чтения одного символа из
последовательного порта. Она может быть идентична
getchar для
вашей целевой системы; разные имена используются, чтобы позволить
вам их различать, если вы хотите.
void putDebugChar(int)
-
Напишите эту подпрограмму для записи одного символа в
последовательный порт. Она может быть идентична
putchar для
вашей целевой системы; разные имена используются, чтобы позволить
вам их различать, если вы хотите.
Если вы хотите, чтобы GDB мог остановить вашу программу во
время ее выполнения, вам нужно использовать управляемый прерываниями
последовательный драйвер и настроить его для остановки при получении
^C (` 03', символ control-C). Это тот символ, который
GDB использует для указания удаленной системе остановиться.
Указание отладочной цели вернуть GDB правильный статус,
вероятно, требует изменений стандартной заглушки; один быстрый и
неаккуратный способ состоит в выполнении лишь инструкции точки останова
("неаккуратная" часть состоит в том, что GDB выдает
SIGTRAP вместо SIGINT ).
Вот другие процедуры, которые вы должны обеспечить:
void exceptionHandler (int номер-исключения, void *адрес-исключения)
-
Напишите эту функцию для установки адреса-исключения в таблицы
обработки исключительных ситуаций. Вам нужно сделать это, потому
что у заглушки нет способа узнать, как устроены таблицы обработки
исключений в вашей целевой системе (например, процессорная
таблица может быть в ПЗУ, и содержать элементы, указывающие на
таблицу в ОЗУ). Номер-исключения---это номер исключительной
ситуации, которая должна быть изменена; его значение зависит от
архитектуры (например, различные номера могут представлять
деление на ноль, доступ с нарушением выравнивания, и так далее). Когда
это исключение возникает, управление должно быть передано
непосредственно адресу-исключения, и процессорное
состояние (стек, регистры и так далее) должно быть таким же, как
во время возникновения процессорного исключения. Так что если вы хотите
использовать инструкцию перехода для достижения адреса-исключения,
это должен быть простой переход, не переход к подпрограмме.
Для 386, адрес-исключения должен быть установлен как обработчик
прерывания, чтобы во время его выполнения остальные прерывания маскировались.
Он должен иметь уровень полномочий 0 (наибольшие полномочия). Заглушки
SPARC и 68k могут маскировать прерывания самостоятельно без помощи
exceptionHandler .
void flush_i_cache()
-
Только для SPARC и SPARCLITE. Напишите эту попрограмму для
очистки кеша инструкций, если он есть, на вашей целевой машине.
Если кеша инструкций нет, эта подпрограмма может ничего не делать.
На целевых машинах, имеющих кеш инструкций, GDB требует эту
функцию, чтобы удостовериться, что состояние вашей программы
стабильное.
Вы должны также удостовериться, что эта библиотечная процедура доступна:
void *memset(void *, int, int)
-
Это стандартная библиотечная функция
memset , которая
устанавливает область памяти в заданное значение. Если вы имеете
одну из свободных версий libc.a , memset может быть найдена
там; иначе вы должны или получить ее от изготовителя аппаратного
обеспечения, или написать свою собственную.
Если вы не используете компилятор GNU Си, вам также могут
понадобиться другие стандартные библиотечные подпрограммы; это
меняется от одной заглушки к другой, но в общем, заглушки
часто используют различные общие библиотечные подпрограммы, которые
gcc генерирует как встроенный код.
Вкратце, когда ваша программа готова к отладке, вы должны проделать
следующие шаги.
-
Убедитесь, что вы имеете поддерживающие процедуры низкого уровня
(см. раздел 13.4.1.2 Что вы должны сделать для заглушки):
getDebugChar , putDebugChar ,
flush_i_cache , memset , exceptionHandler .
-
Вставьте следующие строки вначале вашей программы:
set_debug_traps();
breakpoint();
-
Только для заглушки 680x0, вы должны предоставить переменную
exceptionHook . Обычно вы используете просто:
void (*exceptionHook)() = 0;
если до вызова set_debug_traps , вы установили ее для
указания на функцию в вашей программе; эта функция вызывается, когда
GDB продолжает выполнение после останова на ловушке (например,
ошибка шины).
Функция, указанная exceptionHook , вызывается с одним
параметром типа int , который является номером исключения.
-
Откомпилируйте и скомпонуйте вместе: вашу программу, отладочную
заглушку GDB для вашей целевой архитектуры и
подпрограммы поддержки.
-
Убедитесь, что что у вас есть последовательное соединение между вашей целевой
и рабочей машинами GDB, и идентифицируйте последовательный порт на
рабочей машине.
-
Загрузите вашу программу на целевую машину (или поместите ее туда
любыми средствами, предоставляемыми производителем) и запустите ее.
-
Для начала удаленной отладки, запустите GDB на рабочей машине
и укажите в качестве выполняемого файла программу, которая выполняется
на удаленной машине. Это сообщает GDB, как найти символы и
содержание неизменяемых областей вашей программы.
-
Установите связь, используя команду
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 является управляющей программой для 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 .
- На рабочей машине GDB
-
вам нужна копия вашей программы с символьными данными, так как
GDB нужна информация о символах и отладочная информация.
Запустите GDB как обычно, используя имя локальной копии вашей
программы в качестве первого аргумента. (Вам также может понадобиться
ключ `--baud', если последовательная линия работает на скорости,
отличной от 9600бит/сек.) После этого, используйте
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 ---это управляющая программа для систем 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
- На рабочей машине GDB
-
вам нужна копия вашей программы с символьными данными, так как
GDB требуется символьная и отладочная информация. Запустите
GDB как обычно, используя имя локальной копии вашей программы в
качестве первого параметра. (Вам также может понадобиться ключ
`--baud', если последовательная линия работает на скорости,
отличной от 9600бит/сек.) После этого, используйте
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
Дальнейшие подкоманды могут использоваться для запросов о конкретных
объектах, информация о которых есть в ядре.
В настоящее время не существует другого способа определения,
поддерживается та или иная операционная система, кроме как попробовать.
[Содержание] [Назад] [Пред] [Вверх] [След] [Вперед]
|