[Содержание]   [Назад]   [Пред]   [Вверх]   [След]   [Вперед]  


7. Исследование исходных файлов

GDB может выводить части исходных текстов вашей программы, так как отладочная информация, записанная в ней, сообщает GDB, какие исходные файлы использовались при создании программы. Когда ваша программа останавливается, GDB сам выводит строку, на которой она остановилась. Аналогично, когда вы выбираете кадр стека (см. раздел 6.3 Выбор кадра), GDB выводит строку, на которой остановилось выполнение в этом кадре. Вы можете выводить другие части исходных файлов с помощью явных команд.

Если вы используете GDB через интерфейс к GNU Emacs, вы можете предпочесть воспользоваться средствами Emacs для просмотра исходных текстов; смотрите раздел 17. Использование GDB под управлением GNU Emacs.

7.1 Вывод строк исходного текста

Чтобы вывести строки файла с исходным текстом, используйте команду list (сокращенно l). По умолчанию выводятся десять строк. Существует несколько способов определения того, какую часть файла вы хотите вывести.

Здесь представлены наиболее употребительные формы команды list:

list номер-строки
Вывести строки, расположенные вокруг строки с номером номер-строки в текущем исходном файле.
list функция
Вывести строки, расположенные вокруг начала функции функция.
list
Вывести еще определенное количество строк. Если последние выведенные строки выводились с помощью команды list, то выводятся строки, следующие за последними выведенными; если, однако, последней выведенной строкой была одиночная строка, выведенная как часть отображения кадра стека (см. раздел 6. Исследование стека), то выводятся строки, расположенные вокруг нее.
list -
Вывести строки, расположенные непосредственно перед последними выведенными.

По умолчанию, для любой из этих форм команды list GDB выводит десять строк исходного текста. Вы можете изменить это командой set listsize:

set listsize число
Установить количество выводимых командой list строк в число (если аргумент команды list не задает явно какое-нибудь другое число).
show listsize
Отобразить количество строк, выводимых по команде list.

Повторение команды list нажатием RET отбрасывает аргумент, так что это эквивалентно вводу просто list. Это полезнее, чем вывод тех же самых строк снова. Исключение сделано для параметра `-'; этот параметр сохраняется при повторе команды, так что каждое повторение приводит к перемещению вверх по исходному файлу.

Обычно команда list ожидает от вас ноль, один или два указателя строк. Указатели строк определяют строки исходного текста; существует несколько способов их задания, но результат всегда заключается в задании строки исходного текста. Вот полное описание возможных параметров команды list:

list указ-стр
Вывести строки, расположенные вокруг строки, определяемой указ-стр.
list перв,посл
Вывести строки с перв до посл. Оба параметра являются указателями строк.
list ,посл
Вывести строки, расположенные перед посл.
list перв,
Вывести строки, начиная с перв.
list +
Вывести строки, расположенные сразу за последними выведенными.
list -
Вывести строки, расположенные непосредственно перед последними выведенными.
list
Описано в предыдущей таблице.

Ниже перечислены способы указания одиночной строки исходного текста -- все виды указателей строк.

номер
Определяет строку с номером номер из текущего исходного файла. Если в качестве параметров к команде list задано два указателя строк, это относится к тому же исходному файлу, что и первый указатель строки.
+смещение
Указывает на строку, смещенную вперед на смещение строк относительно последней выведенной строки. Когда используется в качестве второго указателя строки для команды list, имеющей два указателя, задает строку, смещенную на смещение строк вниз относительно строки, определенной первым указателем.
-смещение
Указывает на строку, расположенную на смещение строк раньше последней выведенной строки.
имя-файла:номер
Задает строку номер из исходного файла имя-файла.
функция
Определяет строку, с которой начинается тело функции функция. Например, в Си это строка с открывающейся фигурной скобкой.
имя-файла:функция
Определяет строку с открывающейся фигурной скобкой, с которой начинается тело функции функция в файле имя-файла. Имя файла необходимо лишь для того, чтобы избежать неоднозначности, когда в различных исходных файлах есть одинаково названные функции.
*адрес
Определяет строку, соответствующую адресу адрес программы. адрес может быть любым выражением.

7.2 Поиск в исходных файлах

Существуют две команды для поиска по регулярному выражению в текущем исходном файле.

forward-search рег-выраж
search рег-выраж
Команда `forward-search рег-выраж' проверяет на соответствие регулярному выражению рег-выраж каждую строку, начиная со строки, следующей за последней выведенной. Найденная строка выводится. Вы можете использовать синоним `search рег-выраж' или сокращать имя команды как fo.
reverse-search рег-выраж
Команда `reverse-search рег-выраж', двигаясь назад, проверяет на соответствие регулярному выражению рег-выраж каждую строку, начиная с предшествующей последней выведенной. Найденная строка выводится. Вы можете сокращать эту команду как rev.

7.3 Определение каталогов с исходными файлами

Исполняемые программы иногда не сохраняют имена каталогов, в которых находились исходные файлы, из которых они скомпилированы, а хранят лишь имена файлов. Даже если они их сохранили, каталоги могли быть перемещены в период между компиляцией и сеансом отладки. У GDB есть список каталогов для поиска исходных файлов; он называется путь для исходных файлов. Каждый раз, когда GDB требуется исходный файл, он перебирает по порядку все каталоги из этого списка, пока не находит файл с требуемым именем. Заметьте, что пути поиска исполняемых файлов для этой цели не используются, как не используется и текущий рабочий каталог, если только он не присутствует в пути для исходных файлов.

Если GDB не может найти исходный файл, используя путь для исходных файлов, а в объектном файле программы указан какой-либо каталог, GDB просматривает также и его. В последнюю очередь, если путь для исходных файлов пуст и запись о каталоге компиляции отсутствует, GDB просматривает текущий каталог.

При переустановке или переупорядочивании пути для исходных файлов, GDB очищает любую запомненную им информацию о том, где исходные файлы были найдены и о расположении строк в них.

Когда вы вызываете GDB, путь для исходных файлов содержит только `cdir' и `cwd', в этом порядке. Для добавления других каталогов, используйте команду directory.

directory имя-каталога ...
dir имя-каталога ...
Добавить каталог имя-каталога в начало пути для исходных файлов. Этой команде могут быть заданы несколько имен, разделенные `:' (`;' в MS-DOS и MS-Windows, где `:' обычно является частью абсолютного имени файла) или пробелом. Вы можете указать каталог, который уже содержится в пути для исходных файлов; это переместит его в начало, так что GDB будет просматривать его раньше. Вы можете использовать строку `$cdir' для ссылки на каталог компиляции (если информация о нем сохранена), и `$cwd' для ссылки на текущий рабочий каталог. `$cwd' -- это не то же самое, что `.'. Первая отслеживает текущий рабочий каталог, который может меняться во время вашего сеанса работы с GDB, тогда как вторая сразу преобразовывается в текущий каталог в момент его добавления в путь для исходных файлов.
directory
Очистить путь для файлов с исходными текстами. Эта команда требует подтверждения.
show directories
Вывести путь поиска исходных файлов: показать, какие каталоги он содержит.

Если ваш путь для исходных файлов перемешан с уже неиспользуемыми каталогами, GDB может иногда вызвать недоумение, найдя неправильный вариант исходного файла. Вы можете исправить ситуацию следующим образом:

  1. Использовать directory без параметров, чтобы очистить путь поиска исходных файлов.
  2. Использовать directory с подходящими аргументами, чтобы переустановить каталоги, которые вы хотите видеть в пути для исходных файлов. Вы можете добавить все каталоги одной командой.

7.4 Исходный текст и машинный код

Вы можете использовать команду info line, чтобы отобразить строки исходного текста в программные адреса (и наоборот), и команду disassemble, чтобы вывести диапазон адресов в виде машинных инструкций. При запуске в режиме GNU Emacs, команда info line выводит стрелку, указывающую на заданную строку. Также info line выводит адреса как в символьной форме, так и в шестнадцатеричной.

info line указ-стр
Выводит начальный и конечный адреса скомпилированного кода, соответствующего строке исходного текста указ-стр. Вы можете определить строки исходного текста любым способом, воспринимаемым командой list (см. раздел 7.1 Вывод строк исходного текста).

Например, мы можем использовать info line для определения положения объектного кода первой строки функции m4_changequote:

(gdb) info line m4_changequote
Line 895 of "builtin.c" starts at pc 0x634c and ends at 0x6350.

Мы также можем запросить (используя *адрес как форму задания указ-стр), какая строка исходного текста соответствует определенному адресу:

(gdb) info line *0x63ff
Line 926 of "builtin.c" starts at pc 0x63e4 and ends at 0x6404.

После info line, адрес, используемый по умолчанию для команды x, меняется на начальный адрес строки, так что `x/i' достаточно для начала исследования машинного кода (см. раздел 8.5 Исследование памяти). Этот адрес также сохраняется как значение вспомогательной переменной $_ (см. раздел 8.9 Вспомогательные переменные).

disassemble
Эта специализированная команда служит для дампа диапазона памяти в виде машинных инструкций. Диапазоном памяти по умолчанию является функция, в которой находится счетчик программы в выбранном кадре. Одиночным параметром этой команды является значение счетчика программы; GDB выводит дамп функции, которой принадлежит указанный адрес. Два параметра определяют диапазон адресов для дампа (первый включается, второй исключается).

Следующий пример показывает результат дисассемблирования диапазона адресов кода HP PA-RISC 2.0:

(gdb) disas 0x32c4 0x32e4
Dump of assembler code from 0x32c4 to 0x32e4:
0x32c4 <main+204>:      addil 0,dp
0x32c8 <main+208>:      ldw 0x22c(sr0,r1),r26
0x32cc <main+212>:      ldil 0x3000,r31
0x32d0 <main+216>:      ble 0x3f8(sr4,r31)
0x32d4 <main+220>:      ldo 0(r31),rp
0x32d8 <main+224>:      addil -0x800,dp
0x32dc <main+228>:      ldo 0x588(r1),r26
0x32e0 <main+232>:      ldil 0x3000,r31
End of assembler dump.

Некоторые архитектуры имеют несколько широко используемых наборов мнемоник инструкций или другой синтаксис.

set disassembly-flavor набор-инструкций
Выбрать набор инструкций для использования при дисассемблировании программы командами disassemble и x/i. В настоящее время эта команда определена только для Intel x86. Вы можете установить набор-инструкций в intel или att. По умолчанию установлено att, диалект AT&T используется по умолчанию ассемблерами Unix на архитектурах, базирующихся на x86.


[Содержание]   [Назад]   [Пред]   [Вверх]   [След]   [Вперед]