Прежде чем выполнять программу под управлением GDB, при компиляции вы должны сгенерировать отладочную информацию.
Вы можете запустить GDB с параметрами или без, в любой среде по вашему выбору. Если вы отлаживаете программу на той же машине, на которой выполняется GDB, вы можете перенаправлять ввод и вывод вашей программы, отлаживать уже выполняющийся процесс или убить дочерний процесс.
Для эффективной отладки программы, при компиляции вы должны сгенерировать отладочную информацию. Эта отладочная информация сохраняется в объектном файле; она описывает тип данных каждой переменной или функции и соответствие между номерами строк исходного текста и адресами в выполняемом коде.
Чтобы запросить генерацию отладочной информации, укажите ключ `-g' при вызове компилятора.
Многие компиляторы Си не могут обрабатывать ключи `-g' и `-O' вместе. Используя такие компиляторы, вы не можете создавать оптимизированные выполняемые файлы, содержащие отладочную информацию.
GCC, GNU компилятор Си, поддерживает `-g' вместе с ключом `-O' или без него, что делает возможной отладку оптимизированного кода. Мы рекомендуем вам всегда использовать `-g' при компиляции программ. Вы можете думать, что ваша программа правильная, но нет никакого смысла испытывать удачу.
Когда вы отлаживаете программу, откомпилированную с `-g -O', помните, что оптимизатор перестраивает ваш код; отладчик же показывает то, что там находится в действительности. Не удивляйтесь, если порядок выполнения не будет в точности соответствовать вашему исходному файлу! Крайний пример: если вы определяете переменную, но нигде ее не используете, GDB никогда не увидит этой переменной, потому что при оптимизации компилятор ее исключит.
Некоторые вещи не работают с `-g -O' так же хорошо, как с одним `-g', в частности, на машинах с планированием инструкций. Если сомневаетесь, перекомпилируйте с одним ключом `-g', и если это устранит проблему, пожалуйста, сообщите нам об этом как об ошибке (включите тестовый пример!).
Ранние версии компилятора GNU Си допускали вариант ключа для отладочной информации `-gg'. GDB больше не поддерживает этот формат; если этот ключ есть у вашего компилятора GNU Си, не используйте его.
run
r
run
для запуска вашей программы под
управлением GDB. Сначала вы должны задать имя программы (кроме
как на VxWorks) с параметрами GDB (см. раздел 2. Вход и выход из GDB), или используя команды file
или exec-file
(см. раздел 12.1 Команды для задания файлов).
Если вы запускаете вашу программу в среде выполнения, поддерживающей
процессы, run
создает подчиненный процесс, и этот процесс
выполняет вашу программу. (В средах, не поддерживающих процессы,
run
выполняет переход на начало вашей программы.)
Выполнение программы зависит от определенной информации, которую она получает от породившего ее процесса. GDB предоставляет способы задать эту информацию, что вы должны сделать до запуска программы. (Вы можете изменить ее после старта, но такие изменения воздействуют на вашу программу только при следующем запуске.) Эта информация может быть разделена на четыре категории:
run
. Если на вашей системе доступна оболочка, она
используется для передачи параметров, так что при их описании вы можете
использовать обычные соглашения (такие как раскрывание шаблонов или
подстановка переменных).
В системах Unix, вы можете контролировать, какая оболочка используется, с
помощью переменной среды SHELL
.
См. раздел 4.3 Аргументы вашей программы.
set environment
и
unset environment
, чтобы изменить часть настроек среды, влияющих
на нее. См. раздел 4.4 Рабочая среда вашей программы.
cd
.
См. раздел 4.5 Рабочий каталог вашей программы.
run
или использовать команду tty
,
чтобы установить другое устройство для вашей программы.
См. раздел 4.6 Ввод и вывод вашей программы.
Предупреждение: Хотя перенаправление ввода и вывода работает, вы
не можете использовать каналы для передачи выходных данных отлаживаемой
программы другой программе; если вы попытаетесь это сделать, скорее
всего GDB перейдет к отладке не той программы.
Когда вы подаете команду run
, ваша программа начинает выполняться
немедленно. См. раздел 5. Остановка и продолжение исполнения, для обсуждения
того, как остановить вашу программу. Как только программа
остановилась, вы можете вызывать функции вашей программы, используя
команды print
или call
. См. раздел 8. Исследование данных.
Если время модификации символьного файла изменилось с того момента, когда GDB последний раз считывал символы, он уничтожает свою символьную таблицу и считывает ее заново. При этом GDB старается сохранить ваши текущие точки останова.
Аргументы к вашей программе могут быть заданы как аргументы к команде
run
.
Они передаются оболочке, которая раскрывает символы шаблонов и выполняет
перенаправление ввода-вывода, и с того момента попадают в вашу
программу. Переменная среды SHELL
(если она существует)
определяет, какую оболочку использует GDB. Если вы не
определите SHELL
, он использует оболочку по умолчанию
(`/bin/sh' в Unix).
В не-Unix-системах, программу обычно запускает непосредственно GDB, который эмулирует перенаправление ввода-вывода через соответствующие системные вызовы, и символы шаблонов раскрываются кодом запуска, а не оболочкой.
run
без аргументов использует те же аргументы, которые
использовались предыдущей командой run
, или которые установлены
командой set args
.
set args
set args
нет аргументов, run
выполняет вашу программу без аргументов. Если вы запустили
программу с аргументами, то единственный способ запустить ее
снова без аргументов -- это использовать set args
до следующего
запуска командой run
.
show args
Среда состоит из набора переменных среды и их значений. Переменные среды обычно хранят такие данные, как ваше имя пользователя, домашний каталог, тип терминала и путь поиска для запуска программ. Как правило, вы устанавливаете переменные среды с помощью оболочки, и они наследуются всеми другими программами, которые вы вызываете. При отладке может оказаться полезным попробовать запустить программу в измененной среде, не перезапуская GDB.
path каталог
PATH
(пути
поиска выполняемых файлов), как для GDB, так и для вашей
программы. Вы можете указать названия нескольких каталогов, разделив их
пробелом или системно-зависимым разделителем (`:' в Unix, `;'
в MS-DOS и MS-Windows). Если каталог уже находится в списке путей,
он переносится в начало, так что поиск в нем будет производиться
раньше.
Вы можете использовать строку `cwd', чтобы сослаться на
рабочий каталог, который является текущим в тот момент, когда
GDB производит поиск. Если вместо этого вы используете
`.', то она будет указывать на тот каталог, в котором вы
выполнили команду path
. GDB заменяет `.' в
аргументе каталог (на текущий путь) до добавления каталога к
списку путей поиска.
show paths
PATH
).
show environment [имя-перем]
environment
как env
.
set environment имя-перем [=значение]
set env USER = fooговорит отлаживаемой программе, что при последующих запусках именем пользователя является `foo'. (Пробелы, окружающие `=', использованы здесь для ясности; в действительности, они не обязательны.)
unset environment имя-перем
unset environment
удаляет переменную из среды, а не присваивает
ей пустое значение.
Предупреждение: В системах Unix, GDB вызывает вашу
программу, используя оболочку, указанную вашей переменной среды
SHELL
, если она определена (или /bin/sh
, если не
определена). Если переменная SHELL
указывает на оболочку,
которая выполняет файл инициализации -- такой как `.cshrc' для
оболочки C-shell, или `.bashrc' для BASH -- любая переменная, которую вы
установите в этом файле, воздействует на вашу программу. В этой
связи, вы можете захотеть перенести установку переменных среды в
файлы, которые выполняются только при входе в систему, такие как
`.login' или `.profile'.
Каждый раз, когда вы запускаете свою программу командой run
, она
наследует рабочий каталог от текущего рабочего каталога
GDB. В начальный момент, рабочий каталог GDB
наследуется от его родительского процесса (обычно оболочки), но вы
можете задать новый рабочий каталог командой cd
из GDB.
Рабочий каталог GDB также служит каталогом по умолчанию для команд отладчика, определяющих действия с файлами. См. раздел 12.1 Команды для задания файлов.
cd каталог
pwd
По умолчанию, программа, которую вы запускаете под управлением GDB, осуществляет ввод и вывод на тот же терминал, что и GDB. Для взаимодействия с вами, GDB переключает терминал в свой собственный терминальный режим, но он записывает терминальные режимы, которые использовала ваша программа, и переключается назад к ним, когда вы продолжаете выполнение программы.
info terminal
Вы можете перенаправить ввод и/или вывод вашей программы, используя
перенаправление оболочки с помощью команды run
. Например,
run > выходной-файл
запускает вашу программу, перенаправляя ее вывод в `выходной-файл'.
Другой способ задать, как ваша программа должна осуществлять ввод и
вывод, -- использовать команду tty
. Эта команда принимает в
качестве аргумента имя файла, который будет использоваться по умолчанию
для будущих команд run
. Она также сбрасывает управляющий
терминал для дочернего процесса для будущих команд run
.
Например,
tty /dev/ttyb
указывает, что процессы, запущенные последующими командами run
,
для ввода и вывода используют по умолчанию терминал `/dev/ttyb', и
что он будет их управляющим терминалом.
Явное перенаправление в run
замещает эффект команды tty
для устройств ввода-вывода, но не ее воздействие на управляющий терминал.
Когда вы используете команду tty
или перенаправляете ввод в
команде run
, изменяется только ввод для вашей программы.
Ввод для GDB по прежнему происходит через ваш терминал.
attach идент-процесса
info files
показывает ваши
активные цели.) В качестве аргумента эта команда получает идентификатор
процесса. Обычный способ узнать идентификатор
Unix-процесса -- воспользоваться утилитой ps
или командой оболочки
`jobs -l'.
attach
не повторяется, если вы нажмете RET второй раз
после выполнения команды.
Чтобы использовать attach
, ваша программа должна выполняться в
среде, поддерживающей процессы; например, attach
не работает на
специальных машинах, не имеющих операционной системы. Вы также должны
обладать полномочиями для посылки сигнала процессу.
Когда вы используете attach
, отладчик находит программу
выполняющегося процесса, производя поиск сперва в текущем рабочем
каталоге, а затем (если программа не найдена), используя пути поиска
исходных файлов (см. раздел 7.3 Определение каталогов с исходными файлами). Также, для загрузки программы вы можете
использовать команду file
. См. раздел 12.1 Команды для задания файлов.
Первое, что GDB делает после подготовки указанного процесса к
отладке -- останавливает его. Вы можете исследовать и изменять
присоединенный процесс всеми командами GDB, которые обычно
доступны, когда вы запускаете процессы с помощью run
. Вы можете
устанавливать точки останова; вы можете пошагово выполнять программу и
продолжить ее обычное выполнение, вы можете изменять области данных.
Если вы решите продолжить выполнение процесса после присоединения к нему
GDB, вы можете использовать команду continue
.
detach
detach
. Отсоединение процесса продолжает его
выполнение. После команды detach
, этот процесс и
GDB снова становятся совершенно независимыми, и вы готовы
присоединить или запустить с помощью run
другой процесс.
detach
не повторяется, если вы нажмете RET еще раз.
Если вы выйдете из GDB или используете команду run
, пока
у вас есть присоединенный процесс, вы убьете этот процесс. По
умолчанию, GDB запрашивает подтверждение, если вы пытаетесь
сделать одну из этих вещей; вы можете контролировать, нужно вам это
подтверждение или нет, используя команду set confirm
(см. раздел 15.6 Необязательные предупреждения и сообщения).
kill
Эта команда полезна, если вы хотите отладить дамп памяти, а не выполняющийся процесс. GDB игнорирует любые дампы памяти, пока ваша программа выполняется.
В некоторых операционных системах программа не может быть выполнена вне
GDB, пока в ней есть точки останова, установленные
отладчиком. В этой ситуации вы можете использовать команду
kill
, чтобы разрешить выполнение вашей программы вне отладчика.
Команда kill
также полезна, если вы хотите перекомпилировать и
перекомпоновать вашу программу, так как во многих системах невозможно
модифицировать исполняемый файл во время выполнения процесса. В этом
случае, когда вы в следующий раз введете run
, GDB
заметит, что файл изменился, и заново прочитает символьную таблицу
(стараясь при этом сохранить ваши точки останова).
В некоторых операционных системах, таких как HP-UX и Solaris, одна программа может иметь несколько нитей выполнения. Точная семантика нитей меняется от одной операционной системы к другой, но в общем, нити одной программы сродни нескольким процессам -- за исключением того, что они разделяют одно адресное пространство (то есть, все они могут исследовать и модифицировать одни и те же переменные). С другой стороны, каждая нить имеет свои собственные регистры и стек выполнения, и, возможно, свои собственные участки памяти.
GDB предоставляет следующие возможности для отладки многонитевых программ:
Предупреждение: Пока эти возможности доступны не в любой конфигурации GDB, где операционная система поддерживает нити. Если ваш GDB не поддерживает нити, эти команды не имеют эффекта. Например, в системах без поддержки нитей GDB ничего не выводит на команду `info threads' и всегда отвергает команду
thread
, как в этом примере:(gdb) info threads (gdb) thread 1 Thread ID 1 not known. Use the "info threads" command to see the IDs of currently known threads.(5)
Возможности GDB для отладки нитей позволяют вам наблюдать все нити во время выполнения вашей программы, но когда управление переходит к GDB, одна конкретная нить выделяется для отладки. Она называется текущей нитью. Отладочные команды показывают информацию о программе с точки зрения текущей нити.
Когда GDB обнаруживает новую нить в вашей программе, он выводит для нее идентификатор на целевой системе с сообщением в форме `[New сист-тег]'. Сист-тег является идентификатором нити, чья форма различается в зависимости от конкретной системы. Например, в LynxOS вы можете увидеть
[New process 35 thread 27]
когда GDB замечает новую нить. Напротив, в системе SGI, сист-тег выглядит просто как `process 368', без дополнительных спецификаций.
Для отладочных целей, GDB присваивает свои собственные номера нитей -- всегда в виде одного целого числа -- каждой нити в вашей программе.
info threads
(gdb) info threads 3 process 35 thread 27 0x34e5 in sigpause () 2 process 35 thread 23 0x34e5 in sigpause () * 1 process 35 thread 13 main (argc=1, argv=0x7ffffff8) at threadtest.c:68
В системах HP-UX:
Для отладочных целей, GDB присваивает свои собственные номера нитей -- небольшие целые, присваиваемые в порядке создания нитей --- каждой нити в вашей программе.
Когда GDB обнаруживает новую нить в вашей программе, он выводит как номер нити, присвоенный GDB, так и идентификатор на целевой системе для нити с сообщением в форме `[New сист-тег]'. сист-тег является идентификатором нити, чья форма различается в зависимости от конкретной системы. Например, в HP-UX, когда GDB замечает новую нить, вы увидите
[New thread 2 (system thread 26594)]
info threads
(gdb) info threads * 3 system thread 26607 worker (wptr=0x7b09c318 "@") \
at quicksort.c:137 2 system thread 26606 0x7b0030d8 in __ksleep () \
from /usr/lib/libc.2 1 system thread 27905 0x7b003498 in _brk () \
from /usr/lib/libc.2
thread номер-нити
(gdb) thread 2 [Switching to process 35 thread 23] 0x34e5 in sigpause ()Также как и с сообщением `[New ...]', форма текста после `Switching to' зависит от соглашений для идентификации нитей в вашей системе.
threads apply [номер-нити] [all] арг
thread apply
позволяет вам применить команду к одной или
нескольким нитям. Задайте номера нитей, на которые вы хотите
воздействовать, в аргументе номер-нити. Номер-нити -- это
внутренний номер нити GDB, который показан в первом поле
`info threads'. Чтобы применить команду ко всем нитям, используйте
thread apply all
арг.
Когда GDB останавливает вашу программу, вследствие точки останова или по сигналу, он автоматически выбирает нить, в которой появилась эта точка останова или сигнал. GDB предупреждает вас о переключении контекста сообщением в форме `[Switching to сист-тег]' для идентификации нити.
См. раздел 5.4 Остановка и запуск многонитевых программ, для дополнительной информации о поведении GDB, когда вы останавливаете и запускаете многонитевую программу.
См. раздел 5.1.2 Установка точек наблюдения, для информации о точках наблюдения в многонитевых программах.
В большинстве систем GDB не имеет специальной поддержки для
отладки программ, создающих дополнительные процессы с помощью функции
fork
. Когда программа вызывает fork
, GDB будет
продолжать отладку родительского процесса, а дочерний процесс будет
выполняться беспрепятственно. Если выполнение дочернего процесса дойдет
до места, где вы установили точку останова, дочерний процесс получит
сигнал SIGTRAP
, который приведет к остановке процесса (если он не
перехватывает этот сигнал).
Однако, если вы хотите отладить дочерний процесс, существует достаточно
простое решение. Поместите вызов sleep
в код программы, который
дочерний процесс выполнит после fork
. Может быть удобным
вызывать sleep
, только если установлена определенная переменная
среды, или если существует определенный файл, так что задержка не будет
происходить, если вы не захотите отлаживать дочерний процесс.
Пока дочерний процесс спит, используйте программу ps
для
получения его идентификатора. Затем укажите GDB
(новому экземпляру GDB, если вы отлаживаете также и родительский
процесс) присоединиться к дочернему процессу (см. раздел 4.7 Отладка запущенного ранее процесса).
Начиная с этого момента, вы можете отлаживать дочерний процесс точно
так же, как любой другой процесс, к которому вы присоединились.
В системе HP-UX (только в версиях 11.x и более поздних?) GDB
предоставляет средства для отладки программ, которые создают
дополнительные процессы, используя функции fork
или vfork
.
По умолчанию, когда программа ветвится, GDB будет продолжать отладку родительского процесса, а дочерний процесс будет выполняться беспрепятственно.
Если вы хотите отлаживать дочерний процесс вместо родительского,
используйте команду set follow-fork-mode
.
set follow-fork-mode режим
fork
или vfork
в
программе. Вызов fork
или vfork
создает новый процесс.
режим может быть:
parent
child
ask
show follow-fork-mode
fork
или
vfork
.
Если вы запрашиваете отладку дочернего процесса, и за
vfork
следует exec
, GDB выполняет новую программу
до первой установленной в ней точки останова. Если в вашей исходной
программе была установлена точка останова на функции main
,
она будет также установлена на main
в
дочернем процессе.
Когда дочерний процесс порождается вызовом vfork
, вы не можете
отлаживать дочерний или родительский процесс до тех пор, пока не
завершится вызов exec
.
Если вы даете GDB команду run
после выполнения
exec
, новая программа стартует заново. Чтобы перезапустить
родительский процесс, используйте команду file
с именем
выполняемого файла родительской программы в качестве аргумента.
Вы можете использовать команду catch
, чтобы остановить
GDB, когда сделан вызов fork
, vfork
или
exec
. См. раздел 5.1.3 Установка точек перехвата.