Основы использования отладчика WinDbg. Отладка с помощью GDB Промежуточная оболочка между gdb и отладчиком

Цель отладки программы - устранение ошибок в её коде. Для этого вам, скорее всего, придётся исследовать состояние переменных во время выполнения , равно как и сам процесс выполнения (например, отслеживать условные переходы). Тут отладчик - наш первый помощник. Конечно же, в Си достаточно много возможностей отладки без непосредственной остановки программы: от простогоprintf(3) до специальных систем ведения логов по сети и syslog . В ассемблере такие методы тоже применимы, но вам может понадобиться наблюдение за состоянием регистров, образ ( dump ) оперативной памяти и другие вещи, которые гораздо удобнее сделать в интерактивном отладчике. В общем, если вы пишете на ассемблере, то без отладчика вы вряд ли обойдётесь.

Начать отладку можно с определения точки останова ( breakpoint ), если вы уже приблизительно знаете, какой участок кода нужно исследовать. Этот способ используется чаще всего: ставим точку останова, запускам программу и проходим её выполнение по шагам, попутно наблюдая за необходимыми переменными и регистрами. Вы также можете просто запустить программу под отладчиком и поймать момент, когда она аварийно завершается из-за segmentation fault, - так можно узнать, какая инструкция пытается получить доступ к памяти, подробнее рассмотреть приводящую к ошибке переменную и так далее. Теперь можно исследовать этот код ещё раз, пройти его по шагам, поставив точку останова чуть раньше момента сбоя.

Начнём с простого. Возьмём программу Hello world и скомпилируем её с отладочной информацией при помощи ключа компилятора -g :

$ gcc -g hello.s -o hello $

Запускаем gdb:

$ gdb ./hello GNU gdb 6.4.90-debian Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or 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. This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb)

GDB запустился, загрузил исследуемую программу, вывел на экран приглашение (gdb) и ждёт команд. Мы хотим пройти программу "по шагам" ( single-step mode ). Для этого нужно указать команду, на которой программа должна остановиться. Можно указать подпрограмму - тогда остановка будет осуществлена перед началом исполнения инструкций этой подпрограммы. Ещё можно указать имя файла и номер строки.

(gdb) b main Breakpoint 1 at 0x8048324: file hello.s, line 17. (gdb)

b - сокращение от break . Все команды в GDB можно сокращать, если это не создаёт двусмысленных расшифровок. Запускаем программу командой run . Эта же команда используется для перезапуска ранее запущенной программы.

(gdb) r Starting program: /tmp/hello Breakpoint 1, main () at hello.s:17 17 movl $4, %eax /* поместить номер системного вызова write = 4 Current language: auto; currently asm (gdb)

GDB остановил программу и ждёт команд. Вы видите команду вашей программы, которая будет выполнена следующей, имя функции , которая сейчас исполняется, имя файла и номер строки. Для пошагового исполнения у нас есть две команды: step (сокращённо s ) и next (сокращённо n ). Команда step производит выполнение программы с заходом в тела подпрограмм. Команда next выполняет пошагово только инструкции текущей подпрограммы.

(gdb) n 20 movl $1, %ebx /* первый параметр - в регистр %ebx */ (gdb)

Итак, инструкция на строке 17 выполнена, и мы ожидаем, что в регистре %eax находится число 4. Для вывода на экран различных выражений используется команда print (сокращённо p ). В отличие от команд ассемблера, GDB в записи регистров использует знак $ вместо % . Посмотрим, что в регистре %eax :

(gdb) p $eax $1 = 4 (gdb)

Действительно 4! GDB нумерует все выведенные выражения. Сейчас мы видим первое выражение ($1 ), которое равно 4. Теперь к этому выражению можно обращаться по имени. Также можно производить простые вычисления:

(gdb) p $1 $2 = 4 (gdb) p $1 + 10 $3 = 14 (gdb) p 0x10 + 0x1f $4 = 47 (gdb)

Пока мы играли с командой print , мы уже забыли, какая инструкция исполняется следующей. Команда info line выводит информацию об указанной строке кода. Без аргументов выводит информацию о текущей строке.

(gdb) info line Line 20 of "hello.s" starts at address 0x8048329 and ends at 0x804832e . (gdb)

Команда list (сокращённо l ) выводит на экран исходный код вашей программы. В качестве аргументов ей можно передать:

  • номер_строки - номер строки в текущем файле;
  • файл:номер_строки - номер строки в указанном файле;
  • имя_функции - имя функции, если нет неоднозначности;
  • файл:имя_функции - имя функции в указанном файле;
  • *адрес - адрес в памяти, по которому расположена необходимая инструкция.

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

(gdb) l main 12 за пределами этого файла */ 13 .type main, @function /* main - функция (а не данные) */ 14 15 16 main: 17 movl $4, %eax /* поместить номер системного вызова 18 write = 4 в регистр %eax */ 19 20 movl $1, %ebx /* первый параметр поместить в регистр 21 %ebx; номер файлового дескриптора 22 stdout = 1 */ (gdb) l *$eip 0x8048329 is at hello.s:20. 15 16 main: 17 movl $4, %eax /* поместить номер системного вызова 18 write = 4 в регистр %eax */ 19 20 movl $1, %ebx /* первый параметр поместить в регистр 21 %ebx; номер файлового дескриптора 22 stdout = 1 */ 23 movl $hello_str, %ecx /* второй параметр поместить в 24 регистр %ecx; указатель на строку */ (gdb) l 20, 25 20 movl $1, %ebx /* первый параметр поместить в регистр 21 %ebx; номер файлового дескриптора 22 stdout = 1 */ 23 movl $hello_str, %ecx /* второй параметр поместить в 24 регистр %ecx; указатель на строку */ 25 (gdb)

Запомните эту команду: list *$eip . С её помощью вы всегда можете просмотреть исходный код вокруг инструкции, выполняющейся в текущий момент. Выполняем нашу программу дальше:

(gdb) n 23 movl $hello_str, %ecx /* второй параметр поместить в регистр %ecx (gdb) n 26 movl $hello_str_length, %edx /* третий параметр поместить в регистр %edx (gdb)

Не правда ли, утомительно каждый раз нажимать n ? Если просто нажать Enter , GDB повторит последнюю команду:

(gdb) 29 int $0x80 /* вызвать прерывание 0x80 */ (gdb) Hello, world! 31 movl $1, %eax /* номер системного вызова exit = 1 */ (gdb)

Ещё одна удобная команда , о которой стоит знать - info registers . Конечно же, её можно сократить до i r . Ей можно передать параметр - список регистров, которые необходимо напечатать. Например, когда выполнение происходит в защищённом режиме, нам вряд ли будут интересны значения сегментных регистров.

(gdb) info registers eax 0xe 14 ecx 0x804955c 134518108 edx 0xe 14 ebx 0x1 1 esp 0xbfabb55c 0xbfabb55c ebp 0xbfabb5a8 0xbfabb5a8 esi 0x0 0 edi 0xb7f6bcc0 -1208566592 eip 0x804833a 0x804833a eflags 0x246 [ PF ZF IF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb) info registers eax ecx edx ebx esp ebp esi edi eip eflags eax 0xe 14 ecx 0x804955c 134518108 edx 0xe 14 ebx 0x1 1 esp 0xbfabb55c 0xbfabb55c ebp 0xbfabb5a8 0xbfabb5a8 esi 0x0 0 edi 0xb7f6bcc0 -1208566592 eip 0x804833a 0x804833a eflags 0x246 [ PF ZF IF ] (gdb)

Так, а кроме регистров у нас ведь есть ещё и

GDB относится к «умным» программам-отладчикам, то есть таким, которые «понимают» код и умеют выполнять его построчно, менять значения переменных, устанавливать контрольные точки и условия остановки… Словом, делать всё для того, чтобы разработчик мог проверить правильность работы своей программы.

GDB встроен во многие UNIX -подобные системы и умеет производить отладку нескольких языков программирования. Си - в их числе.

Чтобы вызвать GDB введите в терминале команду

Gdb [ имя_программы_которую_вы_хотите_отладить]

Чтобы выйти из GDB : введите команду

Quit или С –d

Другие важные команды GDB

run [аргументы командной строки программы] Запустить программу на выполнение. break [ номер строки / имя функции] Установить точку остановки программы на определенной строке или функции. next Перейти на следующую строку, не заходя внутрь функций. step Перейти на следующую строку. Если на строке вызов функции - зайти внутрь нее. list Вывести фрагмент кода программы (несколько строк вокруг того места, где сейчас установлена точка) print [ переменная] Вывести значение переменной на экран. info locals Вывести текущие значения всех локальных переменных внутри цикла, функции и так далее. display [ переменная] Вывести значение переменной на каждом шаге отладки. help Показать список всех команд GDB.

Давайте посмотрим, как работать с GDB на примере программы caesar.c, которую вы, скорее всего уже написали на прошлой неделе. Проверять будем на собственной версии, так что у вас результаты могут несколько отличаться в зависимости от реализации.

Итак, переходим в папку pset2 (думаем, вы уже помните, как это сделать) в «Виртуальной лаборатории cs50» или CS50 IDE. Вводим команду:

Gdb . /caesar

В программе caesar есть одна функция, main. Установим точку остановки программы на функции main:

break main

Запустим программу caesar с аргументом «3»:

Run 13

Допустим, нам надо проверить значение argc:

Print argc

Вот как всё это должно выглядеть в окне терминала:

Теперь выполняем программу пошагово с помощью команды next . Выполним несколько раз.

Здесь переменной key присваивают значение. Проверим, какое значение она имеет этой строке:

При первом вызве next переменной key присваивается значение «0». ПОчему так, если мы ввели число 3? Дело в том, что команда ещё не была выполнена. Когда вы вводим next ещё несколько раз, программа предлагает ввести текст.

Выполнив команду next еще раз, мы зайдем внутрь цикла с условием.

Linux: Полное руководство Колисниченко Денис Николаевич

22.2. Отладчик gdb

22.2. Отладчик gdb

Формат вызова отладчика gdb следующий:

gdb [-help] [-nx] [-q] [-batch] [-cd=dir] [-f] [-b bps] [-tty=dev] [-s symfile] [-e prog] [-sе prog] [-c core] [-x cmds] [-d dir] ]

Ключи отладчика описаны в таблице 22.1.

Ключи командной строки gdb Таблица 22.1

Ключ Назначение
-help или -h Вывод краткого описания всех параметров
-nx или -n Не обрабатывать команды файла инициализации.gdbinit
-q Не выводить приветствие и информацию об авторских правах
-batch Командный режим. Отладчик возвращает 0, если были выполнены все команды, указанные в файле, заданном параметром -x (и файле.gdbinit, если его использование разрешено). Если же хотя бы одна из команд не выполнена, возвращается ненулевое значение
-cd=каталог Установить рабочий каталог (по умолчанию используется текущий каталог)
-f или -fullname Данная опция нужна, если вы планируете использовать интерфейс текстового процессора Emacs для отладки ваших программ с помощью gdb . Для более подробного описаний обратитесь к справочной системе
-b bps (bits per second) Установить скорость обмена информацией по последовательному интерфейсу, если вы отлаживаете вашу программу удаленно
-tty=терминал Установить терминал в качестве стандартного ввода и вывода для отлаживаемой программы.
-s файл или -symbols=файл Читает таблицу символов из указанного файла
-write Разрешить запись в исполняемые и core-файлы
-e программа Использовать указанную программу в качестве фильтра дампа
-se=файл Читать таблицу символов из указанного файла и использовать указанный файл в качестве исполнимого
-core=файл или -с файл Указать файл дампа
-command=файл или -x файл Выполнить указанные в файле команды (используется в командном режиме)
-d каталог Добавить каталог к списку поиска исходных текстов
Последний параметр задает объект, который нужно отлаживать. Вы можете задать программу (prog), или дамп-файл (core), который будет создан в случае ошибки программы (Segmentation fault), или же подсоединиться к уже запущенному процессу (procID)
-p PID Подключиться к уже запущенному процессу (данная опция стала доступной в версии gdb 5.2)

Чтобы использовать gdb для отладки вашей программы, нужно добавить в исполняемый файл отладочную информацию. Для этого откомпилируете вашу программу с опцией -g:

$ gcc -g -o prog prog.c

Данная опция включает отладочную информацию в родном для операционной системы формате, с которым может работать gdb .

Затем нужно вызвать gdb так:

Если после запуска вашей программы произошла ошибка и был создан дамп-файл (core), можно передать отладчику и этот файл:

Можно также подключиться к уже запущенному процессу, для этого нужно передать его PID:

Только убедитесь сначала в том, что у вас нет файла 1111, поскольку gdb сначала ищет исполняемый файл, затем core-файл, а уже затем PID.

После запуска отладчика в интерактивном режиме вы можете использовать команды, самые важные из которых перечислены в таблице 22.2. Об остальных можно узнать в справочной системе: man gdb.

Команды gdb Таблица 22.2

Команда Назначение
break [файл:]функция Установить точку останова
run [аргументы] Запустить программу и передать ей указанные аргументы
bt Обратная трассировка: отобразить стек программы
print выражение Вывести значение выражении, операндами могут быть переменные, объявленные в вашей программа
С Продолжить выполнение программы (после останова)
Next Выполнить следующую строку. Это так называемый шаг «над» (step over). Если следующая строка - вызов функции, то мы выполним ее за один шаг - «перешагнем» ее
Step Выполнить следующую строку, Это так называемый шаг «в» (step into). Если следующая строка - вызов функции, то мы будем последовательно выполнять все операторы тела функции
help [имя] Вывести справку о команде отладчика или вывести общую информацию о нем
Quit Выход

В данной таблице приведены далеко не все команды. Если вас интересует более полная информация, обратитесь к руководству по gdb .

Из книги Язык программирования С# 2005 и платформа.NET 2.0. автора Троелсен Эндрю

Отладчик командной строки (cordbg.exe) Прежде чем перейти к рассмотрению возможностей компоновки C#-приложе-ний с помощью TextPad, следует отметить, что.NET Framework 2.0 SDK предлагает отладчик командной строки cordbg.ехe. Этот инструмент имеет множество опций, которые позволяют выполнить

Из книги Разработка приложений в среде Linux. Второе издание автора Джонсон Майкл К.

4.3. Отладчик GNU gdb - это отладчик, рекомендуемый Free Software Foundation, gdb представляет собой хороший отладчик командной строки, на котором строятся некоторые инструменты, включая режим gdb в Emacs, графический отладчик Data Display Debugger (http://www.gnu.org/software/ddd/) и встроенные отладчики в некоторых

Из книги Linux: Полное руководство автора Колисниченко Денис Николаевич

22.2. Отладчик gdb Формат вызова отладчика gdb следующий:gdb [-help] [-nx] [-q] [-batch] [-cd=dir] [-f] [-b bps] [-tty=dev] [-s symfile] [-e prog] [-sе prog] [-c core] [-x cmds] [-d dir] ]Ключи отладчика описаны в таблице 22.1.Ключи командной строки gdb Таблица 22.1 Ключ Назначение -help или -h Вывод краткого описания всех

Из книги Программирование для Linux. Профессиональный подход автора Митчелл Марк

1.4. GNU-отладчик gdb Отладчик - это программа, с помощью которой можно узнать, почему написанная вами программа ведет себя не так, как было задумано. Работать с отладчиком приходится очень часто. Большинство Linux-программистов имеет дело с GNU-отладчиком (GNU Debugger, GDB), который

Из книги Разработка ядра Linux автора Лав Роберт

Отладчик kgdb Отладчик kgdb - это заплата ядра, которая позволяет с помощью отладчика gdb отлаживать ядро по линии последовательной передачи. Для этого требуется два компьютера. На первом выполняется ядро с заплатой kgdb. Второй компьютер используется для отладки ядра по линии

GNU Debugger – переносимый отладчик проекта GNU, который работает на многих UNIX-подобных системах и умеет производить отладку многих языков программирования, включая Си, C++, Ada и Фортран. GNU Debugger – свободное программное обеспечение, распространяемое по лицензии GNU General Public License.

Первоначально GNU Debugger написан Ричардом Столлманом в 1988 году. За основу был взят отладчик DBX, поставлявшийся с дистрибутивом BSD. С 1990 до 1993 гг. проект поддерживался Джоном Джилмором, во время его работы в компании Cygnus Solutions. В настоящее время разработка координируется Управляющим комитетом GDB (GDB Steering Committee), назначенным Free Software Foundation.

Технические детали GNU Debugger

  • Особенности

GNU Debugger предлагает обширные средства для слежения и контроля за выполнением компьютерных программ. Пользователь может изменять внутренние переменные программ и даже вызывать функции независимо от обычного поведения программы. GNU Debugger может отлаживать исполняемые файлы в формате a.out, COFF (в том числе исполняемые файлы Windows), ECOFF, XCOFF, ELF, SOM, использовать отладочную информацию в форматах stabs, COFF, ECOFF, DWARF, DWARF2. Наибольшие возможности отладки предоставляет формат DWARF2.

GNU Debugger активно развивается. Например, в версии 7.0 добавлена поддержка «обратимой отладки», позволяющей отмотать назад процесс выполнения, чтобы посмотреть, что произошло. Также в версии 7.0 была добавлена поддержка скриптинга на .

Для работы с GNU Debugger были созданы и другие инструменты отладки например, датчики утечки памяти.

  • Мультиплатформенность и поддержка встроенных систем

GNU Debugger может быть скомпилирован для поддержки приложений для нескольких целевых платформ и переключаться между ними во время отладочной сессии. Процессоры, поддерживаемые GNU Debugger (2003): Alpha, ARM, H8/300, System/370, System/390, x86 и x86-64, IA-64 (Itanium), Motorola 68000, MIPS, PA-RISC, PowerPC, SuperH, SPARC, VAX, A29K, ARC, AVR, CRIS, D10V, D30V, FR-30, FR-V, Intel i960, M32R, 68HC11, Motorola 88000, MCORE, MN10200, MN10300, NS32K, Stormy16, V850 и Z8000. (Более новые выпуски не будут, вероятно, поддерживать некоторых из них.) Целевые платформы, на которых GNU Debugger не может быть запущен, в частности, встроенные системы, могут поддерживаться с помощью встроенного симулятора (процессоры ARM, AVR), либо приложения для них могут быть скомпилированы со специальными подпрограммами, обеспечивающими удалённую отладку под управлением GNU Debugger, запущенном на компьютере разработчика. Входным файлом для отладки, как правило, используется не прошиваемый двоичный файл, а файл в одном из поддерживающих отладочную информацию форматов, в первую очередь ELF, из которого впоследствии с помощью специальных утилит извлекается двоичный код для прошивки.

  • Удалённая отладка

При удалённой отладке GNU Debugger запускается на одной машине, а отлаживаемая программа запускается на другой. Связь осуществляется по специальному протоколу через последовательный порт или TCP/IP. Протокол взаимодействия с отладчиком специфичен для GNU Debugger, но исходные коды необходимых подпрограмм включены в архив отладчика. Как альтернатива, на целевой платформе может быть запущена использующая тот же протокол программа gdbserver из состава пакета GNU Debugger, исполняющая низкоуровневые функции вроде установки точек останова и доступа к регистрам и памяти.

Этот же режим используется для взаимодействия со встроенным отладчиком ядра Linux KGDB. С его помощью разработчик может отлаживать ядро как обычную программу: устанавливать точки останова, делать пошаговое исполнение кода, просматривать переменные. Встроенный отладчик требует наличия двух машин, соединенных через Ethernet или последовательный кабель, на одном из которых запущен GNU Debugger, на другом – отлаживаемое ядро.

  • Пользовательский интерфейс

В соответствии с идеологией ведущих разработчиков Free Software Foundation, GNU Debugger вместо собственного графического пользовательского интерфейса предоставляет возможность подключения к внешним IDE, управляющим графическим оболочкам либо использовать стандартный консольный текстовый интерфейс. Для сопряжения с внешними программами можно использовать язык текстовой строки (как это было сделано в первых версиях оболочки DDD), текстовый язык управления gdb/mi, либо интерфейс для языка .

Были созданы такие интерфейсы как DDD, cgdb, GDBtk/Insight и «GUD mode» в . С GNU Debugger могут взаимодействовать такие IDE, как

Ошибки, к сожалению, встречаются в любой программе, каким бы крутым профессионалом её разработчик ни был. Поэтому, нравится это вам или нет, пользоваться отладчиком вам всё равно придётся. Жизнь заставит. И чем больше времени вы сейчас потратите на изучение работы с ним, тем больше времени это вам сэкономит в дальнейшем.

Мы рассмотрим отладчик GDB, входящий в комплект программ GNU.

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

Такая компиляция достигается путём добавления флага -g к команде на компиляцию. Например, если бы мы собирали программу kalkul без применения Makefile, мы бы дали такую команду:

g++ main.cpp problem.cpp -o kalkul -g

Если же мы пользуемся командой make, то надо поставить опцию CFLAGS=-g. Тогда все команды на компиляцию, содержащиеся в Make-файле, автоматически получат флаг -g.

Давайте возьмём программу, которую мы создали из файлов main.cpp, problem.cpp и problem.h (мы тогда называли этот каталог проекта kalkulcpp). У нас Makefile уже сформирован. Воспользуемся им.

Очистим пакет от результатов предыдущей сборки.

Соберём программу снова, но уже с включением отладочной информации.

Запустим отладчик GDB, загрузив в него нашу программу для отладки. (Если помните, исполняемая программа у нас находилась в каталоге src.)

gdb ./src/kalkul

Чтобы запустить программу внутри отладчика,даётся команда run.

Чтобы посмотреть исходный код, даётся команда list.

Если дать эту команду без параметров, то она первые девять строк исходного кода главного файла (то есть такого, в котором имеется функция main). Чтобы просматривать файл дальше, надо снова набирать list. Чтобы посмотреть конкретные строки, надо указать два параметра: с какой строки начинать просмотр, и с какой строки заканчивать.

Чтобы просмотреть другие файлы проекта, надо перед номерами строк указать название нужного файла и отделить его от номеров строк двоеточием.

list problem.cpp:20,29

Поставим точку останова на строке номер 21. Точка останова - это метка, указывающая, что программа, дойдя до этого места, должна остановиться.

list problem.cpp:20,27

Посмотреть, где вы поставили точки останова, можно с помощью команды info breakpoints.

info breakpoints

(При желании можно вместо номера строки указать название функции,тогда программа остановится перед входом в функцию.)

Запустим программу.

Введём первое число 5 и знак математического действия « + ». Программа дойдёт до точки останова и остановится, выведя нам строку, у которой эта точка расположена.

Нам, конечно, интересно знать,в каком именно месте мы остановились, и что программа уже успела выполнить. Даём команду backtrace.

Отладчик выдаёт нам следующую информацию:

#0 CProblem::Calculate (this=0x804b008) at problem.cpp:21

#1 0x08048e00 in CProblem::Solve (this=0x804b008) at problem.cpp:93

#2 0x08048efc in main () at main.cpp:15

Это означается, что мы находимся внутри выполняющейся функции Calculate, являющейся функцией-членом класса CProblem. Она была вызвана из функции Solve того же класса, а та, в свою очередь, из функции main. Таким образом, команда backtrace показывает весь стек вызываемых функций от начала программы до текущего места.

Посмотрим, чему же равно на этом этапе значение переменной Numeral.

И нам сразу выводится число 5, которое мы и вводили в программу. (Значение, введённое нами с клавиатуры, присвоилось именно этой переменной.)

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

Добавим ещё одну точку останова на строке 25 файла problem.cpp.

break problem.cpp:25

Продолжим выполнение программы.

Команда Continue продолжает выполнение программы с текущего адреса. Если бы мы набрали run, программа начала бы выполняться с начала. Поскольку на строке 24 имеется команда cin >> SecondNumeral, то нам придётся ввести второе слагаемое. Введём, например,число 2. После этого программа опять остановится на строке 25 (наша вторая точка останова).

Посмотрим, чему равны значения наших переменных Numeral, SecondNumeral и Operation. Если вы помните, именно такие переменные мы объявляли в классе CProblem.

print SecondNumeral

У нас получится 5, « + », 2. Так и должно быть. Но давайте теперь «передумаем» и лучше присвоим переменной SecondNumeral значение 4. Отладчик GDB позволяет прямо во время выполнения программы изменить значение любой переменной.

set SecondNumeral=4

Если не верим, что её значение изменилось,можно проверить.

print SecondNumeral

Теперь мы ожидаетм, что результат будет 9. Давайте выполним программу до конца.

Результат действительно равен 9.

Давайте теперь уберём наши точки останова. Мы, кажется, создали две таких точки. Но это можно проверить.

info breakpoints

Удалим их.

Унас не должно остаться ни одной точки останова. Проверяем.

info breakpoints

Действительно не осталось ни одной.

Теперь давайте пошагово пройдём всю программу (благо, она у нас небольшая).

Поставим точку останова на десятой строке главного файла.

break main.cpp:10

Запустим программу

Дойдя до десятой строчки, она остановится. Теперь проходим её, останавливаясь на каждой строчке, с помощью команды step.

Чтобы не набирать каждый раз s-t-e-p, можно просто вводить букву s. Как только программа доходит до команды Problem->SetValues(), она сразу переходит в файл problem.cpp, где находится определение функции-члена CProblem::SetValues() и проходит код этой функции. То же самое, когда она дойдёт до вызова Problem->Solve().

Чтобы при вызове функции, программа не входила в неё, а продолжала дальше выполняться только на текущем уровне стека, вместо step даётся команда next или просто n.

Таким образом, можно просмотреть, как выполняется вся программа или любой участок программы. На любом шаге можно проверять значение любой переменной. Чтобы перестать проходить программу по шагам и запустить её до конца, надо дать команду continue.

Дадим короткий список наиболее часто встречающихся команд отладчика GDB. За более подробной информацией вы, конечно, всегда можете обратиться к встроенному описанию программы (info gdb) или руководством по пользованию (man gdb).

backtrace - выводит весь путь к текущей точке останова, то есть названия всех функций, начиная от main(); иными словами, выводит весь стек функций;

break - устанавливает точку останова; параметром может быть номер строки или название функции;

clear - удаляет все точки останова на текущем уровне стека (то есть в текущей функции);

continue - продолжает выполнение программы от текущей точки до конца;

delete - удаляет точку останова или контрольное выражение;

display - добавляет выражение в список выражений, значения которых отображаются каждый раз при остановке программы;

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

info breakpoints - выводит список всех имеющихся точек останова;

info watchpoints - выводит список всех имеющихся контрольных выражений;

list - выводит исходный код; в качестве параметра передаются название файла исходного кода, затем, через двоеточие, номер начальной и конечной строки;

next - пошаговое выполнение программы, но, в отличие от команды step, не выполняет пошагово вызываемые функции;

print - выводит значение какого-либо выражения (выражение передаётся в качестве параметра);

run - запускает программу на выполнение;

set - устанавливает новое значение переменной

step - пошаговое выполнение программы;

watch - устанавливает контрольное выражение, программа остановится, как только значение контрольного выражения изменится;

Дмитрий Пантелеичев (dimanix2006 at rambler dot ru) - Знакомство с отладчиком gdb