Отладчик GNU или GDB: мощный инструмент для отладки исходного кода программ в Linux

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.

Debugging source code with GNU Debugger

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

  1. Запустить программу, указав аргументы, которые могут повлиять на общее поведение.
  2. Остановить программу при определенных условиях.
  3. Изучить аварийное завершение программы или остановку программы.
  4. Изменить код и экспериментировать с измененным кодом мгновенно.

Мы можем использовать gdb для отладки программ, написанных на C и C++ без особых усилий. В настоящее время поддержка других языков программирования, таких как D, Modula-2, Fortran, частичная.

Начало работы с отладчиком GNU или GDB

GDB вызывается с помощью команды gdb. При выполнении команды gdb отображается некоторая информация о платформе и вы попадаете в приглашение (gdb), как показано ниже.

[root@fedora20 ~]# gdb
Пример вывода
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 <http://gnu.org/licenses/gpl.html> 
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: 
<http://www.gnu.org/software/gdb/bugs/>. 
Find the GDB manual and other documentation resources online at: 
<http://www.gnu.org/software/gdb/documentation/>. 
For help, type "help". 
Type "apropos word" to search for commands related to "word". 
(gdb)

Введите help list, чтобы получить информацию о различных классах команд, доступных в gdb. Введите help , за которым следует имя класса, для списка команд в этом классе. Введите help all для списка всех команд. Разрешены сокращения имени команды, если они неоднозначны. Например, вы можете набрать n вместо того, чтобы печатать next или c для continue и так далее.

Наиболее часто используемые команды GDB

Общие gdb команды перечислены в следующей таблице. Эти команды должны использоваться из приглашения командной строки gdb (gdb).

Command
Description
run
Start a program execution
quit
Quit gdb
print expr
Print expression where expr may be a variable name too
next
Go to next line
step
Step into next line
continue
Continue from the current line till the end of program or next break point

Обратите внимание на разницу между двумя командами step и next. Команда next не входит в функцию, если следующая строка – вызов функции. В то время как команда step может войти внутрь функции и увидеть, что там происходит.

A sample session with GDB

Рассмотрим следующий исходный код.

// sum.c
#include <stdio.h> 

int sum (int a, int b) { 
	int c; 
	c = a + b; 
	return c; 
} 

int main() { 
	int x, y, z; 
	printf("\nEnter the first number: "); 
	scanf("%d", &x); 
	printf("Enter the second number: "); 
	scanf("%d", &y); 
	z = sum (x, y); 
	printf("The sum is %d\n\n", z); 
	return 0; 
}

Чтобы отлаживать выходной файл, его нужно скомпилировать с помощью -g опции в gcc следующим образом.

$ gcc -g sum.c -o sum

Выходной файл sum можно подключить к gdb одним из следующих 2 способов:

1. Указав выходной файл в качестве аргумента для gdb.

$ gdb sum

2. Запустив выходной файл в gdb с помощью команды file.

$ gdb
(gdb) file sum

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

(gdb) list
1	#include <stdio.h>   
2	 
3	int sum (int a, int b) { 
4		int c; 
5		c = a + b; 
6		return c; 
7	} 
8	 
9	int main() { 
10		int x, y, z;

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

(gdb) b main

Примечание: Я использовал сокращение b для break.

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

(gdb) b sum.c:11

Теперь пройдите по строкам кода, используя команду next или n. Важно отметить, что команда next не переходит внутрь кода функции, если точка останова не установлена в функции. Давайте попробуем команду print сейчас. Установите точку останова на функции sum, как показано ниже.

(gdb) b sum 
Breakpoint 1 at 0x4005aa: file sum.c, line 5. 
(gdb) r 
Starting program: /root/sum 

Enter the first number: 2 
Enter the second number: 3 

Breakpoint 1, sum (a=2, b=3) at sum.c:5 
5		c = a + b; 
(gdb) p a 
$1 = 2 
(gdb) p b 
$2 = 3
(gdb) c 
Continuing. 
The sum is 5 

[Inferior 1 (process 3444) exited normally]

Если программа, которую вы запускаете, требует параметры командной строки, укажите их вместе с командой run.

(gdb) run   . . .

Файлы общих библиотек, связанные с текущей запущенной программой, могут быть перечислены как.

(gdb) info share 
From                To                  Syms Read   Shared Object Library 
0x00000035a6000b10  0x00000035a6019c70  Yes         /lib64/ld-linux-x86-64.so.2 
0x00000035a641f560  0x00000035a6560bb4  Yes         /lib64/libc.so.6

Изменение переменных

GDB также способен изменять переменные во время выполнения программы. Давайте попробуем это. Как упоминалось выше, установите точку останова на строке 16 и запустите программу.

(gdb) r 
Starting program: /root/sum 

Enter the first number: 1 
Enter the second number: 2 

Breakpoint 1, main ( ) at sum.c:16 
16		printf("The sum is %d\n\n", z); 
(gdb) set z=4 
(gdb) c 
Continuing. 
The sum is 4

Теперь a = 1, b = 2, и результат должен быть z = 3. Но здесь мы изменили конечный результат на z = 4 в главной функции. Таким образом, отладка может быть упрощена с помощью gdb.

Включение/отключение точек останова

Для получения списка всех точек останова введите info breakpoints.

(gdb) info breakpoints 
Num     Type           Disp Enb Address            What 
1       breakpoint     keep y   0x00000000004005c2 in main at sum.c:11

Здесь есть только одна точка останова, и она включена. Чтобы отключить точки останова, укажите номер точки останова вместе с командой disable. Для включения используйте команду enable.

(gdb) disable 1 
(gdb) info breakpoints 
Num     Type           Disp Enb Address            What 
1       breakpoint     keep n   0x00000000004005c2 in main at sum.c:11

Можно также удалить точки останова с помощью команды delete.

Отладка запущенных процессов

В системе GNU/Linux много процессов, которые работают в фоновом режиме. Чтобы отлаживать выполняющийся процесс, сначала нам нужно найти идентификатор этого процесса. pidof команда предоставляет вам идентификатор процесса.

$ pidof <process_name>

Теперь нам нужно присоединить этот идентификатор к gdb. Есть 2 способа.

1. Указав идентификатор процесса вместе с gdb.

$ gdb -p <pid>

2. Используя команду attach из gdb.

(gdb) attach <pid>

Вот и все. Это только основы gdb для успешного старта отладки и в нем гораздо больше возможностей, чем то, что было объяснено выше. Например, мы можем отлаживать, используя информацию о стеке, переменные окружения и многое другое. Попробуйте поиграть со всем этим…

Source:
https://www.tecmint.com/debug-source-code-in-linux-using-gdb/