Как установить gdb на линукс

Обновлено: 03.07.2024

Оригинал: How to debug C programs in Linux using gdb
Автор: Himanshu Arora
Дата публикации: 16 января 2017 г.
Перевод: А.Панин
Дата перевода: 7 марта 2017 г.

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

Но перед тем, как двинуться дальше, стоит упомянуть о том, что все инструкции и примеры, приведенные в данной статье, были протестированы в системе Ubuntu 14.04 LTS. В статье был использован пример кода на языке C; в качестве командной оболочки использовалась командная оболочка Bash (версии 4.3.11); также стоит сказать о том, что для отладки тестовой программы использовался отладчик GDB версии 7.7.1.

Основные аспекты использования GDB

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

Во-первых, для успешного использования таких отладчиков, как GDB, вам придется компилировать вашу программу таким образом, чтобы компилятор генерировал отладочную информацию, необходимую отладчикам. Например, в случае компилятора GCC, который будет впоследствии использоваться для компиляции примера программы на языке C, вам придется дополнительно передать параметр -g на этапе компиляции кода.

Вы можете получить дополнительную информацию о данном параметре компилятора на его странице руководства .

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

Инструкции по установке отладчика в других дистрибутивах приведены на данной странице .

Теперь, когда вы скомпилировали вашу программу со специальным параметром компилятора для ее подготовки к отладке и установили в систему отладчик GDB, вы можете выполнить программу в режиме отладки с помощью следующей команды:

Хотя данная команда и инициирует запуск отладчика GDB, ваша программа не начнет исполняться сразу же после его запуска. В этот момент у вас имеется возможность задать параметры отладки. Например, вы можете установить точку останова, сообщающую отладчику GDB о том, что следует приостановить исполнение программы на строке с определенным номером или функции.

Для того, чтобы инициировать исполнение вашей программы, вам придется выполнить следующую команду GDB:

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

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

Пример использования GDB

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

В общем, данный код берет каждое значение из массива val , устанавливает это значение в качестве значения целочисленной переменной out , после чего рассчитывает значение переменной tot путем суммирования ее предыдущего значения и результата вычисления 0xffffffff/out .

Итак, для отладки кода в первую очередь следует скомпилировать код программы с использованием параметра компилятора -g . Это команда компиляции:

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

Обратите внимание на приветствие отладчика (gdb) , после которого я ввел команду break 11 .

Теперь я прошу GDB начать исполнение программы:

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

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

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

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

Теперь для подтверждения предположения о том, что имеется проблема, я использую команду GDB s (или step ) вместо c . Это делается потому, что я хочу, чтобы строка 11, на которой на данный момент остановилось исполнение программы, была исполнена, в результате чего исполнение программы может аварийно завершиться.

В результате случается следующее:

Да, приведенный выше вывод подтверждает, что системный сигнал генерируется именно в этой строке. Окончательное подтверждение происходит при попытке повторного исполнения команды s :

Вы можете отлаживать свои программы с помощью GDB аналогичным образом.

Заключение

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

Напишите C-программу a.c с редактором vi терминала с полномочиями root (или терминалом с общими правами):

(1) Добавить информацию об исходном коде в исполняемый файл

Этот процесс завершен gcc:

gcc –o a a.c -g

Эффект опции -o:Импортируйте вывод команды, здесь выведите результат операции gcc -o a.c -g в файл a (имя файла можно настроить) и сохраните его.

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

(2) Введите GDB

Как показано ниже:


GDB обеспечивает оболочечную среду командной строки. Выше (gdb) - приглашение. Введите соответствующую команду GDB за приглашением, чтобы выполнить соответствующую функцию.

(3) Общие команды для отладки GDB

Запустите выполнение программы командой start:

GDB предлагает подготовиться к выполнению шестой строки кода в a.c Затем продолжайте использовать (gdb) для запроса команд, которые необходимо ввести.

[2] Одношаговое выполнение (n)

После команды запуска каждый раз, когда вы вводите n, вы можете выполнять инструкции (после ввода команды нажмите Enter, чтобы указать значение последней введенной команды). Когда программа закончится, вы можете ввести команду quit для выхода из режима GDB.

[3] отладка точки останова GDB

[ breakpoint,продолжить иdisplay ]

Gdb A войдет в режим gdb исполняемой программы, а команда запуска заставляет программу подготовиться к выполнению первого оператора в программе. b 8 - это сокращение от точки останова 8 (параметр точки останова также может быть именем функции, что означает, что для этой функции установлена ​​точка останова), что означает, что точка останова установлена ​​в восьмой строке программы. c - сокращение от continue, что означает, что для продолжения работы программы программа остановится с установленной точкой останова. displayb означает отображение значения b (отмена отображения отменяет отслеживание переменных), а затем введите одностадийную команду отладки n (далее), чтобы продолжить программу.

Видимые точки останова помогают быстро пропустить код без проблем, а затем медленно переходить к проблемному коду и медленно его анализировать. «Точка останова плюс один шаг» - основной метод использования отладчика. Что касается того, где устанавливать точки останова, как узнать, какие коды могут быть пропущены, а какие коды следует проходить медленно, а также с помощью анализа и предположений о явлении ошибки, чтобы определить, прежде чем использовать printf для печати промежуточных результатов, мы должны также проанализировать Куда вставлять printf и какие промежуточные результаты выводить на печать, основная идея отладки та же.

[4]info

Одна отладка может установить несколько точек останова, вы можете использовать команду info для просмотра установленных точек останова:

[5]delete

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

Иногда точку останова можно отключить, не удаляя временно, чтобы ее можно было напрямую включить, когда вы захотите использовать ее в будущем, без необходимости находить строку в коде, где должна быть установлена ​​точка останова. Этот процесс завершается отключением и включением.

[6]Условные точки останова (разбить и запустить)

Функция точки останова GDB очень гибкая, вы также можете установить точку останова, которая будет активирована при выполнении определенного условия, например:

R означает запуск программы с самого начала, и она будет эффективна только при прерывании при условии == 2. a не равно 2, поэтому прерывание недопустимо.

[7] точки наблюдения GDB (часы и с)

Точка остановаКогда выполнение программы достигает определенной строки кода, иТочка наблюденияОн прерывается, когда программа обращается к определенной единице хранения.Если мы не знаем, где была изменена определенная единица хранения, эта точка наблюдения особенно полезна.

Программа выполняется в блоке хранения b, и отображаются значения до и после выполнения этого блока выполнения.

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

Gdb показывает, что segfault появляется в функции _IO_vfscanf. Вы можете увидеть, какая функция вызвала его с помощью команды bt.

[9] основные команды GDB

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

команда

описание

Просмотр всех уровней вызовов функций и параметров

Продолжайте работать, пока не вернется текущая функция, затем остановитесь и дождитесь команды

frame (f) Номер кадра

Выберите кадр стека

Просмотр значения локальных переменных текущего фрейма стека

Перечислите исходный код, затем последнюю позицию следующего, каждая строка - десять строк

номер строки списка

Перечислите исходный код, начиная с строки

имя функции списка

Перечислите исходный код функции

Выполнить следующую строку

Выведите значение выражения, через значение выражения можно изменить значение переменной или вызвать функцию

Выход из среды отладки GDB

Изменить значение переменной

Начните выполнение программы, остановитесь перед первой строкой основной функции и дождитесь команды

Выполнить следующую строку оператора, если есть функция, введите функцию

перерыв (б) номер строки

Установить точку останова на линии

нарушить имя функции

Установить точку останова в начале функции

Установить условную точку останова

Запустите программу непрерывно из текущей позиции

удалить точки останова

Удалить точку останова этого номера

отображаемое имя переменной

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

отключить точки останова

Отключить эту точку останова

включить номер точки останова

Включить эту точку останова

Посмотрите, какие точки останова в настоящее время установлены

Запустите программу непрерывно с самого начала

отменить отображение номера строки

Отменить отображение отслеживания

Установить точку наблюдения

Посмотрите, какие точки наблюдения в настоящее время установлены

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

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

Пошагово можно отлаживать по одной инструкции.

Вы можете отобразить текущие значения всех регистров. Представляя имя регистра в gdb, добавьте перед ним символ $, например, p $ esp может напечатать значение регистра esp.

Интеллектуальная рекомендация


Краткое описание общих функций MPI

содержание 1, основная функция MPI 2, точка-точка функция связи 3, коллективная функция связи 1, основная функция MPI MPI_Init(&argc, &argv) Информировать системы MPI для выполнения всех необх.

Примечание 9: EL выражение


JVM память

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

Проблема сетевого запроса на Android 9.0

вЗапустите Android 9 (API Уровень 28) или вышеНа устройстве операционной системы Android, чтобы обеспечить безопасность пользовательских данных и устройств, использование по умолчанию для зашифрованно.


Учебная запись по Webpack (3) В статье рассказывается о создании webpack4.0.

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

GDB поставляется вместе со сценарием configure , который автоматизирует процесс подготовки GDB к установке; затем вы можете использовать make для построения программы gdb . (20)

Дистрибутив GDB включает весь исходный код, который вам понадобится для GDB, в одном каталоге, имя которого обычно составляется добавлением номера версии к `gdb' .

Например, дистрибутив GDB версии 5.0 находится в каталоге `gdb-5.0' . Этот каталог содержит: gdb-5.0/configure (и файлы поддержки) сценарий для конфигурации GDB и всех поддерживаемых библиотек gdb-5.0/gdb исходные тексты, специфичные для самого GDB gdb-5.0/bfd исходные тексты для библиотеки описания двоичных файлов (Binary File Descriptor) gdb-5.0/include включаемые файлы GNU gdb-5.0/libiberty исходные тексты для `-liberty' библиотеки свободного программного обеспечения gdb-5.0/opcodes исходные тексты библиотеки таблиц кодов операций и дисассемблеров gdb-5.0/readline исходные тексты интерфейса командной строки GNU gdb-5.0/glob исходные тексты подпрограммы GNU сопоставления с образцом имени файла gdb-5.0/mmalloc исходные тексты пакета GNU для выделения памяти

Простейший способ сконфигурировать и собрать GDB состоит в выполнении configure из исходного каталога `gdb- номер-версии ' , который в этом примере есть `gdb-5.0' .

Сперва перейдите в исходный каталог `gdb- номер-версии ' , если вы еще не находитесь в нем; затем запустите configure . Передайте в качестве аргумента идентификатор платформы, на которой будет выполняться GDB.

где платформа ---идентификатор, такой как `sun4' или `decstation' , задающий платформу, на которой будет выполняться GDB. (Часто вы можете опустить платформу ; configure пытается определить корректное значение, изучая вашу систему.)

Выполнение `configure платформа ' и затем make строят библиотеки `bfd' , `readline' , `mmalloc' и `libiberty' , и затем сам gdb . Сконфигурированные исходные файлы, а также двоичные файлы, остаются в соответствующих исходных каталогах.

configure является сценарием оболочки Bourne ( /bin/sh ); если ваша система не распознает это автоматически, когда вы находитесь в другой оболочке, вам может потребоваться выполнить sh явно:

Если вы выполните configure из каталога, содержащего исходные каталоги для нескольких библиотек или программ, например `gdb-5.0' для версии 5.0, configure создает файлы конфигурации для всех подкаталогов низшего уровня (если вы не велите ему не этого делать ключем `--norecursion' ).

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

Например, для версии 5.0, чтобы сконфигурировать только подкаталог bfd , введите:

Вы можете установить gdb куда угодно; он не имеет никаких жестко заданных путей. Однако, вы должны удостовериться, что ваша оболочка (определяемая переменной среды `SHELL' ) доступна всем для чтения. Помните, что GDB использует оболочку для запуска вашей программы--- некоторые системы не позволяют GDB отлаживать дочерние процессы, чьи программы недоступны для чтения.

Если вы хотите запускать версии GDB на нескольких рабочих или целевых машинах, вам нужны различные gdb , скомпилированные для каждой комбинации рабочей и целевой машины. configure разработан так, чтобы облегчить это, позволяя вам создавать каждую конфигурацию в отдельном подкаталоге, а не в исходном каталоге. Если ваша программа make поддерживает возможности `VPATH' (GNU make это делает), вызов make в каждом из этих каталогов строит программу gdb , определенную там.

Чтобы построить gdb в отдельном каталоге, запустите configure с ключем `--srcdir' , для определения, где искать источник. (Вам также нужно определить путь для поиска configure из вашего рабочего каталога. Если путь к configure совпадает с параметром `--srcdir' , ключ `--srcdir' можно опустить; он подразумевается.)

Например, в версии 5.0, вы можете построить GDB в отдельном каталоге для Sun 4 так:

Когда configure строит конфигурацию, используя удаленный каталог с источниками, он создает дерево для двоичных файлов с той же структурой (и используя те же имена), что и дерево каталогов с исходными текстами. В этом примере, вы бы нашли библиотеку Sun 4 `libiberty.a' в каталоге `gdb-sun4/libiberty' , и сам GDB в `gdb-sun4/gdb' .

Одна из распространенных причин построения нескольких конфигураций GDB в отдельных каталогах состоит в том, чтобы конфигурировать GDB для кросс-компиляции (где GDB запускается на одной машине--- рабочей , в то время как отлаживаемые программы выполняются на другой машине--- целевой ). Вы определяете целевую машину кросс-отладки ключем configure `--target= цель ' .

Когда вы выполняете make для построения программы или библиотеки, вы должны выполнять ее из сконфигурированного каталога---того каталога, из которого вы вызывали configure (или из одного из его подкаталогов).

Makefile , который создает configure в каждом исходном каталоге, также выполняется рекурсивно. Если вы ввели make в каталоге с исходными файлами, например в `gdb-5.0' (или в каталоге, сконфигурированном отдельно посредством `--srcdir= имя-каталога /gdb-5.0' ), вы построите все требуемые библиотеки, и затем GDB.

Когда у вас имеется несколько рабочих или целевых конфигураций в отдельных каталогах, вы можете запустить make для них параллельно (например, если они смонтированы по NFS на каждой рабочей машине); они не будут конфликтовать друг с другом.

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

Например, вы можете использовать синоним sun4 как параметр платформа , или как значение цель в ключе --target= цель . Эквивалентное полное имя--- `sparc-sun-sunos4' .

Сценарий configure , сопровождающий GDB, не предоставляет никаких средств для запроса вывода всех поддерживаемых имен рабочих и целевых машин или их сокращений. configure вызывает скрипт оболочки Bourne config.sub для отображения сокращений в полные имена; при желании, вы можете посмотреть сценарий или использовать его для проверки ваших предположений о сокращениях. Например:

config.sub также распространяется в исходном каталоге GDB ( `gdb-5.0' , для версии 5.0).

Здесь приводится обзор ключей и параметров configure , которые наиболее часто используются для построения GDB. configure также имеет несколько других ключей, не представленных здесь. See Info file `configure.info', node `What Configure Does', для полного объяснения configure .

Если хотите, можете вводить ключи с одним `-' , а не с `--' ; но вы можете сокращать имена ключей, если используете `--' . --help Отображает быстрый обзор, как вызывать configure . --prefix= каталог Конфигурировать источник, чтобы устанавливать программы и файлы в подкаталогах ` каталога ' . --exec-prefix= каталог Конфигурировать источник, чтобы устанавливать программы в каталог ` каталог ' . --srcdir= имя-каталога Предупреждение: использование этого ключа требует GNU make или другой программы make , реализующей возможности VPATH .
Используйте этот ключ для создания конфигураций в каталогах, отдельных от исходного каталога GDB. Кроме всего прочего, вы можете использовать его для построения (или поддержки) нескольких конфигураций одновременно в отдельных каталогах. configure записывает файлы, относящиеся к конфигурации, в текущий каталог, но принимает меры, чтобы можно было использовать источники в каталоге имя-каталога . configure создает каталоги внутри рабочего каталога параллельно с исходными каталогами внутри имя-каталога . --norecursion Конфигурировать только тот уровень каталогов, где выполняется configure ; не распространять конфигурацию на подкаталоги. --target= цель Конфигурировать GDB для кросс-отладки программ, выполняемых на указанной цели . Без этого ключа GDB конфигурируется для отладки программ, выполняемых на той же машине ( платформе ), что и сам GDB. Нет никакого удобного способа сгенерировать список всех доступных целей. платформа . Конфигуровать GDB для выполнения на указанной платформе . Нет никакого удобного способа сгенерировать список всех допустимых платформ.

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


В этом коротком туториале мы рассмотрим базовые приёмы работы с GDB, а также посмотрим как можно (и нужно) подготавливать файлы к отладке для GDB.

GDB — переносимый отладчик проекта GNU, который работает на многих UNIX-подобных системах и умеет производить отладку многих языков программирования, включая Си, C++, Free Pascal, FreeBASIC, Ada, Фортран, Python3, Swift, NASM и Rust.

Почему именно GDB? Всё легко, он уже установлен на многих UNIX-подобных системах, лёгок в использовании и поддерживает много языков. Работа с ним оказывается очень лёгкой, а также его можно подключить к VSCode и другим редакторам кода (Включая Vim, NeoVim (ясное дело), Emacs, Atom и далее)

Подготовка файлов

Для примера мы возьмём файлы .cpp и будем проходиться по ним вдоль и поперёк.

Для того чтобы нам пройтись по такому файлу нам нужно скомпилировать его с помощью G++ с использованием флага -g (это действительно важно, без этого флага, программа не будет корректно работать в GDB).

Python-файл вы можете продебажить с помощью этой команды:

Для Java вы просто можете использовать jdb, который уже идёт в комплекте c JDK.

Также, если вам не хочется компилировать всё ручками, вы можете просто использовать сайт OnlineGDB, там просто нужно вставить код и нажать debug, а затем внизу откроется консоль, где вы сможете писать команды.

Использование GDB

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

Теперь нужно посмотреть, где в нашем файле точка вхождения (строка, откуда наша программа начинает свою работу), в случае cpp это метод main() . Находим номер этой строки c помощью команды list и пишем её порядковый номер с буквой b (также можно просто указать имя функции b main тоже работает):

Далее запускаем программу с помощью комманды r :

Также вы можете включить TUI, с помощью комбинации клавиш <Ctrl-x a>

Для того, чтобы посмотреть на какой мы сейчас строке, нужно написать f :

Для того, чтобы сделать шаг, нужно нажать n (от слова next):

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

(В примере нет функции, однако шаг step-in все равно будет работать и с обычными инициализациями, условиями и циклами)

Чтобы узнать какие переменные (локальные) сейчас инициализированны в программе нужно написать комманду info locals :

Чтобы вывести только одну переменную, нужно написать print имя_переменной :

Мы можем также изменить переменную с помощью set :

Мы можем также следить за переменными с помощью watch :

Также, если нужно можно посмотреть что в данный момент находится в регистрах ( info registers ):

Чтобы посмотреть какие в данный момент есть breakpoints (точки останова) нужно написать info breakpoints :

Чтобы удалить точку останова del breakpoint_num :

Чтобы прыгнуть к следующей точке останова нужно нажать c :

Мы можем вызывать функции из программы (локальные) с помощью call :

Чтобы продолжить выполнение функции и остановить программу когда она (функция) завершится нужно написать finish или fin :

Стоит уточнить, что нельзя использовать finish в главном методе.

Чтобы завершить выполнение программы, нужно написать kill :

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

Читайте также: