«Ричард Столмен, Роланд Пеш, Стан Шебс и другие. (Присылайте сообщения об ошибках и комментарии к GDB по адресу bug-gdb Отладка с помощью GDB TEXinfo 1999-10-01.07 Copyright c 1988-2000 Free Software ...»
Отладка с помощью GDB
Отладчик gnu уровня исходного кода
Восьмая Редакция, для GDB версии 5.0
Март 2000
Ричард Столмен, Роланд Пеш, Стан Шебс и другие.
(Присылайте сообщения об ошибках и комментарии к GDB по адресу [email protected].)
Отладка с помощью GDB
TEXinfo 1999-10-01.07 Copyright c 1988-2000 Free Software Foundation, Inc.
Перевод c 2000 Дмитрий Сиваченко.
Published by the Free Software Foundation 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA ISBN 1-882114-77-9 Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modied versions of this manual under the conditions for verbatim copying, provided also that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modied versions.
i Оглавление Обзор GDB..................................... Свободно распространяемые программы......................... Кто внес вклад в развитие GDB................................. 1 Пример сеанса GDB.......................... 2 Вход и выход из GDB........................ 2.1 Вызов GDB................................................. 2.1.1 Выбор файлов..................................... 2.1.2 Выбор режимов................................... 2.2 Выход из GDB............................................ 2.3 Команды оболочки........................................ 3 Команды GDB.............................. 3.1 Синтаксис команд......................................... 3.2 Завершение команд........................................ 3.3 Получение справки........................................ 4 Выполнение программ под управлением GDB............................................ 4.1 Компиляция для отладки.................................. 4.2 Начало выполнения вашей программы..................... 4.3 Аргументы вашей программы............................. 4.4 Рабочая среда вашей программы........................... 4.5 Рабочий каталог вашей программы........................ 4.6 Ввод и вывод вашей программы............................ 4.7 Отладка запущенного ранее процесса...................... 4.8 Уничтожение дочернего процесса........................... 4.9 Отладка программ с несколькими нитями.................. 4.10 Отладка многонитевых программ......................... 5 Остановка и продолжение исполнения....... 5.1 Точки останова, точки наблюдения и точки перехвата...... 5.1.1 Установка точек останова......................... 5.1.2 Установка точек наблюдения...................... 5.1.3 Установка точек перехвата........................ 5.1.4 Удаление точек останова.......................... 5.1.5 Отключение точек останова....................... 5.1.6 Условия останова................................. 5.1.7 Команды точки останова.......................... 5.1.8 Меню точки останова............................. 5.1.9 “Не удается поместить точки останова”............ 5.2 Продолжение и выполнение по шагам...................... 5.3 Сигналы.................................................. 5.4 Остановка и запуск многонитевых программ............... ii Отладка с помощью GDB 6 Исследование стека......................... 6.1 Кадры стека.............................................. 6.2 Цепочки вызовов........................................... 6.3 Выбор кадра.............................................. 6.4 Информация о кадре стека................................. 7 Исследование исходных файлов.............. 7.1 Вывод строк исходного текста............................. 7.2 Поиск в исходных файлах.................................. 7.3 Определение каталогов с исходными файлами.............. 7.4 Исходный текст и машинный код.......................... 8 Исследование данных....................... 8.1 Выражения................................................ 8.11 Аппаратные средства поддержки вычислений с плавающей 9 Использование GDB с различными языками 9.1.1 Соответствие расширений файлов и языков........ 9.2 Отображение языка программирования..................... 9.3 Проверка диапазона и принадлежности типу............... 9.3.1 Краткий обзор проверки соответствия типов....... 9.4.1.5 Проверки диапазона и принадлежности типу 9.4.2.6 Проверки диапазона и принадлежности типу 10 Исследование таблицы символов........... 11 Изменение выполнения.................... 13 Определение отладочной цели............. 13.4.1.6 Использование программы gdbserve.nlm 14 Информация о конфигурации.............. 14.2 Встроенные операционные системы...................... 14.3.3.2 Использование встроенного эмулятора E 16 Фиксированные последовательности команд 17 Использование GDB под управлением gnu 20 Отчеты об ошибках в GDB............... 21 Редактирование командной строки........ 22 Использование истории в интерактивном Приложение A Форматирование документации Приложение B Установка GDB.............. B.2 Определение имен рабочих и целевых машин.............. Алфавитный указатель....................... Обзор GDB Назначение отладчика, такого как GDB—позволить вам увидеть, что происходит “внутри” другой программы во время ее выполнения, или что делала другая программа в момент краха.
GDB может выполнять действия четырех основных типов (а также другие, поддерживающие эти основные), чтобы помочь вам выявить ошибку:
• Начать выполнение вашей программы, задав все, что может повлиять на ее поведение.
• Остановить вашу программу при указанных условиях.
• Исследовать, что случилось, когда ваша программа остановилась.
• Изменить вашу программу, так что вы можете экспериментировать с устранением эффектов одной ошибки и продолжить выявление других.
Вы можете использовать GDB для отладки программ, написанных на Си и Си++. Для получения более подробной информации, смотрите Раздел 9.4 [Поддерживаемые языки], с. 81. Для дополнительной информации, смотрите Раздел 9.4.1 [Си и Си++], с. 81.
GDB частично поддерживает языки Модула-2 и Chill. Для получения информации о Модуле-2, смотрите Раздел 9.4.2 [Модула-2], с. 87. Для получения информации о Chill, см.
Раздел 9.4.3 [Chill], с. Отладка программ на Паскале, которые используют множества, поддиапазоны, файловые переменные или вложенные функции, в настоящее время не работает. GDB не поддерживает ввод выражений, вывод значений, и аналогичные возможности, использующие синтаксис Паскаля.
GDB может использоваться для отладки программ, написанных на Фортране, хотя может возникнуть необходимость ссылаться на некоторые переменные с использованием знака подчеркивания на конце.
Свободно распространяемые программы GDB—свободная программа, защищенная Универсальной Общественной Лицензией gnu (GPL). GPL предоставляет вам свободу копировать или изменять программу, но каждый человек, получая копию, также получает свободу изменять эту копию (это означает, что он должен получить доступ к исходному коду), и свободу распространять последующие копии. Обычные компании, разрабатывающие программы, используют авторские права для ограничения ваших свобод; Фонд Свободного Программного Обеспечения использует GPL для сохранения этих свобод.
Главное, Универсальная Общественная Лицензия—это лицензия, говорящая, что вы имеете эти свободы и что вы не можете их у кого-либо отнять.
Кто внес вклад в развитие GDB Первоначальным автором GDB, как и многих других программ gnu, был Ричард Столмен. Многие другие люди внесли вклад в его разработку. Этот раздел пытается отдать должное основным участникам разработки. Одним из достоинств свободных программ является то, что любой человек имеет свободу делать вклад в их развитие; к сожалению, мы не можем в действительности поблагодарить здесь всех. Файл ‘ChangeLog’ в поставке GDB представляет детальнейший отчет.
Изменения, сделанные задолго до версии 2.0 потеряны в тумане времен.
Оправдание: Дополнения к этому разделу особенно приветствуются. Если вы или ваши друзья (или враги, чтобы соблюдать справедливость) были незаслуженно пропущены в этом списке, мы будем рады добавить ваши имена!
Особенно мы хотим сказать спасибо тем, кто присматривал за GDB между основными выпусками, чтобы они не сочли свои многочисленные заслуги оставленными без благодарности: Эндрю Кагни (выпуск 5.0); Джим Бленди (выпуск 4.18); Джесон Моленда (выпуск 4.17); Стан Шебс (выпуск 4.14); Фред Фиш (выпуски 4.16, 4.15, 4.13, 4.12, 4.11, 4.10, и 4.9);
Сту Гроссман и Джон Гилмор (выпуски 4.8, 4.7, 4.6, 4.5, и 4.4); Джон Гилмор (выпуски 4.3, 4.2, 4.1, 4.0, и 3.9); Джим Кингдон (выпуски 3.5, 3.4, и 3.3) и Ренди Смит (выпуски 3.2, 3.1, и 3.0).
Ричард Столмен, которому в различные времена помогали Петер ТерМаат, Крис Хенсон и Ричард Млинарик, занимался выпусками до 2.8.
Михаэль Тиманн является автором большей части поддержки gnu Си++ в GDB, со значительным дополнительным вкладом от Пера Бозера. Джеймс Кларк написал дешифровщик1 имен gnu Си++. Ранняя работа по Си++ была сделана Петером ТерМаатом (который также сделал много общей работы по обновлению, приведшей к выпуску 3.0).
Для исследования многих форматов объектных файлов, GDB 4 использует библиотеку подпрограмм BFD. BFD был совместным проектом Дэвида В. Хенкел-Волласа, Рича Пиксли, Стива Чемберлена, и Джона Гилмора.
Дэвид Джонсон первоначально написал поддержку COFF; Пейс Виллисон первоначально сделал поддержку инкапсулированного COFF.
Брент Бенсон из Harris Computer Systems сделал поддержку DWARF 2.
Адам ДеБур и Брэндли Дэвис сделали поддержку ISI Optimum V. Пер Бозер, Нобоюки Хикичи, и Алессандро Форин сделали поддержку MIPS. Жан-Даниэль Фекет сделал поддержку Sun 386i. Крис Хенсон улучшил поддержку HP9000. Нобоюки Хикичи и Томоюки Хаси сделали поддержку Sony/News OS 3. Дэвид Джонсон сделал поддержку Encore Umax. Юрки Куоппала сделал поддержку Altos 3068. Джефф Ло сделал поддержку HP PA и SOM. Кейс Паккард сделал поддержку NS32K. Доуг Ребсон сделал поддержку Acorn Risc Machine. Боб Раск сделал поддержку Harris Nighthawk CX-UX. Крис Смит сделал поддержку Convex (и отладку программ на Фортране). Джонатан Стоун сделал поддержку Pyramid. Михаэль Тиманн сделал поддержку SPARC. Тим Такер сделал поддержку для Gould NP1 и Gould Powernode. Пейс Виллисон сделал поддержку Intel 386. Джей Восбург сделал поддержку Symmetry.
В Си++ и других объектно-ориентированных языках программирования, у вас может быть несколько функций с одним именем, но с аргументами разных типов. Например:
double add_two(double a, double b);
double add_two(double a, int b);
Компилятор генерирует код для вызова верной функции по заданным аргументам. Это называется перегрузкой функций.
Однако, компоновщик требует, чтобы все символы имели недвусмысленные имена. Поэтому компилятор шифрует (от английского “mangle”) имена перегруженных функций так, чтобы они включали типы аргументов и возвращаемые значения. К примеру, приведенные выше функции могут быть могут быть зашифрованы примерно так:
add_two_Ret_int_int_int add_two_Ret_double_double_double add_two_Ret_double_double_int (в действительности шифрованные имена выглядят безобразнее). В результате компоновщик может правильно обработать перегруженные функции. Дешифровщик (от английского “demangler”)—это программа (или функция), которая выполняет обратную операцию: анализируя зашифрованные имена, она выдает исходную сигнатуру функции. Это необходимо, чтобы отобразить то, что программист сможет понять и связать с исходным текстом своей программы. Для этого любому средству отладки, поддерживающему Си++, обычно требуется дешифровщик. (Прим. переводчика) Андреас Шваб сделал поддержку M68K Linux.
Рич Шаефер и Петер Шауер помогли реализовать поддержку разделяемых библиотек SunOS.
Джей Фенласон и Роланд МакГрес проверили совместимость GDB и GAS по нескольким наборам машинных инструкций.
Патрик Дювал, Тед Голдстейн, Викрам Кока и Гленн Инжел помогли разработать удаленную отладку. Intel Corporation, Wind River Systems, AMD и ARM сделали модули удаленной отладки для целей i960, VxWorks, A29K UDI, и RDI соответственно.
Брайан Фокс является автором библиотек Readline, предоставляющих историю команд и возможность редактирования командной строки.
Эндрю Бирс из SUNY Bualo написал код для переключения языков, поддержку Модулы-2, главу ‘Языки’ этого руководства.
Фред Фиш написал большую часть поддержки Unix System Vr4. Он также улучшил поддержку завершения команд для поддержки перегруженных символов Си++.
Hitachi America, Ltd. спонсировала поддержку для процессоров H8/300, H8/500 и SuperH.
NEC спонсировала поддержку процессоров v850, Vr4xxx и Vr5xxx.
Mitsubishi спонсировала поддержку процессоров D10V, D30V и M32R/D.
Toshiba спонсировала поддержку процессора TX39 Mips.
Matsushita спонсировала поддержку процессоров MN10200 и MN10300.
Fujitsu спонсировала поддержку процессоров SPARClite и FR30.
Кунг Шу, Джефф Ло и Рик Слэдки добавили поддержку аппаратных точек наблюдения.
Михаэль Снайдер добавил поддержку точек трассировки.
Сту Гроссман написал gdbserver.
Джим Кингдон, Петер Шауер, Ян Тейлор и Сту Гроссман сделали почти бесчисленное количество исправлений и улучшений во всем GDB.
Следующие люди из Hewlett-Packard Company сделали поддержку архитектуры PARISC 2.0, HP-UX 10.20, 10.30 и 11.0 (усеченный режим), реализации нитей HP в ядре, компилятора HP aC++, и конечного интерфейса пользователя: Бен Крепп, Ричард Тайтл, Джон Бишоп, Сюзан Макчиа, Кэси Манн, Сэтиш Пай, Индиа Поул, Стив Рейраур и Елена Заннони. Ким Хаас предоставил специфичную для HP информацию для этого руководства.
Cygnus Solutions спонсировала поддержку GDB и большую часть его развития с года. Среди инженеров Cygnus, работавших над GDB на постоянной основе, Марк Александер, Джим Бленди, Пер Бозер, Кевин Беттнер, Эдит Эпштейн, Крис Фейлор, Фред Фиш, Мартин Хант, Джим Ингам, Джон Гилмор, Сту Гроссман, Кунг Шу, Джим Кингдон, Джон Мецлер, Фернандо Нассер, Джеффри Ноер, Дон Перчик, Рич Пиксли, Зденек Радуч, Кейс Сейц, Стан Шебс, Дэвид Тейлор и Елена Заннони. Кроме того, Дейв Бролли, Ян Кармихаэль, Стив Чемберлен, Ник Клифтон, Джэй Ти Конклин, Стен Кокс, Ди Джей Делори, Ульрих Дреппер, Фрэнк Эйглер, Дуг Эванс, Син Фаган, Дэвид ХенкельВоллас, Ричард Хендерсон, Джефф Холком, Джефф Ло, Джим Лемке, Том Лорд, Боб Мансон, Михаэль Мейсснер, Джейсон Меррилл, Кэтрин Мур, Дрю Мосли, Кен Робурн, Гавин Ромиг-Кох, Роб Савой, Джейми Смит, Майк Стамп, Ян Тейлор, Анжела Томас, Михаэль Тиманн, Том Тромей, Рон Унро, Джим Вилсон и Дэвид Зун также сделали свой вклад в большей или меньшей степени.
4 Отладка с помощью GDB 1 Пример сеанса GDB Вы можете пользоваться этим руководством в свое удовольствие, чтобы прочитать о GDB все. Однако, достаточно небольшого количества команд, чтобы начать пользоваться отладчиком. Эта глава иллюстрирует эти команды.
В этом примере сеанса мы выделяем ввод пользователя так: ввод, чтобы его было проще отличить от находящегося рядом вывода программы.
В одной из предварительных версий программы gnu m4 (настраиваемый макропроцессор), была допущена следующая ошибка: иногда, при замене строк, определяющих кавычки, со значений по умолчанию, команды, использовавшиеся для поиска одного макроопределения внутри другого, прекращали работать. В следующем коротком сеансе m4, мы определим макрос foo, который расширяется до 0000; затем мы используем встроенную процедуру m4 defn, чтобы определить bar точно также. Однако, когда мы изменим открывающую кавычку на, а закрывающую на, та же самая процедура не сможет определить новый синоним baz:
dene(foo,0000) dene(bar,defn(‘foo’)) changequote(,) dene(baz,defn(foo)) m4: End of input: 0: fatal error: EOF in string Попытаемся с помощью GDB понять, что же происходит.
GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 5.0, Copyright 1999 Free Software Foundation, Inc...
GDB читает только минимум символьных данных, достаточный для того, чтобы знать, где в случае необходимости искать остальные; в результате первое приглашение появляется очень быстро. Теперь мы велим GDB использовать меньшую ширину экрана, чем обычно, чтобы примеры умещались на страницах этого руководства.
(gdb) set width Нам необходимо увидеть, как работает встроенная процедура m4 changequote. Посмотрев исходный текст, мы знаем, что соответствующей подпрограммой является m4_ changequote, так что мы устанавливаем там точку останова с помощью команды GDB break.
m4: Конец ввода: 0: фатальная ошибка: EOF в строке (Прим. переводчика) (gdb) break m4 changequote Breakpoint 1 at 0x62f4: file builtin.c, line 879.
Используя комманду run, мы запускаем m4 под управлением GDB; до тех пор, пока управление не достигло подпрограммы m4_changequote, программа выполняется как обычно:
Starting program: /work/Editorial/gdb/gnu/m4/m dene(foo,0000) Чтобы активировать точку останова, мы вызываем changequote. GDB приостанавливает выполнение m4, выводя на экран информацию о том месте, где он остановился.
changequote(,) Breakpoint 1, m4_changequote (argc=3, argv=0x33c70) 879 if (bad_argc(TOKEN_DATA_TEXT(argv[0]),argc,1,3)) Теперь мы используем команду n (next), чтобы продолжить выполнение до следующей строки текущей функции.
882 set_quotes((argc >= 2) ? TOKEN_DATA_TEXT(argv[1])\ set_quotes выглядит как нужная нам подпрограмма. Мы можем войти в нее, используя команду s (step) вместо next. step переходит на следующую исполняемую строку любой подпрограммы, так что она входит в set_quotes.
set_quotes (lq=0x34c78 "", rq=0x34c88 "") Отображение, показывающее подпрограмму (и ее параметры), где m4 сейчас приостановлен, называется отображением кадра стека. Оно показывает обзор стека. Мы можем использовать команду backtrace (которая может сокращаться как bt), чтобы посмотреть, в каком месте стека мы находимся: команда backtrace выводит кадр стека для каждой активной подпрограммы.
#0 set_quotes (lq=0x34c78 "", rq=0x34c88 "") #1 0x6344 in m4_changequote (argc=3, argv=0x33c70) #2 0x8174 in expand_macro (sym=0x33320) at macro.c: #3 0x7a88 in expand_token (obs=0x0, t=209696, td=0xf7fffa30) #4 0x79dc in expand_input () at macro.c: #5 0x2930 in main (argc=0, argv=0xf7fffb20) at m4.c: Чтобы посмотреть, что же происходит, мы проходим по шагам еще несколько строк. Первые два раза мы можем использовать ‘s’; следующие два раза мы пользуемся командой n, чтобы избежать вхождения в подпрограмму xstrdup.
def_lquote : xstrdup(lq);
: xstrdup(rq);
538 len_lquote = strlen(rquote);
Последняя выведенная строка выглядит несколько странно; мы можем исследовать переменные lquote и rquote, чтобы понять, действительно ли это определенные нами новые левая и правая кавычки. Мы используем команду p (print), чтобы посмотреть их значения.
(gdb) p lquote (gdb) p rquote Действительно, lquote и rquote являются новыми кавычками. Для просмотра контекста, мы можем вывести десять строк исходного текста, окружающих текущую строку, используя команду l (list).
538 len_lquote = strlen(rquote);
539 len_rquote = strlen(lquote);
Давайте пройдем еще две строки, которые устанавливают len_lquote и len_rquote, и затем исследуем значения этих переменных.
(gdb) p len lquote (gdb) p len rquote Это, очевидно, неправильно, так как len_lquote и len_rquote обозначают длины переменных lquote и rquote соответственно. Мы можем присвоить им лучшие значения, используя команду p, так как она может выводить значение любого выражения, а выражение может содержать вызовы подпрограмм и присваивания.
(gdb) p len lquote=strlen(lquote) (gdb) p len rquote=strlen(rquote) Достаточно ли этого, чтобы решить проблему использования новых кавычек во встроенной процедуре m4 defn? Мы можем продолжить выполнение m4 командой c (continue), и затем попробовать пример, первоначально вызывавший ошибку:
Continuing.
dene(baz,defn(foo)) Успех! Теперь новые кавычки работают так же хорошо, как и стандартные. Кажется, проблема заключалась лишь в двух опечатках, приводивших к неправильному определению длин. Мы позволим m4 выйти, подавая ему на вход EOF:
Program exited normally. Сообщение ‘Program exited normally.’ исходит от GDB; оно показывает, что m4 закончил выполнение. Мы можем завершить наш сеанс работы с GDB командой quit.
Программа завершилась нормально. (Прим. переводчика) 2 Вход и выход из GDB Эта глава посвящена тому, как запустить GDB и как из него выйти. Основные принципы:
• введите ‘gdb’ для вызова GDB.
• введите quit или C-d для выхода из него.
2.1 Вызов GDB Вызывайте GDB путем запуска программы gdb. Начав работу, GDB считывает команды с терминала до тех пор, пока вы не скажете ему выйти.
Вы также можете запустить gdb с различными аргументами и ключами, чтобы в самом начале лучше настроить среду отлаживания.
Ключи командной строки, описанные здесь, предназначены для охвата различных ситуаций; в дейтсвительности, в некоторых средах часть этих ключей может быть недоступна.
Чаще всего GDB вызывается с одним аргументом, который определяет исполняемую программу:
gdb программа Вы также можете указать при старте как исполняемую программу, так и файл дампа памяти:
gdb программа дамп Если вы хотите отладить выполняющийся в данный момент процесс, то вместо этого, вы можете указать вторым аргументом идентификатор этого процесса:
gdb программа присоединит GDB к процессу 1234 (если, конечно, у вас нет файла с именем ‘1234’, GDB сначала проверяет наличие файла дампа памяти).
Преимущества, которые можно получить при использовании второго аргумента командной строки, требуют наличия достаточно совершенной операционной системы; если вы используете GDB как удаленный отладчик, присоединенный к компьютеру без операционной системы, там вообще может не быть понятия “процесса”, и часто нет никакого способа получить дамп. GDB предупредит вас, если ему не удается присоединиться к процессу или считать файл дампа памяти.
Вы можете запустить gdb без вывода начального сообщения, описывающего отсутствие гарантии на него, указав -silent:
gdb -silent Кроме того, вы можете контролировать процесс запуска GDB с помощью ключей командной строки. GDB может сам напомнить вам о доступных ключах.
Введите чтобы вывести на экран все доступные опции с кратким описанием их использования (сокращенный эквивалент—‘gdb -h’).
Все заданные вами ключи и параметры командной строки обрабатываются последовательно. Порядок становится важным при использовании ключа ‘-x’.
2.1.1 Выбор файлов При запуске, GDB считывает параметры, отличные от ключей, как указатели на исполняемую программу и файл дампа (или идентификатор процесса), точно так же, как если бы эти параметры задавались ключами ‘-se’ и ‘-c’ соответственно. (GDB считает первый параметр, не имеющий соответствующего флага ключа, эквивалентом ключа ‘-se’, за которым следует этот параметр; а второй параметр, не имеющий соответствующего флага ключа, если он есть, эквивалентом ключа ‘-c’, за которым следует этот параметр.) Если GDB был сконфигурирован без включения поддержки файлов дампа, что имеет место для большинства встроенных целей, то он выразит недовольство вторым аргументом и проигнорирует его.
Многие ключи имеют как длинную, так и краткую формы; в следующем списке приводятся обе. GDB также распознает сокращения длинных форм, не являющиеся двусмысленными. (Вы можете, по желанию, обозначать ключи с помощью ‘-’, а не ‘-’, хотя мы показываем наиболее употребляемый формат.) -symbols файл -s файл Читать таблицу символов из файла файл.
-exec файл -e файл Использовать файл как исполняемый для выполнения и исследования данных вместе с дампом памяти, когда это необходимо.
-se файл Читать таблицу символов из файла файл и использовать его как исполняемый -core файл -c файл Использовать файл как дамп памяти для исследования.
-c номер Присоединиться к процессу с идентификатором номер, также, как по команде attach (при условии, что нет файла в формате дампа памяти с именем номер;
в этом случае ‘-c’ определяет этот файл как дамп для считывания).
-command файл -x файл Выполнить команды GDB из файла файл. См. Раздел 16.3 [Командные файлы], -directory каталог -d каталог Добавить каталог к путям поиска файлов с исходными текстами.
Предупреждение: этот ключ зависит от возможностей операционной сиmapped стемы, которые реализованы не везде.
Если отображаемые в память файлы поддерживаются в вашей системе через системный вызов mmap, вы можете использовать этот ключ, чтобы GDB записывал символы из вашей программы в файл в текущем каталоге, допускающий повторное использование. Если программа, которую вы отлаживаете, называется ‘/tmp/fred’, то отображаемым символьным файлом будет ‘/tmp/fred.syms’. Последующие отладочные сеансы GDB замечают наличие этого файла и могут быстро отобразить в память символьную информацию из него, а не читать таблицу символов из выполняемого файла.
Файл ‘.syms’ специфичен для рабочей машины, на которой запускается GDB.
Он содержит точный образ внутренней символьной таблицы GDB. Он не может быть разделен между несколькими рабочими платформами.
Читать символьную таблицу каждого файла, содержащего таблицу символов, -readnow пенно по мере необходимости. Эта команда замедляет запуск, но дальнейшие операции производятся быстрее.
Ключи -mapped и -readnow обычно используются вместе, чтобы построить файл ‘.syms’, который содержит полную информацию о символах. (См. Раздел 12.1 [Команды для задания файлов], с. 105, для информации о файлах ‘.syms’.) Вот простой вызов GDB, не делающий ничего, кроме построения файла ‘.syms’ для использования в будущем:
gdb -batch -nx -mapped -readnow имя-программы 2.1.2 Выбор режимов Вы можете вызывать GDB в различных альтернативных режимах—например, в пакетном или в “тихом” режиме.
-nx Не выполнять команды ни из каких файлов инициализации (обычно назваемых ‘.gdbinit’, или ‘gdb.ini’ на PC). В нормальном режиме, GDB выполняет команды из этих файлов после обработки всех командных ключей и параметров.
См. Раздел 16.3 [Командные файлы], с. 158.
-quiet -silent “Тихий”. Не печатать вводное сообщение и информацию об авторских правах.
Эти сообщения также подавляются в пакетном режиме.
Выполняться в пакетном режиме. Выйти со значением 0 после обработки всех -batch командных файлов, заданных ключем ‘-x’ (и всех команд из инициализационных файлов, если это не запрещено ключем ‘-n’). Выйти с ненулевым значением, если во время выполнения команд GDB из командных файлов произойдет Пакетный режим может быть полезен при вызове GDB как фильтра; например, чтобы загрузить программу и запустить ее на другом компьютере. Для того, чтобы сделать это более удобным, сообщение (которое обычно выдается при завершении программы, выполняемой под управлением GDB), при выполнении в пакетном режиме не выдается.
-nowindows “Без окон”. Если GDB имеет встроенный графический интерфейс пользователя -nw (GUI), то этот ключ велит GDB использовать только интерфейс командной строки. Если GUI недоступен, этот ключ не оказывает никакого действия.
-windows Если GDB включает GUI, этот ключ требует использовать его, если только -cd каталог Запустить GDB, используя в качестве рабочего каталога каталог, вместо текущего.
-fullname gnu Emacs устанавливает этот ключ, когда вызывает GDB как подпроцесс.
Это велит GDB выводить полное имя файла и номер строки в стандартном, распознаваемом стиле всякий раз, когда отображается кадр стека (что включает каждую остановку вашей программы). Этот распознаваемый формат выглядит как два знака ‘\032’, за которыми следует имя файла, номер строки и символьная позиция, разделенные двоеточиями, и знак новой строки. Программа интерфейса Emacs-GDB использует два знака ‘\032’ как сигнал для отображения исходного текста для кадра.
Интерфейс Emacs-GDB Epoch устанавливает этот ключ, когда вызывает GDB -epoch как подпроцесс. Это велит GDB изменить свои подпрограммы печати так, чтобы позволить Epoch отображать значения выражений в отдельном окне.
-annotate уровень Этот ключ устанавливает уровень примечаний внутри GDB. Его эффект аналогичен использованию ‘set annotate уровень’ (см. Глава 18 [Примечания], с. 163). Уровень примечаний контролирует, какое количество информации GDB выводит вместе с приглашением, значениями выражений, строками исходного текста и другими типами вывода. Уровень 0 является обычным, уровень 1 используется, когда GDB выполняется как подпроцесс gnu Emacs, уровень 2 выводит максимальное количество примечаний и подходит для программ, которые управляют GDB.
Использовать асинхронный цикл событий для интерфейса командной строки.
-async GDB обрабатывает все события, такие как ввод пользователя с клавиатуры, через специальный цикл событий. Это позволяет GDB принимать и обрабатывать команды пользователя параллельно с выполнением отлаживаемого процесса1, так что вы не должны ждать возвращения управления GDB, прежде чем ввести следующую команду. (Замечание: в версии 5.0, асинхронное выполнение на целевой системе еще не поддерживается, так что режим ‘-async’ Когда стандартный ввод соединен с терминальным устройством, GDB по умолчанию использует асинхронный цикл событий, если это не отключено ключем Отключить асинхронный цикл событий для интерфейса командной строки.
-noasync -baud бод-в-сек -b бод-в-сек Устанавливает скорость линии (скорость в бодах, или в битах в секунду) любого последовательного интерфейса, используемого GDB для удаленной отладки.
-tty устройство -t устройство Запуститься, используя устройство для стандартного ввода и вывода вашей -interpreter интерп Использовать интерпретатор интерп к качестве интерфейса с управляющей программой или устройством. Подразумевается, что этот ключ должет устанавливаться программами, которые взаимодействуют с GDB, используя его как выходной буфер. Например, ‘-interpreter=mi’ велит GDB использовать интерфейс gdbmi (см. Глава 19 [Интерфейс gdb/mi], с. 171).
Открыть выполняемый файл и файл дампа памяти как для чтения, так и для -write записи. Это эквивалентно команде GDB ‘set write on’ (см. Раздел 11.6 [Внесение изменений], с. 104).
-statistics Этот ключ велит GDB печатать статистику о времени и использовании памяти после завершения каждой команды и возврата к приглашению.
GDB, собранный со средствами djgpp для MS-DOS/MS-Windows, поддерживает этот режим функционирования, но цикл событий приостанавливается, когда выполняется отлаживаемая программа.
Этот ключ велит GDB напечатать номер своей версии и объявление об отсутversion ствии гарантий, и затем завершиться.
2.2 Выход из GDB quit [выражение] Чтобы выйти из GDB, используйте команду quit (сокращенно q), или введите знак конца файла (обычно C-d). Если вы не укажете выражение, GDB закончит работу нормально; в противном случае, он использует результат выражения Прерывание (часто C-c) не приводит к выходу из GDB, а завершает любую выполняющуюся команду и возвращает вас на командный уровень. Вы можете безопасно пользоваться прерыванием в любое время, потому что GDB не позволяет ему вступить в силу до того, как это станет безопасным.
Если вы использовали GDB для управления присоединенным процессом или устройством, вы можете освободить его командой detach (см. Раздел 4.7 [Отладка запущенного ранее процесса], с. 25).
2.3 Команды оболочки Если вам случайно потребовалось выполнить команды оболочки в течение сеанса отладки, нет смысла приостанавливать или покидать GDB; вам достаточно воспользоваться командой shell.
shell командная строка Вызвать стандартную оболочку для выполнения командной строки. Переменная окружения SHELL, если она существует, определяет, какую оболочку запустить. В противном случае, GDB использует оболочку по умолчанию (‘/bin/sh’ в системах Unix, ‘COMMAND.COM’ в MS-DOS, и так далее).
В средах разработки часто бывает необходимо воспользоваться утилитой make. Для этой цели вам не обязательно пользоваться командой shell в GDB:
make make-арг Выполнить программу make с указанными аргументами. Это эквивалентно 14 Отладка с помощью GDB 3 Команды GDB Вы можете сокращать команды GDB по нескольким первым символам имени команды, если это сокращение однозначно; и вы можете повторять определенные команды GDB простым нажатием RET. Вы также можете использовать клавишу TAB для того, чтобы GDB сам дополнил остаток слова в команде (или показал вам возможные альтернативы, если существует несколько вариантов).
3.1 Синтаксис команд Команда GDB представляет собой одну строку ввода. Никаких ограничений на ее длину нет. Она начинается именем команды, за которым следуют параметры, значение которых определяется ее названием. Например, команда step допускает в качестве параметра число шагов, как в ‘step 5’. Вы также можете использовать команду step и без параметров.
Некоторые команды не допускают никаких параметров.
Названия команд GDB всегда могут быть сокращены, если это сокращение однозначно. Другие возможные сокращения команд перечислены в документации по отдельным командам. В некоторых случаях, допускаются даже неоднозначные сокращения; напрмер, s специально определено как эквивалент step, даже если существуют другие команды, чьи названия начинаются на s. Вы можете проверить сокращения, задавая их как параметр для команды help.
Введенная пустая строка (просто нажатие RET ), означает повтор предыдущей команды. Определенные команды (например, run) не повторяются таким способом; это те команды, непреднамеренное повторение которых может вызвать проблемы и которые вы вряд ли захотите повторять.
Команды list и x, при их повторе нажатием RET, вместо точного повтора создают новые параметры. Это позволяет легко просматривать исходный текст или память.
GDB может также использовать RET по-другому: для разделения длинного вывода, аналогично обычной утилите more (см. Раздел 15.4 [Размер экрана], с. 153). Так как в такой ситуации легко нажать RET слишком много раз, GDB блокирует повтор после любой команды, генерирующей такой тип вывода.
Любой текст, расположенный от # до конца строки является комментарием; он ничего не делает. В основном, это полезно в командных файлах (см. Раздел 16.3 [Командные файлы], с. 158).
3.2 Завершение команд GDB может дополнить за вас окончание слова в команде, если существует только один вариант; он также может в любой момент показать, какие завершения возможны для следующего слова в команде. Это работает для команд и подкоманд GDB, а также для имен символов в вашей программе.
Нажмите TAB в любой момент, когда захотите, чтобы GDB дополнил оставшуюся часть слова. Если существует только одна возможность, GDB дополняет слово и ждет, пока вы закончите команду (или нажмете RET, чтобы ввести ее). Например, если вы введете (gdb) info bre TAB GDB дополнит остаток слова ‘breakpoints’, так как у команды info есть единственная подкоманда, начинающаяся с ‘bre’:
(gdb) info breakpoints Теперь вы можете нажать либо RET, чтобы выполнить команду info breakpoints, либо удалить часть символов и ввести что-то другое, если ‘breakpoints’ не является той командой, которую вы ожидали. (Если вы с самого начала были уверены, что хотите info breakpoints, вы также могли просто нажать RET, сразу после ‘info bre’, использовав сокращение команды вместо завершения).
Если при нажатии TAB существует несколько вариантов для следующего слова, GDB издает звук. Вы можете либо ввести больше символов и попробовать снова, либо нажать TAB второй раз; GDB выведет все возможные завершения для этого слова. Например, вы можете захотеть установить точку останова на подпрограмме, чье имя начинается с ‘make_’, но когда вы вводите b make_ TAB, GDB лишь издает звук. Повторное нажатие TAB отображает все имена функций в вашей программе, начинающиеся с этих символов.
Например:
GDB издает звук; нажав TAB еще раз, видим:
make_a_section_from_file make_environ После отображения возможных вариантов, GDB копирует ваш частичный ввод (‘b make_’ в этом примере), так что вы можете закончить команду.
Если вы сначала хотите только увидеть список альтернатив, вы можете нажать M-?, а не нажимать TAB дважды. M-? означает META ?. Вы можете ввести это либо удерживая клавишу, обозначенную на вашей клавиатуре как META (если такая есть), и нажать ?, или как ESC, за которой следует ?.
Иногда нужная вам строка, являясь логически “словом”, может содержать скобки или другие символы, которые GDB обычно исключает из своего понятия о слове. Чтобы позволить завершению слов работать в такой ситуации, вы можете заключить слова в командах GDB в ’ (знаки одинарных кавычек).
Наиболее вероятная ситуация, где вам это может потребоваться, это при вводе имени функции в Си++. Это происходит потому, что Си++ допускает перегрузку функций (множественные определения одной и той же функции, различающиеся типом параметров). Например, когда вы хотите установить точку останова, вам может потребоваться различать, имеете вы в виду версию name с параметром целого типа, name(int), или же версию с параметром вещественного типа, name(float). Для использования возможностей завершения слов в такой ситуации, введите одинарную кавычку ’ в начале имени функции. Это предупреждает GDB, что ему может потребоваться принять во внимание больше информации, чем обычно, когда вы нажимаете TAB или M-? для запроса завершения слова:
(gdb) b ’bubble( M-?
bubble(double,double) bubble(int,int) (gdb) b ’bubble( В некоторых случаях, GDB может сам определить, что завершение имени требует использования кавычек. Когда это происходит, GDB вставляет кавычку за вас (выполняя завершение на столько, на сколько это возможно), если вы не ввели ее в первой позиции:
GDB изменяет вашу строку ввода на следующую, и издает звук:
(gdb) b ’bubble( Вообще, GDB может определить, что кавычка нужна (и вставляет ее), если вы запрашиваете завершение перегруженного символа до того, как начали вводить список параметров.
Для большей информации о перегруженных функциях, смотрите Раздел 9.4.1.3 [Выражения Си++], с. 84. Вы можете использовать команду set overload-resolution off для отключения распознавания перегруженных символов; смотрите Раздел 9.4.1.7 [Возможности GDB для Си++], с. 85.
3.3 Получение справки Используя команду help, вы всегда можете запросить информацию о командах у самого GDB.
help Вы можете использовать help (сокращенно h) без параметров, для отображения короткого списка именованных классов команд:
breakpoints - Making program stop at certain points tracepoints - Tracing of program execution without Command name abbreviations are allowed if unambiguous.
help класс Используя один из общих классов справки как параметр, вы можете получить список отдельных команд этого класса. Вот, например, отображение справки Command name abbreviations are allowed if unambiguous.
help команда Если указать имя команды в качестве параметра help, GDB выведет короткую справку о том, как ей пользоваться.
apropos арг Команда apropos арг производит поиск по регулярному выражению, заданному в арг, во всех командах GDB и их документации. Она выводит все найденные совпадения. Например:
set symbol-reloading - Set dynamic symbol table reloading show symbol-reloading - Show dynamic symbol table reloading complete арг Команда complete арг перечисляет все возможные завершения для начала команды. Используйте арг для задания начала команды, которую вы хотите завершить. Например, Это предназначено для использования gnu Emacs.
В дополнение к help, вы можете использовать команды GDB info и show для получения информации о состоянии вашей программы, или о состоянии самого GDB. Каждая команда поддерживает много тем запросов; это руководство описывает каждую тему в соответствующем месте. Списки в разделах info и show в Алфавитном указателе указывают на все подкоманды. См. [Алфавитный указатель], с. 253.
Эта команда (сокращенно i) предназначена для описания состояния вашей проinfo граммы. Например, вы можете с помощью info args просмотреть аргументы, переданные вашей программе, с помощью info registers перечислить используемые в настоящий момент регистры, или используя info breakpoints вывести установленные вами точки останова. Вы можете получить полный список подкоманд команды info с помощью help info.
Вы можете присвоить переменной среды результат выражения с помощью set.
set Например, вы можете установить приглашение GDB в знак $ используя set В отличие от info, команда show предназначена для описания состояния саshow мого GDB. Вы можете изменить почти все, что показывает show, используя соответствующую команду set. Например, командой set radix вы можете задать, какую систему счисления использовать для вывода, или просто узнать, какая система используется в данный момент с помощью команды show radix.
Для отображения всех устанавливаемых параметров и их текущих значений, вы можете использовать show без аргументов; также можно использовать info set. Обе команды приводят к одинаковому результату.
Вот три разнообразные подкоманды show, которые не имеют соответствующих setкоманд:
show version Показывает, какая версия GDB запущена. Вам следует включать эту информацию в отчеты об ошибках в GDB. Если вы используете несколько версий GDB, вам может потребоваться определить, какая из них запущена; по мере развития отладчика появляются новые команды, а старые могут исчезнуть. Кроме того, многие распространители операционных систем поставляют модифицированные версии GDB, также существуют модифицированные версии GDB в gnu/Linux. Номер версии—это номер, появляющийся при старте.
show copying Выводит информацию о правах на распространение GDB.
show warranty Отображает заявление gnu об отсутствии гарантий, или гарантии, если ваша версия GDB поставляется с гарантиями.
20 Отладка с помощью GDB 4 Выполнение программ под управлением GDB Прежде чем выполнять программу под управлением GDB, при компиляции вы должны сгенерировать отладочную информацию.
Вы можете запустить GDB с параметрами или без, в любой среде по вашему выбору.
Если вы отлаживаете программу на той же машине, на которой выполняется GDB, вы можете перенаправить ввод и вывод вашей программы, отлаживать уже выполняющийся процесс, или убить дочерний процесс.
4.1 Компиляция для отладки Для эффективной отладки программы, при компиляции вы должны сгенерировать отладочную информацию. Эта отладочная информация сохраняется в объектном файле; она описывает тип данных каждой переменной или функции, и соответствие между номерами строк исходного текста и адресами в выполняемом коде.
Чтобы запросить генерацию отладочной информации, укажите ключ ‘-g’ при вызове компилятора.
Многие компиляторы Си не могут обрабатывать ключи ‘-g’ и ‘-O’ вместе. Используя такие компиляторы, вы не можете создавать оптимизированные выполняемые файлы, содержащие отладочную информацию.
GCC, gnu компилятор Си, поддерживает ‘-g’ с или без ‘-O’, делая возможным отладку оптимизированного кода. Мы рекомендуем, чтобы вы всегда использовали ‘-g’ при компиляции программ. Вы можете думать, что ваша программа правильная, но нет никакого смысла испытывать удачу.
Когда вы отлаживаете программу, откомпилированную с ‘-g -O’, помните, что оптимизатор перестраивает ваш код; отладчик же показывает то, что там находится в действительности. Не удивляйтесь, если порядок выполнения не будет в точности соответствовать вашему исходному файлу! Крайний пример: если вы определяете переменную, но нигде ее не используете, GDB никогда не увидит этой переменной, потому что при оптимизации компилятор ее исключит.
Некоторые вещи не работают с ‘-g -O’ также, как просто с ‘-g’, в частности, на машинах с планированием инструкций. Если сомневаетесь, перекомпилируйте с одним ключем ‘-g’, и если это устранит проблему, пожалуйста, сообщите нам об этом как об ошибке (включите тестовый пример!).
Ранние версии компилятора gnu Си допускали вариант ключа для отладочной информации ‘-gg’. GDB больше не поддерживает этот формат; если этот ключ есть у вашего компилятора gnu Си, не используйте его.
4.2 Начало выполнения вашей программы run Используйте команду run для запуска вашей программы под управлением GDB. Сначала вы должны задать имя программы (кроме как на VxWorks) с параметрами GDB (см. Глава 2 [Вход и выход из GDB], с. 9), или используя команды file или exec-file (см. Раздел 12.1 [Команды для задания файлов], Если вы запускаете вашу программу в среде выполнения, поддерживающей процессы, run создает подчиненный процесс, и этот процесс выполняет вашу программу. (В средах, не поддерживающих процессы, run выполняет переход на начало вашей программы.) Выполнение программы зависит от определенной информации, которую она получает от породившего ее процесса. GDB предоставляет способы задать эту информацию, что вы должны сделать до запуска программы. (Вы можете изменить ее после старта, но такие изменения воздействуют на вашу программу только при следующем запуске.) Эта информация может быть разделена на четыре категории:
Параметры.
Задайте параметры, которые нужно передать вашей программе, как параметры команды run. Если на вашей системе доступна оболочка, она используется для передачи параметров, так что при их описании вы можете использовать обычные соглашения (такие как раскрывание шаблонов или подстановка переменных). В системах Unix, вы можете контролировать, какая оболочка используется, с помощью переменной среды SHELL. См. Раздел 4.3 [Аргументы вашей Среда. Обычно ваша программа наследует свою среду от GDB, но вы можете использовать команды GDB set environment и unset environment, чтобы изменить часть настроек среды, влияющих на нее. См. Раздел 4.4 [Рабочая среда вашей Рабочий каталог.
Ваша программа наследует свой рабочий каталог от GDB. Вы можете установить рабочий каталог GDB командой cd. См. Раздел 4.5 [Рабочий каталог Стандартный ввод и вывод.
Обычно ваша программа использует те же устройства для стандартного ввода и вывода, что и GDB. Вы можете перенаправить ввод и вывод в строке команды run, или использовать команду tty, чтобы установить другое устройство для вашей программы. См. Раздел 4.6 [Ввод и вывод вашей программы], с. 24.
Предупреждение: Хотя перенаправление ввода и вывода работает, вы не можете использовать каналы для передачи выходных данных отлаживаемой программы другой программе; если вы попытаетесь это сделать, скорее всего GDB перейдет к отладке неправильной программы.
Когда вы подаете команду run, ваша программа начинает выполняться немедленно.
См. Глава 5 [Остановка и продолжение], с. 31, для обсуждения того, как остановить вашу программу. Как только ваша программа остановилась, вы можете вызывать функции вашей программы, используя команды print или call. См. Глава 8 [Исследование данных], с. 61.
Если время модификации вашего символьного файла изменилось с того момента, когда GDB последний раз считывал символы, он уничтожает свою символьную таблицу и считывает ее заново. При этом GDB старается сохранить ваши текущие точки останова.
4.3 Аргументы вашей программы Аргументы к вашей программе могут быть заданы как аргументы к команде run. Они передаются оболочке, которая раскрывает символы шаблонов и выполняет перенаправление ввода-вывода, и с того момента попадают в вашу программу. Ваша переменная среды SHELL (если она существует) определяет, какую оболочку использует GDB. Если вы не определите SHELL, он использует оболочку по умолчанию (‘/bin/sh’ в Unix).
В не-Unix системах, программу обычно запускает непосредственно GDB, который эмулирует перенаправление ввода-вывода через соответствующие системные вызовы, и символы шаблонов раскрываются кодом запуска, а не оболочкой.
run без аргументов использует те же аргументы, которые использовались предыдущей командой run, или которые установлены командой set args.
Задает аргументы, которые будут использоваться при следующем запуске ваset args шей программы. Если у set args нет аргументов, run выполняет вашу программу без аргументов. Если вы запустили вашу программу с аргументами, то единственный способ запустить ее снова без аргументов—это использовать set args до следующего запуска командой run.
show args Показать аргументы, которые будут переданы вашей программе при ее вызове.
4.4 Рабочая среда вашей программы Среда состоит из набора переменных среды и их значений. Переменные среды обычно хранят такие данные, как ваше имя пользователя, домашний каталог, тип терминала и путь поиска для запуска программ. Как правило, вы устанавливаете переменные среды с помощью оболочки и они наследуются всеми другими программами, которые вы вызываете. При отладке может оказаться полезным попробовать запустить программу в измененной среде, не перезапуская GDB.
path каталог Добавить каталог в начало переменной среды PATH (пути поиска выполняемых файлов), как для GDB, так и для вашей программы. Вы можете указать названия нескольких каталогов, разделив их пробелом или системно-зависимым разделителем (‘:’ в Unix, ‘;’ в MS-DOS и MS-Windows). Если каталог уже находится в списке путей, он переносится в начало, так что поиск в нем будет производиться раньше.
Вы можете использовать строку ‘cwd’, чтобы сослаться на рабочий каталог, который является текущим в тот момент, когда GDB производит поиск. Если вместо этого вы используете ‘.’, то она будет указывать на тот каталог, в котором вы выполнили команду path. GDB заменяет ‘.’ в аргументе каталог (на текущий путь) до добавления каталога к списку путей поиска.
show paths Отобразить список путей для поиска выполняемых файлов (переменную среды show environment [имя-перем] Вывести значение переменной среды имя-перем, которое будет передано вашей программе при ее старте. Если вы не указываете имя-перем, вывести названия и значения всех переменных среды, передаваемых вашей программе. Вы можете сократить environment как env.
set environment имя-перем [=значение] Присваивает значение переменной среды имя-перем. Значение меняется только для вашей программы, но не для самого GDB. значение может быть любой строкой; значениями переменных среды являются просто строки, а их интерпретацию обеспечивает ваша программа. Параметр значение является необязательным; если он опущен, переменная устанавливается в пустое значение.
говорит отлаживаемой программе, что при последующих запусках именем пользователя является ‘foo’. (Пробелы, окружающие ‘=’, использованы здесь для ясности; в действительности, они не обязательны.) unset environment имя-перем Удалить переменную имя-перем из среды, передаваемой вашей программе. Это отличается от ‘set env имя-перем =’; unset environment удаляет переменную из среды, а не присваивает ей пустое значение.
Предупреждение: В системах Unix, GDB вызывает вашу программу, используя оболочку, указанную вашей переменной среды SHELL, если она определена (или /bin/sh, если не определена). Если ваша переменная SHELL указывает на оболочку, которая выполняет файл инициализации—такой как ‘.cshrc’ для оболочки C-shell, или ‘.bashrc’ для BASH—любая переменная, которую вы установите в этом файле, воздействует на вашу программу. В этой связи, вы можете захотеть перенести установку переменных среды в файлы, которые выполняются только при вашем входе в систему, такие как ‘.login’ или ‘.profile’.
4.5 Рабочий каталог вашей программы Каждый раз, когда вы запускаете свою программу командой run, она наследует рабочий каталог от текущего рабочего каталога GDB. В начальный момент, рабочий каталог GDB наследуется от его родительского процесса (обычно оболочки), но вы можете задать новый рабочий каталог командой cd из GDB.
Рабочий каталог GDB также служит каталогом по умолчанию для команд отладчика, определяющих действия с файлами. См. Раздел 12.1 [Команды для задания файлов], с. 105.
cd каталог Установить рабочий каталог GDB в каталог.
pwd 4.6 Ввод и вывод вашей программы По умолчанию, программа, которую вы запускаете под управлением GDB, осуществляет ввод и вывод на тот же терминал, что и GDB. Для взаимодействия с вами, GDB переключает терминал в свой собственный терминальный режим, но он записывает терминальные режимы, которые использовала ваша программа, и переключается назад к ним, когда вы продолжаете выполнение программы.
info terminal Отображает информацию, записанную GDB о терминальных режимах, которые использует ваша программа.
Вы можете перенаправить ввод и/или вывод вашей программы, используя перенаправление оболочки с помощью команды run. Например, run > выходной-файл запускает вашу программу, перенаправляя ее вывод в ‘выходной-файл’.
Другой способ задать, как ваша программа должна осуществлять ввод и вывод— использовать команду tty. Эта команда принимает в качестве агрумента имя файла, который будет использоваться по умолчанию для будущих команд run. Эта команда также сбрасывает управляющий терминал для дочернего процесса для будущих команд run.
Например, tty /dev/ttyb указывает, что процессы, запущенные последующими командами run, для ввода и вывода используют по умолчанию терминал ‘/dev/ttyb’, и что он будет их управляющим терминалом.
Явное перенаправление в run замещает эффект команды tty для устройств вводавывода, но не ее воздействие на управляющий терминал.
Когда вы используете команду tty или перенаправляете ввод в команде run, изменяется только ввод для вашей программы. Ввод для GDB по прежнему происходит через ваш терминал.
4.7 Отладка запущенного ранее процесса attach идент-процесса Эта команда присоединяется к выполняющемуся процессу—процессу, который был запущен вне GDB. (Команда info files показывает ваши активные цели.) В качестве аргумента команда получает идентификатор процесса. Обычный способ узнать идентификатор Unix-процесса—воспользоваться утилитой ps или командой оболочки ‘jobs -l’.
attach не повторяется, если вы нажмете RET второй раз после выполнения Чтобы использовать attach, ваша программа должна выполняться в среде, поддерживающей процессы; например, attach не работает на специальных машинах, не имеющих операционной системы. Вы также должны обладать полномочиями для посылки сигнала процессу.
Когда вы используете attach, отладчик находит программу выполняющегося процесса, производя поиск сперва в текущем рабочем каталоге, а затем (если программа не найдена), используя пути поиска исходных файлов (см. Раздел 7.3 [Определение каталогов с исходными файлами], с. 57). Также, для загрузки программы вы можете использовать команду file. См. Раздел 12.1 [Команды для задания файлов], с. 105.
Первое, что GDB делает после подготовки указанного процесса к отладке— останавливает его. Вы можете исследовать и изменять присоединенный процесс всеми командами GDB, которые обычно доступны, когда вы запускаете процессы с помощью Вы можете устанавливать точки останова; вы можете пошагово выполнять run.
программу и продолжить ее обычное выполнение, вы можете изменять области данных.
Если вы решите продолжить выполнение процесса после присоединения к нему GDB, вы можете использовать команду continue.
Когда вы закончили отлаживать присоединенный процесс, для его освобождеdetach ния из под управления GDB вы можете использовать команду detach. Отсоединение процесса продолжает его выполнение. После команды detach, этот процесс и GDB снова становятся совершенно независимыми, и вы готовы присоединить или запустить с помощью run другой процесс. detach не повторяется, если вы нажмете RET еще раз после выполнения команды.
Если вы выйдете из GDB или используете команду run, пока у вас есть присоединенный процесс, вы убьете этот процесс. По умолчанию, GDB запрашивает подтверждение, если вы пытаетесь сделать одну из этих вещей; вы можете контролировать, нужно вам это подтверждение или нет, используя команду set confirm (см. Раздел 15.6 [Необязательные предупреждения и сообщения], с. 154).
4.8 Уничтожение дочернего процесса Уничтожить дочерний процесс, в котором ваша программа выполняется под kill Эта команда полезна, если вы хотите отладить дамп памяти, а не выполняющийся процесс. GDB игнорирует любые дампы памяти, пока ваша программа выполняется.
В некоторых операционных системах, программа не может быть выполнена вне GDB, пока у вас есть в ней точки останова, установленные отладчиком. В этой ситуации вы можете использовать команду kill, чтобы разрешить выполнение вашей программы вне отладчика.
Команда kill также полезна, если вы хотите перекомпилировать и перекомпоновать вашу программу, так как во многих системах невозможно модифицировать исполняемый файл во время выполнения процесса. В этом случае, когда вы в следующий раз введете run, GDB заметит, что файл изменился, и заново прочитает символьную таблицу (стараясь при этом сохранить ваши точки останова).
4.9 Отладка программ с несколькими нитями В некоторых операционных системах, таких как HP-UX и Solaris, одна программа может иметь несколько нитей выполнения. Точная семантика нитей меняется от одной операционной системы к другой, но в общем, нити одной программы сродни нескольким процессам—за исключением того, что они разделяют одно адресное пространство (то есть, все они могут исследовать и модифицировать одни и те же переменные). С другой стороны, каждая нить имеет свои собственные регистры и стек выполнения, и, возможно, свои собственные участки памяти.
GDB предоставляет следующие возможности для отладки многонитевых программ:
• автоматическое уведомление о новых нитях • ‘thread номер-нити’, команда для переключения между нитями • ‘info threads’, команда для запроса информации о существующих нитях • ‘thread apply [номер-нити] [all] арг’, команда для применения некоторой команды к списку нитей • точки останова, определяемые отдельно для каждой нити Предупреждение: Эти возможности доступны еще не в любой конфигурации GDB, где операционная система поддерживает нити. Если ваш GDB не поддерживает нити, эти команды не имеют эффекта. Например, в системах без поддержки нитей, GDB ничего не выводит на команду ‘info threads’, и всегда отвергает команду thread, как в этом примере:
Thread ID 1 not known. Use the "info threads" command to see the IDs of currently known threads. Возможности отладки нитей GDB позволяют вам наблюдать все нити во время выполнения вашей программы, но когда управление переходит к GDB, одна конкретная нить выделяется для отладки. Она называется текущей нитью. Отладочные команды показывают информацию о программе с точки зрения текущей нити.
Когда GDB обнаруживает новую нить в вашей программе, он выводит для нее идентификатор на целевой системе с сообщением в форме ‘[New сист-тег]’. Сист-тег является идентификатором нити, чья форма различается в зависимости от конкретной системы.
Например, в LynxOS вы можете увидеть [New process 35 thread 27] когда GDB замечает новую нить. Напротив, в системе SGI, сист-тег выглядит просто как ‘process 368’, без дополнительных спецификаций.
Для отладочных целей, GDB присваивает свои собственные номера нитей—всегда в виде одного целого числа—каждой нити в вашей программе.
info threads Вывести краткую информацию обо всех имеющихся в данный момент в вашей программе нитях. Для каждой нити, GDB отображает (в этом порядке):
Нить с идентификатором 1 неизвестна. Используйте команду "info threads", чтобы получить идентификаторы известных нитей. (Прим. переводчика) 1. номер нити, назначенный GDB 2. идентификатор нити на целевой системе (сист-тег) 3. краткие сведения о текущем кадре стека для этой нити Звездочка ‘*’ слева от номера нити GDB обозначает текущую нить.
(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) В системах HP-UX:
Для отладочных целей, GDB присваивает свои собственные номера нитей—небольшие целые, присваиваемые в порядке создания нитей— каждой нити в вашей программе.
Когда GDB обнаруживает новую нить в вашей программе, он выводит как номер нити, присвоенный GDB, так и идентификатор на целевой системе для нити с сообщением в форме ‘[New сист-тег]’. сист-тег является идентификатором нити, чья форма различается в зависимости от конкретной системы. Например, в HP-UX, когда GDB замечает новую нить, вы увидите [New thread 2 (system thread 26594)] info threads Вывести краткую информацию обо всех имеющихся в данный момент в вашей программе нитях. Для каждой нити, GDB отображает (в этом порядке):
1. номер нити, назначенный GDB 2. идентификатор нити на целевой системе (сист-тег) 3. краткие сведения о текущем кадре стека для этой нити Звездочка ‘*’ слева от номера нити GDB означает текущую нить.
(gdb) info threads * 3 system thread 26607 worker (wptr=0x7b09c318 "@") \ 2 system thread 26606 0x7b0030d8 in ksleep () \ thread номер-нити Сделать нить с номером номер-нити текущей. Аргумент команды, номер-нити, является внутренним номером нити GDB, который показан в первом поле ‘info threads’. GDB отвечает, выводя системный идентификатор выбранной вами Также как и с сообщением ‘[New...]’, форма текста после ‘Switching to’ зависит от соглашений для идентификации нитей в вашей системе.
threads apply [номер-нити] [all] арг Команда thread apply позволяет вам применить команду к одной или нескольким нитям. Задайте номера нитей, на которые вы хотите воздействовать, в аргументе номер-нити. Номер-нити—это внутренний номер нити GDB, который показан в первом поле ‘info threads’. Чтобы применить команду ко всем нитям, используйте thread apply all арг.
Когда GDB останавливает вашу программу, вследствие точки останова или по сигналу, он автоматически выбирает нить, в которой появилась точка останова или сигнал. GDB предупреждает вас о переключении контекста сообщением в форме ‘[Switching to систтег]’ для идентификации нити.
См. Раздел 5.4 [Остановка и запуск многонитевых программ], с. 48, для дополнительной информации о поведении GDB, когда вы останавливаете и запускаете многонитевую программу.
См. Раздел 5.1.2 [Установка точек наблюдения], с. 35, для информации о точках наблюдения в многонитевых программах.
4.10 Отладка многонитевых программ В большинстве систем, GDB не имеет специальной поддержки для отладки программ, создающих дополнительные процессы с помощью функции fork. Когда программа вызывает fork, GDB будет продолжать отладку родительского процесса, а дочерний процесс будет выполняться беспрепятственно. Если выполнение дочернего процесса дойдет до места, где вы установили точку останова, дочерний процесс получит сигнал SIGTRAP, который приведет к остановке процесса (если он не перехватывает этот сигнал).
Однако, если вы хотите отладить дочерний процесс, существует достаточно простое решение. Поместите вызов sleep в код программы, который дочерний процесс выполнит после fork. Может быть удобным вызывать sleep только если установлена определенная переменная среды или если существует определенный файл, так что задержка не будет происходить, если вы не захотите отлаживать дочерний процесс. Пока дочерний процесс спит, используйте программу ps для получения ее идентификатора процесса. Затем укажите GDB (новому экземпляру GDB, если вы отлаживаете также и родительский процесс) присоединиться к дочернему процессу (см. Раздел 4.7 [Присоединение], с. 25). Начиная с этого момента, вы можете отлаживать дочерний процесс точно также, как любой другой процесс, к которому вы присоединились.
В системе HP-UX (только в версиях 11.x и более поздних?) GDB предоставляет средства для отладки программ, которые создают дополнительные процессы, используя функции fork или vfork.
По умолчанию, когда программа ветвится, GDB будет продолжать отладку родительского процесса, а дочерний процесс будет выполняться беспрепятственно.
Если вы хотите отлаживать дочерний процесс вместо родительского, используйте команду set follow-fork-mode.
set follow-fork-mode режим Устанавливает реакцию отладчика на вызов fork или vfork в программе. Вызов fork или vfork создает новый процесс. режим может быть:
После ветвления отлаживается исходный процесс. Дочерний проparent цесс выполняется беспрепятственно. Это поведение по умолчанию.
После ветвления отлаживается новый процесс. Родительский проchild 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 [Установка точек перехвата], с. 37.
30 Отладка с помощью GDB 5 Остановка и продолжение исполнения Основные цели применения отладчика—остановка вашей программы до ее завершения, или чтобы в случае нарушений в работе вашей программы вы могли выяснить их причину.
Внутри GDB ваша программа может остановиться по нескольким причинам, таким как сигнал, точка останова, или достижение новой строки после команды GDB, такой как step.
Затем вы можете исследовать и изменять значения переменных, устанавливать новые точки останова и удалять старые, и затем продолжить выполнение. Обычно, выводимые GDB сообщения предоставляют достаточную информацию о состоянии вашей программы, но вы также можете запросить эту информацию явно в любое время.
info program Отобразить информацию о состоянии вашей программы: выполняется она или нет, каким процессом она является и почему остановлена.
5.1 Точки останова, точки наблюдения и точки перехвата Точка останова останавливает вашу программу всякий раз, когда ее выполнение достигает определенной точки. Для каждой точки останова вы можете добавлять условия для лучшего управления условиями остановки. Вы можете устанавливать точки останова командой break и ее вариантами (см. Раздел 5.1.1 [Установка точек останова], с. 32), чтобы задать место, где должна остановиться ваша программа, по номеру строки, имени функции или точному адресу.
В конфигурациях HP-UX, SunOS 4.x, SVR4 и Alpha OSF/1, вы можете устанавливать точки останова в разделяемых библиотеках до запуска выполняемого файла. В системах HP-UX существует небольшое ограничение: вы должны подождать, пока программа не перестанет выполняться, для установки точек останова в подпрограммах из разделяемой библиотеки, которые не вызываются напрямую из программы (например, подпрограммах, являющихся аргументами вызова pthread_create).
Точка наблюдения—это специальная точка останова, которая останавливает вашу программу при изменении значения выражения. Вы должны использовать другую команду для установки точки наблюдения (см. Раздел 5.1.2 [Установка точек наблюдения], с. 35), но помимо этого, вы можете обращаться с ней так же, как с любой другой точкой останова: вы включаете, отключаете и удаляете точки останова и точки наблюдения при помощи одних и тех же команд.
Вы можете установить, что значения из вашей программы должны отображаться автоматически, когда GDB останавливается в точке останова. См. Раздел 8.6 [Автоматическое отображение], с. 66.
Точка перехвата—это другая специализированная точка останова, которая останавливает вашу программу при возникновении события определенного типа, такого как выбрасывание исключения в Си++ или загрузка библиотеки. Также как с точками наблюдения, вы используете другую команду для установки точки перехвата, (см. Раздел 5.1.3 [Установка точек перехвата], с. 37), но помимо этого, вы можете обращаться с ней так же, как с любой другой точкой останова. (Для остановки, когда ваша программа получает сигнал, используйте команду handle; смотрите Раздел 5.3 [Сигналы], с. 46.) Когда вы создаете точку останова, наблюдения или перехвата, GDB присваивает ей номер; эти номера являются последовательными целыми числами, начинающимися с единицы. Во многих командах для управления различными возможностями точек останова, вы используете эти номера для указания, какую точку останова вы хотите изменить. Каждая точка останова может быть включена или отключена; если точка останова отключена, она не оказывает никакого влияния на вашу программу, пока вы снова не включите ее.
Некоторые команды GDB допускают в качестве указания точек останова, на которые они действуют, их диапазоны. Диапазон точек останова—это или номер одной точки, например ‘5’, или два таких номера, в порядке увеличения, разделенные дефисом, например ‘5-7’. Когда команде задается диапазон точек останова, она действует на все точки останова в этом диапазоне.
5.1.1 Установка точек останова Точки останова устанавливаются командой break (сокращенно b). Вспомогательная переменная отладчика ‘$bpnum’ хранит номер последней установленной вами точки останова;
смотрите Раздел 8.9 [Вспомогательные переменные], с. 73, для обсуждения того, что вы можете делать со вспомогательными переменными.
Вы можете задавать место для установки новой точки останова несколькими способами.
break функция Установить точку останова на входе в функцию функция. При использовании языков, допускающих перегрузку символов, таких как Си++, функция может ссылаться более чем на одно возможное место останова. См. Раздел 5.1. [Меню точки останова], с. 42, для обсуждения такой ситуации.
break +смещение break -смещение Установить точку останова через несколько строк впереди или сзади от позиции, на которой выполнение остановилось в текущем выбранном кадре стека.
(См. Раздел 6.1 [Кадры стека], с. 51, для описания кадров стека.) break номер-строки Установить точку останова на строке номер-строки в текущем исходном файле.
Текущий исходный файл—это файл, исходный текст которого отображался последним. Точка останова остановит вашу программу сразу перед выполнением какого-либо кода на этой строке.
break имя-файла:номер-строки Установить точку останова на строке номер-строки в исходном файле имяфайла.
break имя-файла:функция Установить точку останова на входе в функцию, находящуюся в файле имяфайла. Указание имени файла вместе с именем функции является излишним, за исключением ситуаций, когда несколько файлов содержат одинаково названные break *адрес Установить точку останова по адресу адрес. Вы можете использовать это для установки точек останова в тех частях вашей программы, которые не имеют отладочной информации или исходных файлов.
При вызове без аргументов, break устанавливает точку останова на инструкbreak ции, которая должна быть выполнена следующей в выбранном кадре стека (см.
Глава 6 [Исследование стека], с. 51). В любом выбранном кадре, кроме самого внутреннего, это останавливает вашу программу, как только управление возвращается в этот кадр. Это похоже на результат команды finish в кадре внутри выбранного кадра—за исключением того, что finish не оставляет активной точки останова. Если вы используете break без аргументов в самом внутреннем кадре, GDB останавливается, когда в следующий раз достигает текущего места; это может быть полезно внутри циклов.
Обычно GDB игнорирует точки останова, когда он возобновляет выполнение, пока не будет выполнена хотя бы одна инструкция. Если бы он этого не делал, вы не могли бы продолжать выполнение после точки останова, не отключив сперва эту точку останова. Это правило применяется вне зависимости от того, существовала или нет точка останова, когда ваша программа остановилась.
break... if усл Установить точку останова с условием усл; каждый раз, когда достигается точка останова, происходит вычисление выражения усл, и остановка происходит только если эта величина не равна нулю—то есть, если усл истинно. ‘...’ означает один из возможных аргументов, перечисленных выше (или отсутствие аргументов), описывающих место остановки. См. Раздел 5.1.6 [Условия остановки], с. 40, для большей информации об условных точках останова.
tbreak арг Установить точку останова только до первой активизации. Аргументы арг такие же, как для команды break, и точка останова устанавливается аналогичным образом, но она автоматически уничтожается после того, как ваша программа первый раз на ней остановится. См. Раздел 5.1.5 [Отключение hbreak арг Установить аппаратно-поддерживаемую точку останова. Аргументы арг такие же, как и для команды break, и точка останова устанавливается аналогичным образом, но она требует аппаратной поддержки и некоторые целевые платформы могут ее не иметь. Основной целью этого является отладка кода EPROM/ROM, так что вы можете установить точку останова на инструкции без изменения инструкции. Это может быть использовано с новой генерацией ловушек, предоставляемой SPARClite DSU и некоторыми машинами на базе x86. Эти платформы будут генерировать ловушки, когда программа обращается к некоторым данным или адресу инструкции, которые назначены регистрам отладки. Однако, регистры аппаратных точек останова могут хранить ограниченное число точек останова. Например, на DSU, только две точки останова могут быть установлены одновременно, и GDB будет отвергать эту команду, если используется больше. Удалите или отключите неиспользуемые аппаратные точки останова перед установкой новых (см. Раздел 5.1.5 [Отключение точек останова], с. 39). См. Раздел 5.1.6 [Условия], с. 40.
thbreak арг Установить аппаратно-поддерживаемую точку останова, включенную только до первой активизации. Аргументы арг такие же, как и для команды hbreak, и точка останова устанавливается аналогичным образом. Однако, как в случае команды tbreak, точка останова автоматически уничтожается после того, как программа первый раз на ней остановится. Также, как и в случае команды hbreak, точка останова требует аппаратной поддержки и некоторые аппаратные платформы могут ее не иметь. См. Раздел 5.1.5 [Отключение точек останова], с. 39. Смотрите также Раздел 5.1.6 [Условия остановки], с. 40.
rbreak рег-выр Установить точки останова на всех функциях, удовлетворяющих регулярному выражению рег-выр. Эта команда устанавливает безусловные точки останова при всех совпадениях, выводя список всех установленных точек останова. После установки, они рассматриваются точно так же, как точки останова, установленные командой break. Вы можете удалять их, отключать, или делать их условными таким же способом, как любые другие точки останова.
Регулярные выражения имеют стандартный синтаксис, используемый такими средствами, как ‘grep’. Заметьте, что это отличается от синтаксиса, испольОтладка с помощью GDB зуемого оболочками; так, например, foo* подходит для всех функций, которые включают fo, за которым следует любое число букв o. Существует неявное.* в начале и в конце введенного вами регулярного выражения, так что для нахождения только тех функций, которые начинаются на foo, используйте ^foo.
При отладке программ, написанных на Си++, rbreak полезна для установки точек останова на перегруженных функциях, не являющихся членами никакого специального класса.
info breakpoints [n] info break [n] info watchpoints [n] Вывести таблицу всех установленных и не удаленных точек останова, наблюдения и перехвата, со следующими колонками для каждой точки:
Тип Точка останова, наблюдения или перехвата.
План Помечена ли точка останова для отключения или удаления после Включенные точки останова помечаются как ‘y’. ‘n’ отмечает отключенные точки.
Адрес Адрес памяти, где расположена точка останова в вашей программе.
Где Файл и номер строки, где расположена точка останова в исходном Если точка останова условная, info break показывает условие на строке, следующей за этой точкой; команды точки останова, если они есть, перечисляются info break с номером точки останова n в качестве аргумента отображает только эту точку. Вспомогательная переменная $_ и адрес по умолчанию для исследования для команды x устанавливаются равными адресу последней из перечисленных точек останова (см. Раздел 8.5 [Исследование памяти], с. 65).
info break отображает то число раз, которое точка останова была активирована. Это особенно полезно при использовании вместе с командой ignore. Вы можете игнорировать большое число активаций точки останова, посмотреть информацию о точке останова чтобы узнать, сколько раз она активировалась, и затем запустить заново, игнорируя на единицу меньше, чем это число. Это быстро приведет вас к последней активации этой точки останова.
GDB позволяет вам установить любое число точек останова в одном и том же месте вашей программы. В этом нет ничего глупого или бессмысленного. Когда точки останова являются условными, это даже полезно (см. Раздел 5.1.6 [Условия останова], с. 40).
GDB сам иногда устанавливает точки останова в вашей программе для специальных целей, таких как правильная обработка longjmp (в программах на Си). Этим внутренним точкам останова присваиваются отрицательные номера, начиная с -1; ‘info breakpoints’ не отображает их.
Вы можете увидеть эти точки останова с помощью служебной команды GDB ‘maint info breakpoints’.
maint info breakpoints Используя тот же формат, что и ‘info breakpoints’, отобразить как точки останова, установленные вами явно, так и те, которые GDB использует для внутренних целей. Внутренние точки останова показываются с отрицательными номерами. Колонка типа определяет, какого типа точка останова показана:
Внутренняя точка останова, используемая для корректной обработlongjmp Временная внутренняя точка останова, используемая командой Временная внутренняя точка останова, используемая командой 5.1.2 Установка точек наблюдения Вы можете использовать точку наблюдения для остановки выполнения, как только изменится значение какого-либо выражения, не предсказывая конкретное место, где это может произойти.
В зависимости от вашей системы, точки наблюдения могут быть реализованы программно или аппаратно. GDB осуществляет программную реализацию точек наблюдения путем пошагового выполнения вашей программы и проверки значения переменной на каждом шаге, что в сотни раз медленнее нормального выполнения. (Но тем не менее это может стоить того, найти ошибку в программе, когда вы не представляете, в какой ее части она находится, может быть очень нелегко.) В некоторых системах, таких как HP-UX, Linux и некоторых других платформах, базирующихся на x86, GDB включает поддержку для аппаратных точек наблюдения, которые не замедляют выполнение вашей программы.
watch выраж Устанавливает точку наблюдения за выражением. GDB остановит программу, когда выраж сохраняется программой и его величина изменяется.
rwatch выраж Устанавливает точку наблюдения, которая остановит программу, когда наблюдаемое выраж считывается программой.
awatch выраж Устанавливает точку наблюдения, которая остановит программу, когда выраж либо считывается, либо сохраняется программой.
info watchpoints Эта команда печатает список точек наблюдения, останова и перехвата; это то Когда это возможно, GDB устанавливает аппаратную точку наблюдения. Аппаратные точки наблюдения выполняются очень быстро, и отладчик сообщает об изменении величины точно в месте инструкции, где это изменение произошло. Если GDB не может установить аппаратную точку наблюдения, он устанавливает программную точку наблюдения, которая выполняется намного медленнее и сообщает об изменении величины на следующем операторе, а не инструкции, после появления изменения.
Когда вы даете команду watch, GDB сообщает Hardware watchpoint номер: выраж если ему удалось установить аппаратную точку наблюдения.
В настоящее время, команды awatch и rwatch могут устанавливать только аппаратные точки наблюдения, так как доступы к данным, которые не изменяют величины наблюдаемого выражения, не могут быть замечены без исследования каждой инструкции во время ее выполнения, а GDB пока этого не делает. Если GDB обнаруживает, что не может установить аппаратную точку останова командами awatch или rwatch, он напечатает сообщение, аналогичное этому:
Expression cannot be implemented with read/access watchpoint. Иногда GDB не может установить аппаратную точку наблюдения из-за того, что тип данных наблюдаемого выражения занимает больше места, чем допускает аппаратная точка наблюдения на целевой платформе. Например, некоторые системы позволяют наблюдать за областями, занимающими до 4 байт; на таких системах вы не можете устанавливать аппаратные точки наблюдения за выражениями, которые в результате дают число с плавающей точкой двойной точности (которое обычно занимает 8 байт). В качестве одного из решений, можно разбить большую область на несколько меньших областей, и затем наблюдать за каждой из них с помощью отдельной точки наблюдения.
Если вы установите слишком много аппаратных точек наблюдения, GDB может быть не в состоянии задействовать их все, когда вы возобновите выполнение вашей программы. Так как точное количество активных точек наблюдения неизвестно до того момента, когда ваша программа должна возобновить выполнение, GDB может быть не в состоянии предупредить вас об этом, когда вы устанавливаете точку наблюдения, и предупреждение будет напечатано только когда программа возобновит выполнение:
Hardware watchpoint номер: Could not insert watchpoint Если это происходит, удалите или отключите некоторые точки наблюдения.
SPARClite DSU будет генерировать ловушки, когда программа обращается к некоторым данным или адресу инструкции, которые отведены для отладочных регистров. Для адресов данных, DSU упрощает команду watch. Однако, аппаратные регистры точек останова могут принять только две точки наблюдения за данными, и обе точки наблюдения должны быть одного типа. Например, вы можете установить две точки наблюдения с помощью команды watch, две с помощью команды rwatch, или две с помощью команды awatch, но вы не можете установить одну точку наблюдения с помощью одной команды, а другую с помощью другой. GDB не примет команду, если вы попытаетесь смешать различные точки наблюдения. Удалите или отключите неиспользуемые точки наблюдения перед установкой новых.
Если вы вызываете функцию интерактивно, используя print или call, все установленные вами точки наблюдения будут неактивными, до тех пор пока GDB не достигнет точки останова другого типа, или пока вызов не завершится.
GDB автоматически удаляет точки наблюдения, которые наблюдают за локальными переменными, или за выражениями, которые используют такие переменные, когда они выходят из области видимости, то есть когда выполнение покидает блок, в котором эти переменные были определены. В частности, когда отлаживаемая программа завершается, все локальные переменные выходят из области видимости, и таким образом остаются установленными только те точки наблюдения, которые наблюдают за глобальными переменными. Если вы снова запустите программу, вы должны будете заново установить все Выражение не может быть реализовано с помощью точки наблюдения чтения/доступа. (Прим. переводчика) Аппаратная точка наблюдения номер: Не удается поместить точку наблюдения (Прим. переводчика) такие точки наблюдения. Одним из способов сделать это будет установить точку останова на входе в функцию main, и, когда программа остановится, установить все точки наблюдения.
Предупреждение: В многонитевых программах точки наблюдения являются лишь частично полезными. С текущей реализацией точек наблюдения, GDB может наблюдать только за величиной выражения в одной нити. Если вы уверены, что выражение может измениться только вследствие действий внутри текущей нити (и если вы также уверены, что никакая другая нить не может стать текущей), то вы можете использовать точки наблюдения как обычно.
Однако, GDB может не заметить, когда действия в не текущей нити изменяют выражение.
Предупреждение для HP-UX: В многонитевых программах, программные точки наблюдения являются лишь частично полезными. Если GDB создает программную точку наблюдения, она может наблюдать только за величиной выражения в одной нити. Если вы уверены, что выражение может измениться только вследствие действий внутри текущей нити (и если вы также уверены, что никакая другая нить не может стать текущей), то вы можете использовать программные точки наблюдения как обычно. Однако, GDB может не заметить, когда действия в не текущей нити изменяют выражение. (Аппаратные же точки наблюдения напротив, наблюдают за выражением во всех нитях.) 5.1.3 Установка точек перехвата Вы можете использовать точки перехвата, чтобы вызвать остановку отладчика в ответ на определенные типы событий в программе, такие как исключения в Си++ или загрузка разделяемой библиотеки. Для установки точки перехвата используйте команду catch.
catch событие Остановиться, когда происходит событие. Событие может быть одним из:
Динамическая загрузка любой разделяемой библиотеки, или загрузка библиотеки имя-библ. В настоящее время это доступно только Выгрузка любой динамически загруженной разделяемой библиотеки, или выгрузка библиотеки имя-библ. В настоящее время это tcatch событие Установить точку перехвата, которая включена только до первой активации.
Точка перехвата автоматически уничтожается после того, как событие перехвачено первый раз.
Используйте команду info break для получения списка текущих точек перехвата.
В настоящее время, в GDB существуют некоторые ограничения на обработку исключений Си++ (catch throw и catch catch):
• Если вы вызываете функцию интерактивно, GDB обычно возвращает вам управление после того, как функция закончила выполнение. Однако, если вызов возбуждает исключение, он может обойти механизм, возвращающий вам управление, и заставить вашу программу либо остановиться, либо просто продолжить выполнение до тех пор, пока она не активирует точку останова, получит сигнал, который ждет GDB, или выйдет. Это имеет место даже если вы установите точку перехвата для исключения;
точки перехвата для исключений отключены при интерактивных вызовов.
• Вы не можете возбуждать исключения интерактивно.
• Вы не можете интерактивно установить обработчик исключения.
Иногда catch не является лучшим способом отладки обработки исключений: если вам необходимо точно знать, где исключение возбуждено, то лучше остановиться до того, как вызван обработчик исключения, так как в этом случае вы можете увидеть стек до того, как произойдет какое-либо развертывание. Если вместо этого вы установите точку останова в обработчике исключений, то может быть нелегко определить, где исключение было возбуждено.
Для остановки сразу перед вызовом обработчика исключений, вам необходимы некоторые знания о реализации. В случае gnu Си++, исключения возбуждаются путем вызова библиотечной функции raise_exception, которая имеет следующий интерфейс ANSI Си:
/* addr - где хранится идентификатор исключения.
void raise_exception (void **addr, void *id);
Для того, чтобы отладчик перехватывал все исключения до того, как произойтет развертывание стека, установите точку останова на raise_exception (см. Раздел 5.1 [Точки останова], с. 31).
С помощью условных точек останова (см. Раздел 5.1.6 [Условия останова], с. 40), зависящих от величины id, вы можете остановить вашу программу, когда возбуждается определенное исключение. Вы можете использовать несколько условных точек останова, чтобы остановить программу, когда возбуждается любое из нескольких исключений.
5.1.4 Удаление точек останова Часто бывает необходимо уничтожить точку останова, наблюдения или перехвата, когда она сделала свое дело и вы больше не хотите останавливать там свою программу. Это называется уничтожением точки останова. Точка останова, которая была уничтожена, более не существует; она забыта.
С помощью команды clear вы можете удалять точки останова в соответствии с тем, где они находятся в вашей программе. С помощью команды delete вы можете удалять отдельные точки останова, наблюдения или перехвата, указывая их номера.
Не обязательно удалять точку останова, чтобы продолжить выполнение после нее. GDB автоматически игнорирует точки останова на первой инструкции, которая должна быть выполнена, когда вы продолжаете исполнение без изменения адреса выполнения.
Удаляет любые точки останова, установленные на следующей инструкции, коclear торая должна быть выполнена в выбранном кадре стека (см. Раздел 6.3 [Выбор кадра], с. 52). Когда выбран самый внутренний кадр, это хороший способ удалить ту точку останова, на которой ваша программа только что остановилась.
clear функция clear имя-файла:функция Удалить любые точки останова, установленные на входе в функцию.
clear номер-строки clear имя-файла:номер-строки Удалить все точки останова, установленные на или внутри кода на указанной delete [breakpoints] [диапазон...] Удалить точки останова, наблюдения или перехвата из диапазона, указанного в качестве аргумента. Если аргумент не задан, удалить все точки останова (GDB запрашивает подтверждение, если у вас не установлено set confirm off). Вы можете сократить это команду как d.
5.1.5 Отключение точек останова Вместо того, чтобы удалять точку останова, наблюдения или перехвата, вам может быть удобнее отключить ее. Это делает точку останова бездействующей, как если бы она была удалена, но информация о ней запоминается, так что вы можете позже включить ее снова.
Вы отключаете и включаете точки останова, наблюдения и перехвата командами enable и disable, возможно указывая один или более номеров точек останова в качестве аргументов. Используйте info break или info watch для распечатки списка точек останова, наблюдения и перехвата, если вы не знаете какие номера использовать.
Точка останова, наблюдения или перехвата может находиться в одном из четырех состояний:
• Включена. Точка останова останавливает вашу программу. Точка останова, установленная командой break, изначально находится в таком состоянии.
• Отключена. Точка останова не оказывает воздействия на вашу программу.
• Включена до первого срабатывания. Точка останова останавливает вашу программу, но потом становится отключенной.
• Включена для удаления. Точка останова останавливает вашу программу, но сразу после этого она удаляется навсегда. Точка останова, установленная командой tbreak, изначально находится в этом состоянии.
Вы можете использовать следующие команды для включения или отключения точек останова, наблюдения и перехвата:
disable [breakpoints] [диапазон...] Отключить указанные точки останова, или все точки останова, если ни одна не перечислена. Отключенная точка останова не оказывает никакого действия, но она не забывается. Все параметры, такие как счетчик игнорирований, условия и команды запоминаются, на случай, если точка останова позже будет снова включена. Вы можете сокращать disable как dis.
enable [breakpoints] [диапазон...] Включает указанные (или все определенные) точки останова. Они снова становятся значимыми для остановки вашей программы.
enable [breakpoints] once диапазон...