Как пользоваться отладчиком gdb
GDB предоставляет все перечисленные возможности. Он называется отладчиком на уровне исходного текста, создавая иллюзию, что Вы выполняете операторы C++ из Вашей программы, а не машинный код, в который они действительно транслируются.
Для иллюстрации мы используем систему, которая компилирует программы на C++ в исполняемые файлы, содержащие машинный код. В результате этого процесса информация об оригинальном коде C++ теряется при трансляции. Отдельный оператор C++ обычно преобразуется в несколько машинных команд, а большинство имен локальных переменных просто теряется. Информация о именах переменных и операторах C++ в Вашей исходной программе не является необходимой для ее выполнения. Поэтому, для правильной работы отладчика на уровне исходного текста, компилятор должен поместить в программу некоторую дополнительную информацию. Обычно ее добавляют к информации, используемой компоновщиком, в исполняемый файл.
Чтобы указать компилятору (gcc), что Вы планируете отлаживать Вашу программу, и поэтому нуждаетесь в дополнительной информации, добавьте ключ -g в опции компиляции и компоновки. Например, если Ваша программа состоит из двух файлов main.C и utils.C, Вы можете откомпилировать ее командами
gcc -c -g -Wall main.C gcc -c -g -Wall utils.C gcc -g -o myprog main.ob utils.o
или одной командой
gcc -g -Wall -o myprog main.o utils.o
Обе последовательности команд приводят к созданию исполняемого файла myprog.
чтобы выполнить полученную программу под управлением gdb, введите
Вы увидите командное приглашение GDB:
Это очень простой, но эффективный тексовый интерфейс отладчика. Его вполне достаточно, чтобы ознакомиться с основными командами gdb.
Когда GDB запускается, Ваша программа в нем еще не выполняется; Вы должны сами сообщить GDB, когда ее запустить. Как только программа приостанавливается в процессе выполнения, GDB ищет определенную строку исходной программы с вызовом определенной функции — либо строку в программе, где произошел останов, либо строку, содержащую вызов функции, в которой произошел останов, либо строку с вызовом функции и т.д. Далее используется термин «текущее окно» , чтобы сослаться на точку останова.
Как только возникает командное приглашение, Вы можете использовать следующие команды. help command
Выводит краткое описание команды GDB. Просто help выдает список доступных разделов справки.
Запускает Вашу программу с определенными аргументами командной строки. GDB запоминает переданные аргументы, и простой перезапуск программы с помощью run приводит к использованию этих аргументов.
Создает трассу — цепочку вызовов функций, произошедших до попадания программы в текущее место. Синонимом является команда bt.
Перемещает текущее окно так, чтобы GDB анализировал место, из которого произошел вызов данного окна. Очень часто Ваша программа может войти в библиотечную функцию — такую, для которой не доступен исходный код, например, в процедуру ввода-вывода. Вам может понадобиться несколько команд up , чтобы перейти в точку программы, которая была выполнена последней.
Производит эффект, обратный up.
Выводит значение E в текущем окне программы, где E является выражением C++ (обычно просто переменной). Каждый раз при использовании этой команды, GDB нумерует ее упоминание для будущих ссылок. Например,
(gdb) print A[i] $2 = -16
(gdb) print $2 + ML $3 = -9
сообщает нам, что величина A[i] в текущем окне равна -16, и что при добавлении этого значения к переменной ML получится -9.
Если программа запущена через оболочку shell, Ctrl-c немедленно прекращает ее выполнение. В GDB программа приостанавливается, пока ее выполнение не возобновится.
Установить точку останова; программа приостановится при ее достижении. Простейший способ — установить точку останова после входа в функцию, например
(gdb) break MungeData Breakpoint 1 at 0x22a4: file main.C, line 16.
Команда break main остановит выполнение в начале программы.
Вы можете установить точки останова на определенную строку исходного кода:
(gdb) break 19 Breakpoint 2 at 0x2290: file main.C, line 19.
(gdb) break utils.C:55 Breakpoint 3 at 0x3778: file utils.C, line 55.
Когда Вы запустите программу и она достигнет точки останова, Вы увидите сообщение об этом и приглашение, например
Breakpoint 1, MungeData (A=0x6110, N=7) at main.c:16
Удаляет точку останова с номером N. Если опустить N, будут удалены все точки останова.
cont или continue
Продолжает обычное выполнение программы.
Выполняет текущую строку программы и останавливается на следующем операторе для выполнения.
Похожа на step, однако, если текущая строка программы содержит вызов функции (так что step должен будет остановиться в начале функции), не входит в эту функцию, а выполняет ее и переходит на следующий оператор.
Выполняет команды next без остановки, пока не достигнет конца текущей функции.
Next: Интерфейсы gdb и другие Up: Средства программирования в ОС Previous: Ассемблеры gas и nasm Contents Index Alex Otwagin 2002-12-16
Использование отладчика GDB

В вебинарах «Linux разработка на языке си. Изучаем основное API.» Было кратко упомянуто о gdb-отладчике. Но за 40 минут осветить хотя бы основные моменты использования отладчика не представляется возможным. Поэтому было принято решение записать открытое видео по отладчику gdb. Полезна будет всем кто начинает разбираться в программировании встроенных систем на Linux.
Видеолекция включает в себя использование популярного отладчика *nix системах и разбираются основные темы:
1. Пример отладки простейшей программы.
- Основные команды.
- Точки останова (по переменным, по строкам).
- Переменные, массивы.
2. Дизассемблирование. (в т.ч. и других архитектур).
3. Многопоточная отладка.
4. Отладка дочерних программ.
5. Подключение к работающему процессу.
6. Удалённая отладка. (в т.ч. и других архитектур)
7. Отладка с дампом ядра.
Программы, использованные в видео обитают тут:
Github
Если есть интерес освоить программирование в *nix системах или даже написание модулей ядра (драйверов), то вы можете следить за предстоящими событиями в блоге Сереги, либо написать ему по почте dlinyj(с)gmail.com и вы получите уведомление обо всех планируемых вебинарах. Также он продает записи прошлых вебинаров. А это многие часы видео плото набитых инфой пр программированию в linux.
Спасибо. Вы потрясающие! Всего за месяц мы собрали нужную сумму в 500000 на хоккейную коробку для детского дома Аистенок. Из которых 125000+ было от вас, читателей EasyElectronics. Были даже переводы на 25000+ и просто поток платежей на 251 рубль. Это невероятно круто. Сейчас идет заключение договора и подготовка к строительству!
А я встрял на три года, как минимум, ежемесячной пахоты над статьями :)))))))))))) Спасибо вам за такой мощный пинок.
Краткая инструкция по использованию отладчика GDB
GDB — это консольное приложение, выполненное в классическом духе командной строки. Вот краткое руководство по использованию отладчика GDB.
И хотя за время своего существования GDB успел обрасти ворохом красивых графических морд (среди них DDD, Data Display Debugger, — старейший и самый популярный интерфейс), интерактивная отладка в стиле WinDBG в мире Linux крайне непопулярна.

Как правило, это удел эмигрантов с Windows-платформы, сознание которых необратимо искалечено идеологией «окошек». Грубо говоря, если WinDBG — слесарный инструмент, то GDB — токарный станок с программным управлением. Когда‑нибудь вы полюбите его.

Для отладки на уровне исходных текстов программа должна быть откомпилирована с отладочной информацией. В GCC за это отвечает ключ — g . Если отладочная информация недоступна, GDB будет отлаживать программу на уровне дизассемблерных команд.
Обычно имя отлаживаемого файла передается в командной строке:
gdb filename
Для отладки активного процесса укажите в командной строке его ID, а для подключения коры (core dump) воспользуйтесь ключом:
— core == corename
Все три параметра можно загружать одновременно, попеременно переключаясь между ними командой target.
Переключаемся на отлаживаемый файл:
target exec
На приаттаченный процесс:
target child
Или на дамп коры:
target core
Необязательный ключ — q подавляет вывод копирайта. Загрузив программу в отладчик, мы должны установить точку останова. Для этого служит команда break (она же b ).
Эта команда устанавливает точку останова на функцию main языка C, а вот эта:
на точку входа в ELF-файл (впрочем, в некоторых файлах она называется по‑другому). Можно установить точку останова и на произвольный адрес:
b * 0x8048424
Регистры пишутся маленькими буквами и предваряются знаком доллара. GDB понимает два «общесистемных» регистра: $ pc — указатель команд и $ sp — стековый указатель. Только помните, что непосредственно после загрузки программы в отладчик никаких регистров у нее еще нет, они появляются только после запуска отлаживаемого процесса на выполнение (команда run , она же r ).
Отладчик самостоятельно решает, какую точку останова установить, программную или аппаратную, и лучше ему не препятствовать (команда принудительной установки аппаратной точки останова hbreak работает не на всех версиях отладчика). Точки останова на данные в GDB называются точками наблюдения — watch point.
Перечислю основные приемы работы с отладчиком.
- watch addr вызывает отладчик всякий раз, когда содержимое addr изменяется, а awatch addr — при чтении или записи в addr.
- rwatch addr реагирует только на чтение, но работает не во всех версиях отладчика.
- info break позволяет просмотреть список установленных точек останова.
- clear удаляет все точки останова.
- clear addr удаляет все точки останова, установленные на данную функцию, адрес или номер строки.
- enable и disable позволяют временно включать и отключать точки останова. Точки останова поддерживают развитый синтаксис условных команд, описание которого можно найти в документации.
- continue ( c ) возобновляет выполнение программы, прерванное точкой останова.
- next N ( n N ) выполняет N следующих строк кода без входа, а step N ( s N ) сo входом во вложенные функции. Если число N не задано, по умолчанию выполняется одна строка.
- nexti и stepi делают то же самое, но работают не со строками исходного текста, а с машинными командами. Обычно они используются совместно с командой display / i $ pc ( x / i $ pc ) , предписывающей отладчику отображать текущую машинную команду. Ее достаточно вызывать один раз за сеанс.
- jump addr передает управление в произвольную точку программы, а call addr / fname вызывает функцию fname с аргументами! Этого нет даже во многих Windows-отладчиках. А как часто оно требуется!
- Другие полезные команды:
- finish — продолжать выполнение до выхода из текущей функции;
- until addr ( u addr ) — продолжать выполнение, пока указанное место не будет достигнуто, при запуске без аргументов — остановить выполнение при достижении следующей команды (актуально для циклов!);
- return — немедленно вернуться в дочернюю функцию.
- выражения (например, p 1 + 2 );
- содержимого переменной ( p my_var );
- содержимого регистра ( p $ eax );
- ячейки памяти ( p * 0x8048424 , p * $ eax ).
- set $ eax = 0 записывает в регистр eax ноль;
- set var my_var = $ ecx присваивает переменной my_var значение регистра ecx;
- set < unsigned char * >0x8048424 = 0xCC записывает по байтовому адресу 0x8048424 число 0xCC.
Короче говоря, приблизительный сеанс работы с GDB выглядит так: грузим программу в отладчик, отдаем ему команду b main , а если не сработает, то b _star t, затем r , после чего отлаживаем программу по шагам ( n / s ), при желании задав параметры ( x / i $ pc ) , чтобы GDB показывал, что у нас выполняется в данный момент.
Выходим из отладчика по команде quit ( q ). Описание остальных команд ищите в документации. Теперь по крайней мере вы не заблудитесь в ней.
Еще есть графический интерфейс gdbgui, который запускается внутри браузера.

Он представляет собой серверное приложение, написанное на Python, и устанавливается через pip:
Как пользоваться gdb
Программа gdb — это популярный отладчик для программ, написанных на языке программирования Си и С++. Отладчик позволяет выполнить программу пошагово, посмотреть значения всех переменных на каждом из этапов выполнения, а если это необходимо, то и дизассемблировать код и посмотреть состояние регистров процессора.
В сегодняшней статье мы рассмотрим как пользоваться gdb для отладки и анализа выполнения программ, написанных на Си. Попытаемся разобраться с основными возможностями программы.
Как пользоваться gdb
1. Установка gdb
Обычно, отладчик устанавливается вместе с другими инструментами для сборки программного обеспечения. Для установки всего необходимого в Ubuntu или Debian достаточно выполнить:
sudo apt install build-essential
Для того чтобы установить отладчик отдельно, выполните:
sudo apt install gdb
В CentOS или Fedora команда установки будет выглядеть следующим образом:
sudo dnf install gdb
А для Arch Linux надо выполнить:
sudo pacman -S gdb
Теперь отладчик gdb установлен и вы можете его использовать.
2. Компиляция программы
Для того чтобы получить максимум полезной информации во время отладки, например, имена переменных и номера строк кода программу следует скомпилировать особым образом. Для примеров из этой статьи мы будем использовать такую небольшую программу на Си, в процессе будем её изменять, но начнём с этого:
#include
int main() int var1 = 0;
int var2 = 2;
char greeting[] = «Hello from losst\n»;
printf(«%s», greeting);
>Для того чтобы всё необходимое было включено в исполняемый файл, программу надо собрать с опцией -g. В данном случае команда будет выглядеть вот так:
gcc -g -o program program.c
Затем вы можете её выполнить:

3. Запуск отладчика
Для того чтобы запустить программу достаточно передать путь к ней отладчику. Какие-либо опции указывать не обязательно:
После запуска отладчика вы попадаете в его командный интерфейс. Программа ещё не запущена, запущен только отладчик, в котором вы можете ею управлять с помощью специальных команд. Вот основные команды gdb:
- break или b — создание точки останова;
- info или i — вывести информацию, доступные значения: break, registers, frame, locals, args;
- run или r — запустить программу;
- continue или c — продолжить выполнение программы после точки останова;
- step или s — выполнить следующую строчку программы с заходом в функцию;
- next или n — выполнить следующую строчку без захода в функцию;
- print или p — вывести значение переменной;
- backtrace или bt — вывести стек вызовов;
- x — просмотр содержимого памяти по адресу;
- ptype — просмотр типа переменной;
- h или help — просмотр справки по команде;
- q или quit — выход из программы.
4. Запуск программы
Для того чтобы запустить программу надо воспользоваться командой run в консоли gdb. Просто выполните:

И программа будет запущена и выполнена. Если вам надо передать программе какие-либо аргументы, то следует их передать команде run, например:
(gdb) run arg1 arg2
Если программа завершилась с ошибкой, вы можете вывести стек вызовов функций для того чтобы узнать в какой именно функции возникла ошибка:
Программа сообщает на какой строчке исходного кода возникла проблема. Чтобы посмотреть весь исходник выполните команду list:

Для того чтобы вызвать ошибку Segmentation Fault и проверить как это работает можете добавить в программу такие строки и перекомпилировать её:
char *buffer = malloc(sizeof(char) * 10);
while(1) *(++buffer) = ‘c’;
>Тут мы выделяем из памяти массив символов размером 10 элементов и заполняем его и память, которая находится за ним символами «с», пока программа не упадёт.
5. Точки останова
Неотъемлемая часть отладки приложения — это точки останова. С помощью них можно остановить выполнение программы на любом месте исходного кода или функции, а затем проанализировать все переменные, а также что происходит с программой. Сначала смотрим исходник программы:

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

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

Для того чтобы выполнить следующую строчку без входа в функцию используйте команду next:

Тогда выполнится следующая строка кода в программе. Если надо войти в функцию и посмотреть что в ней происходит следует использовать команду step:
Для отладки циклов можно устанавливать точки останова на основе условия, например, на 11-той строке, если значение переменной var1 будет 20:
(gdb) break 11 if var1==20

Чтобы этот пример заработал добавьте в код цикла следующую строчку, как на снимке:
Посмотреть все установленные точки останова можно такой командой:

6. Вывод информации
Сами по себе точки останова не очень полезны, но после каждой остановки программы можно посмотреть полностью её состояние и значения всех переменных, а это уже намного интереснее. Для просмотра информации используется команда info, а для вывода значения конкретной переменной — print. Для того чтобы посмотреть значения всех локальных переменных выполните:
(gdb) info locals

А для вывода значений аргументов функции:
Вывести значение определённой переменной можно с помощью print:
Интересно, что с помощью print можно выполнять арифметические операции и их результат не только выводится на экран, но и присваивается внутренней переменной, таким образом его можно будет вывести ещё раз позже или использовать в других вычислениях. Например:
(gdb) print var1+30

Имя временной переменной, куда были записаны данные отображается перед самим результатом, например, в последней команде это $2. Теперь можно ещё раз вывести это значение:

Таким образом вы можете анализировать состояние программы, на каждой точке останова и искать ошибки.
7. Изменение информации
С помощью команды set можно изменить значение переменной прямо во время выполнения программы. Например:
(gdb) break 7
(gdb) run
(gdb) set var2 = 20
(gdb) print var2
8. Вывод типа
С помощью команды ptype вы можете вывести тип переменной. Например:
(gdb) break 7
(gdb) run
(gdb) ptype var2
9. Просмотр адресов
Ещё интереснее исследовать как программы на Си работают с памятью. Команда print может выводить не только выводить значения переменных, но и их адреса в памяти. Приведите программу к такому виду и перекомпилируйте её:
#include
#include
#include
int main(int argc, char *argv[]) int var1 = 0;
int var2 = 2;
char *buffer = malloc(sizeof(char) * 10);
while(var1 < 10)var1++;
*(++buffer) = ‘c’;
>
printf(«%s\n», buffer);
>Запустите отладчик и установите точку останова на девятой строке и запустите программу:
Теперь вы можете вывести адреса всех переменных в памяти с помощью символа &. Например:
(gdb) print &argc
(gdb) print &var1
(gdb) print &buffer
(gdb) print bufferКак видите, аргументы функции находятся в одном месте, локальные переменные в другому, но не очень далеко, а во память выделенная из кучи, на которую указывает указатель buffer — совсем далеко. Можете поменять программу и поэкспериментировать с разным количеством переменных.
10. Просмотр памяти
С помощью команды x или eXamine можно посмотреть содержимое памяти, по определённому адресу. Например, смотрим содержимое переменной var2:

Если вы не знаете адрес переменной, можно передать её имя с оператором &, он извлечет её адрес. Программа выводит шеснадцатиричное значение, и оно обычно мало о чём нам может сообщить. Для того чтобы улучшить ситуацию можно воспользоваться опциями форматирования. Можно указать тип выводимых данных с помощью таких модификаторов:
Также можно указать размер выводимого блока:
Мы пытались вывести переменную типа int. Она занимает обычно четыре байта. Для её корректного вывода используйте такие параметры:

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

Но поскольку там уже не наша переменная, эти данные не имеют смысла. Аналогично всё работает с строками, символами и другими значениями. Только обратите внимание, что если вы будете выводить переменную не одним блоком, то на результат повлияет порядок расположения байт. Значение будет выводиться задом на перед.
11. Справка по программе
Мы рассмотрели основные возможности отладчика gdb. Но если этого вам не достаточно, вы можете посмотреть справку по любой команде программы в самой программе. Для этого используйте команду help. Например, для команды exemine:

Выводы
Теперь вы знаете как пользоваться gdb для отладки своих программ. Обычно, для отладки намного удобнее использовать графический интерфейс среды программирования, но консоль дает больше возможностей и больше гибкости.