Поиск по сайту:

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


Отладчик играет жизненно важную роль в любой системе разработки программного обеспечения. Никто не может сразу написать код без ошибок. В ходе разработки возникают ошибки, которые необходимо устранить для дальнейшего улучшения. Система разработки неполна без отладчика. Учитывая сообщество разработчиков открытого исходного кода, GNU Debugger — их лучший выбор. Он также используется для разработки коммерческого программного обеспечения на платформах типа UNIX.

Отладчик 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 вместо ввода следующий или c . для продолжить и так далее.

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

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

Command

Описание

run

Начать выполнение программы

quit

Выйти из GDB

print expr

Вывести выражение, где expr также может быть именем переменной

next

Перейти на следующую строку

step

Перейти на следующую строку

continue

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

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

Пример сеанса с 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 одним из следующих двух способов:

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;

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

(gdb) b main

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

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

(gdb) b sum.c:11

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

(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 as.

(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.

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

Чтобы получить список всех точек останова, введите информация о точках останова.

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

Здесь есть только одна точка останова и это To. включено отключить точки останова, укажите номер точки останова вместе с командой отключить. Для последующего включения используйте команду 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 выдает вам pid процесса.

pidof <process_name>

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

1. Указав pid вместе с gdb.

gdb -p <pid>

2. Использование команды attach из GDB.

(gdb) attach <pid>

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