[ Страница назад | Страница вперед | Содержание | Индекс | Библиотека | Юридическая информация | Поиск ]

Программирование: Разработка и отладка программ


Просмотр и редактирование исходного файла с помощью программы отладки dbx

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

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

Примечание: это справедливо только в том случае, если процесс был прерван в разделе программы, откомпилированном для отладки.

Дополнительная информация приведена в следующих разделах:

Изменение каталога исходных файлов

По умолчанию программа dbx ищет исходный файл отлаживаемой программы в следующих каталогах:

Список просматриваемых каталогов можно изменить с помощью опции -I, указываемой при вызове dbx, или с помощью команды use в программе dbx. Например, если после компиляции исходного файла вы переместили его в другой каталог, то с помощью одной из этих команд вы должны указать его старое расположение, новое расположение и некоторое временное расположение.

Просмотр текущего файла

Просмотреть текст исходного файла можно с помощью команды list.

С командами list, stop и trace можно использовать символы $ (знак доллара) и @ (коммерческое 'at'), которые определяют выражение строка-исходного-файла. Символ $ задает следующую выполняемую, а символ @ - следующую показываемую строку.

Команда move предназначена для перехода к следующей указанной строке.

Изменение текущего файла или процедуры

Команды func и file предназначены для изменения текущего файла, текущей процедуры и текущей строки внутри программы dbx без запуска какой-либо части вашей программы.

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

/Выражение [/] Выполняется поиск по образцу в текущем исходном файле в прямом направлении.
? выражение [?] Выполняется поиск по образцу в текущем исходном файле в обратном направлении.

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

С помощью команды edit можно загрузить исходный файл во внешний текстовый редактор. Можно переопределить редактор, установленный по умолчанию (vi), указав имя редактора в переменной среды EDITOR перед запуском программы dbx.

После завершения сеанса редактирования управление процессом будет вновь передано программе dbx.

 

Отладка программ с несколькими нитями

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

Активная нить Пользовательская нить, которая ответственна за останов программы при попадании в точку прерывания. С активными нитями работают команды, предназначенные для пошагового выполнения программы.
Текущая нить Пользовательская нить, которую вы изучаете. В контексте текущей нити работают команды, выдающие информацию.

По умолчанию активная нить и текущая нить - это одно и то же. С помощью команды thread можно сделать текущей другую нить. В списке нитей, выдаваемом командой thread, текущая нить отмечена знаком >. Если активная нить не совпадает с текущей, то она отмечена знаком *.

Идентификация объектов, связанных с нитями

Для синхронизации доступа к ресурсам нити используют взаимные блокировки и переменные условия. Нити, взаимные блокировки и переменные условия создаются с помощью объектов атрибутов, которые определяют их характеристики. Программа dbx автоматически создает несколько переменных, идентифицирующих различные объекты, связанные с нитями. Для каждого класса объектов программа dbx поддерживает нумерованный список объектов, причем для каждого объекта из списка она создает связанную переменную. Имена этих переменных начинаются с символа $ (знака доллара), за которым следует буква, указывающая на класс объекта (a, c, m илиt), и номер, отражающий положение объекта в списке класса. Ниже перечислены возможные буквы и связанные классы объектов:

Например, $t2 соответствует второй нити в списке нитей dbx. В данном случае 2 - это номер нити объекта, который не связан с идентификатором нити ядра (tid). Получить список объектов каждого класса можно с помощью следующих команд программы dbx: attribute, condition, mutex и thread. Например, для получения списка всех нитей можно просто ввести команду thread.

Программа dbx автоматически создает и поддерживает переменную $running_thread, идентифицирующую нить, которая выполнялась в момент попадания в точку прерывания.

Точки прерывания и нити

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

Если вы хотите указать, какая именно нить должна попадать в данную точку прерывания, вы можете с помощью команд stop или stopi установить условную точку прерывания. Необходимые условия автоматически задаются следующими псевдонимами:

Эти псевдонимы останавливают выполнение нити на указанной функции или на строке с указанным номером, соответственно. Номер_нити - это номер, который входит в состав символьного имени нити, выдаваемого командой thread (например, 2 - это Номер_нити в имени $t2).

Например, следующая команда останавливает выполнение нити $t1 на функции func1:

(dbx) bfth (func1, 1)

следующая команда - выполнение нити $t2 на строке 103 исходного файла:

(dbx) blth (103, 2)

Если для точки прерывания не указана конкретная нить, то активной может стать любая нить, выполняющая код, в котором установлена точка прерывания.

Команды работы с нитями

В программе dbx предусмотрены следующие команды, предназначенные для работы с отдельными объектами атрибутов, переменными условия, взаимными блокировками и нитями:

attribute Выдает информацию обо всех объектах атрибутов или объектах атрибутов с данным номером атрибута.
condition Выдает информацию обо всех переменных условия, переменных с ожидающими нитями, переменных без ожидающих нитей или переменных с данным номером условия.
mutex Выдает информацию обо всех взаимных блокировках, установленных или снятых блокировках или блокировках с указанным номером.
thread Выдает информацию о нитях, делает указанную нить текущей, а также блокирует и разблокирует нити.

Некоторые команды непосредственно не работают с нитями, но изменяют свой вид в случае их использования при отладке программы с несколькими нитями:

print При передаче символьного имени объекта, сообщаемого командами thread, mutex, condition или attribute, выдает информацию о состоянии объекта. Например, для просмотра информации о взаимной блокировке третьей и первой нитей введите:

(dbx) print $m3, $t1

stop, stopi Если одна нить попадает в точку прерывания, все остальные нити также останавливаются, как и таймер процесса. Это означает, что точка прерывания не влияет на глобальное поведение процесса. Это обычные (глобальные) точки прерывания, которые могут остановить выполнение любой нити.

Если же вы хотите определить конкретную нить, которая будет попадать в точку прерывания, необходимо задать условие, как это показано в следующем примере (в точку прерывания, установленную в функции f1, может попасть только нить $t5):

(dbx)stopiat &f1if($running_thread == 5)

Аналогичный формат имеет и команда stop. Еще один способ задания условий заключается в применении псевдонимов bfth и blth (см. раздел Точки прерывания и нити).

step, next, nexti По командам step, next и nexti выполнение всех нитей возобновляется. Для пошагового выполнения только активной нити необходимо установить переменную $hold_next программы dbx.
stepi Команда stepi выполняет указанное число машинных инструкций только в активной нити. Другие нити отлаживаемого процесса на время выполнения команды stepi не запускаются.
trace, tracei Если в командах trace и tracei указать условие, то можно трассировать определенную пользовательскую нить. Ниже приведен пример трассировки изменений в var1, внесенных нитью $t1:

(dbx) trace var1 if ($running_thread == 1)

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

59 var = 5;

60 printf("var=%d\n", var);

Для проверки правильности инициализации переменной вы можете ввести команду:

stop at 60 if var==5

Программа dbx установит точку прерывания в строке 60, но эта точка будет доступна только в том случае, если значение данной переменной не будет обновлено другой нитью. В противном случае программа dbx обнаружит, что значение переменной не равно 5, и продолжит выполнение.

Отладка программ с несколькими процессами

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

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

Если в режиме параллельной отладки порождается новый процесс, то родительский и дочерний процессы останавливаются. Для контроля за работой дочернего процесса для программы dbx открывается отдельный виртуальный терминал Xwindow:

(dbx) multproc on
(dbx) multproc
включен режим параллельной отладки
(dbx) run

При порождении процесса выполнение родительского процесса останавливается и программа dbx показывает информацию о состоянии программы:

порожден новый процесс, pid = 422, процесс остановлен, ожидается ввод
остановлен из-за порождения дочернего процесса в режиме с несколькими
процессами в точке 0x1000025a (fork+0xe)
(dbx)

Затем для отладки дочернего процесса открывается еще один виртуальный терминал Xwindow:

отладка дочернего процесса, pid=422, процесс остановлен, ожидается ввод
остановлен из-за порождения дочернего процесса в режиме с несколькими
процессами в точке 0x10000250
10000250 (fork+0x4) )80010010    1       r0,0x10(r1)
(dbx)

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

Если программа выполняет функцию exec в режиме параллельной отладки, то она переписывает саму себя, и символьная информация становится устаревшей. При выполнении функции exec все точки прерывания удаляются; новая программа останавливается для идентификации, упрощая отладку. Программа dbx сама подключается к образу новой программы, вызывает функцию для определения имени новой программы, сообщает это имя, а затем выдает приглашение на ввод. Приглашение выглядит примерно следующим образом:

(dbx) multproc
Включен режим параллельной отладки
(dbx) run
Attaching to program from exec . . . 
Determining program name . . . 
Successfully attached to /home/user/execprog . . . 
Reading symbolic information . . . 
(dbx)

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

Для того чтобы следить за порожденным дочерним процессом, не открывая новое окно Xwindow, укажите в команде multproc флаг child. В этом случае при порождении процесса программа dbx будет следить за дочерним процессом. Если указать в команде multproc флаг parent, то при порождении процесса программа dbx остановится, но затем будет отслеживать родительский процесс. Если указать оба флага (и child, и parent), то будет отслеживаться выполняемый процесс. Эти флаги полезны при отладке программ без запуска Xwindows.

Связанная информация

Программа символьной отладки dbx - Обзор

Работа с программой отладки dbx

Проверка программных данных

Применение dbx для отладки на машинном уровне

Настройка среды отладки dbx


[ Страница назад | Страница вперед | Содержание | Индекс | Библиотека | Юридическая информация | Поиск ]