Debugging code in linux

Как пользоваться gdb

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

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

Как пользоваться gdb

1. Установка gdb

Обычно, отладчик устанавливается вместе с другими инструментами для сборки программного обеспечения. Для установки всего необходимого в Ubuntu или Debian достаточно выполнить:

sudo apt install build-essential

Для того чтобы установить отладчик отдельно, выполните:

В CentOS или Fedora команда установки будет выглядеть следующим образом:

А для Arch Linux надо выполнить:

Теперь отладчик gdb установлен и вы можете его использовать.

2. Компиляция программы

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

#include
int main() int var1 = 0;
int var2 = 2;
char greeting[] = «Hello from losst\n»;
printf(«%s», greeting);
>

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

Затем вы можете её выполнить:

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, например:

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

Читайте также:  Microsoft word and linux

Программа сообщает на какой строчке исходного кода возникла проблема. Чтобы посмотреть весь исходник выполните команду list:

Для того чтобы вызвать ошибку Segmentation Fault и проверить как это работает можете добавить в программу такие строки и перекомпилировать её:

char *buffer = malloc(sizeof(char) * 10);
while(1) *(++buffer) = ‘c’;
>

Тут мы выделяем из памяти массив символов размером 10 элементов и заполняем его и память, которая находится за ним символами «с», пока программа не упадёт.

5. Точки останова

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

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

Например, давайте установим точку останова на восьмой строчке исходника:

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

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

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

Для отладки циклов можно устанавливать точки останова на основе условия, например, на 11-той строке, если значение переменной var1 будет 20:

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

Посмотреть все установленные точки останова можно такой командой:

6. Вывод информации

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

А для вывода значений аргументов функции:

Вывести значение определённой переменной можно с помощью print:

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

Имя временной переменной, куда были записаны данные отображается перед самим результатом, например, в последней команде это $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);
>

Читайте также:  Linux shell создать файл

Запустите отладчик и установите точку останова на девятой строке и запустите программу:

Теперь вы можете вывести адреса всех переменных в памяти с помощью символа &. Например:

(gdb) print &argc
(gdb) print &var1
(gdb) print &buffer
(gdb) print buffer

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

10. Просмотр памяти

С помощью команды x или eXamine можно посмотреть содержимое памяти, по определённому адресу. Например, смотрим содержимое переменной var2:

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

Также можно указать размер выводимого блока:

Мы пытались вывести переменную типа int. Она занимает обычно четыре байта. Для её корректного вывода используйте такие параметры:

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

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

11. Справка по программе

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

Выводы

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

Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.

Источник

GNU Debugger or GDB: A Powerful Source Code Debugging tool for Linux Programs

A debugger plays a vital role in any software development system. Nobody can write a bug-free code all at once. During the course of development, bugs are being raised and needs to be solved for further enhancement. A development system is incomplete without a debugger. Considering the open source developers community, GNU Debugger is their best choice. It is also used for commercial software development on UNIX type platforms.

GNU Debugger Tool

GNU Debugger, also known as gdb, allows us to sneak through the code while it executes or what a program was trying to do at the moment before it crashed. GDB basically helps us to do four main things to catch flaws in the source code.

  1. Start the program, specifying arguments that may affect the general behavior.
  2. Stop the program on specified conditions.
  3. Examine the crash or when program was stopped.
  4. Change the code and to experiment with the modified code instantaneously.

We can use gdb to debug programs written in C and C++ without much effort. As of now support for other programming languages like D, Modula-2, Fortran are partial.

Читайте также:  Linux alternatives to windows software

Getting started with GNU Debugger or GDB

GDB is invoked using the gdb command. On issuing gdb, it displays some information about platform and drops you into the (gdb) prompt as shown below.

Sample Output
GNU gdb (GDB) Fedora 7.6.50.20130731-19.fc20 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word". (gdb)

Type help list to out the different classes of commands available inside gdb. Type help followed by a class name for a list of commands in that class. Type help all for the list of all commands. Command name abbreviations are allowed if they are unambiguous. For example, you can type n instead of typing next or c for continue and so on.

Most Commonly used GDB Commands

Commonly used gdb commands are listed in the following table. These commands are to be used from the gdb command prompt (gdb).

Источник

How Can I debug a C program on Linux?

I am writing a C language program on Linux and compiling it using GCC. I also use a Make file. I want to debug my program. I don’t want to debug a single file, I want to debug the whole program. How can I do it?

4 Answers 4

Compile your code with the -g flag, and then use the gdb debugger. Documentation for gdb is here, but in essence:

gcc -g -o prog myfile.c another.c 

If you want a user-friendly GUI for gdb, take a look at DDD or Insight.

There’s also a graphical interface for gdb named ddd that can be useful if you’re having a hard time with getting used to gdb.

I guess that you are building from the command line.

You might want to consider an IDE (Integrated Development Environment), such as KDevelop or Eclipse, etc (hint — Eclipse . ECLPISE . E C L I PS E).

Use an IDE to edit your code, refactor your code, examine your code — class tree, click a variable, class or function to jump to declaration, etc, etc

  • run your code in the IDE
  • set breakpoints to stop at particular lines
  • or just step through, a line at a time
  • examine the call stack to see how you go there
  • examine the current values of variables, to understand your problem
  • change the values of those variables and run to see what happens
  • and more, more, more

p.s as wasatz mentioned- DDD is great — for visualizing the contents of arrays/matrices, and — imo — especially if you have linked lists

Источник

Оцените статью
Adblock
detector