Categories: Devops

Linux gdb command (program debugging) [Basic Guide]

The gdb command in Linux is a very useful tool for debugging software compiled with GCC.

Using the gdb debugger for the first time

In order for the debugger to work, the software must be compiled with the gcc “-g” option, so the compiler will provide debugging information in the object code.

Example:

$ gcc —wall —g principal.c network.c interface.c —the new ping

The main idea for debugging a program is to enter a breakpoint at the point where you want to start debugging on a given N line of code.

The breakpoint stops the execution of the program at a certain point that you want to examine more carefully.

After entering the breakpoint, the program must be executed within gdb and proceed with the execution, checking the parameters passed to the functions, the type and content of the variables, until the error is found. The error in the source code is then corrected and the program is compiled again.

To use gdb it’s simple:

# gdb 
GNU gdb 5.3.92 executable program
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type 'show copying' to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for details.
This GDB was configured as “i586-suse-linux”...

(gdb)

Its interface is based on Linux commands with relatively simple syntaxes.

Commands can be written in full or in a simplified form, where only the first letters are generally used. Parameters such as line numbers and variable names are passed immediately after the command name.

Let’s look at the most important commands:

To enter a breakpoint on a given line of code:

Break N or B N

Where N is the line of code that you want to stop running the program. To do this, it may be necessary to view the program’s source code.

To remove all breakpoints:

Delete or d

To run the program until the first breakpoint is found:

Run or r

To list the program’s source code:

List or l

To execute the next program instructions. An instruction can be understood as a function:

Next N or N N

Where N is the number of instructions.

To execute the next N lines after the breakpoint:

Step N or S N

To end the program:

Kill or K

To view information about the type of a variable:

What variable or w variable

To view the contents of a variable:

Variable print or variable p

To view the state of a variable at each execution step:

Variable display and l

To view the content of all instantiated variables:

Local info

To view the program registrars:

Info registers

To view the program’s assembly code:

Disassemble

To view the recursion stack:

backtrace or bt

To get help with a command:

Help command or h command

To exit gdb:

Quit or q

Example of debugging a program

Debugging programs without using appropriate tools can be an exhausting and often impossible task. To help with this task, the following is an example of the procedure for discovering problems using GDB.

The following sample program was designed to cause a floating-point calculation error:

#include 
float calculation (int number1, int number2)
{
int difference;
float result;
difference = number1 - number2;
result = number1/difference;
return result;
}
int main (int argc, char *argv [])
{
& & nbsp; int value, divisor, i;
float result, total;
value = 10.1;
divisor = 6;
total = 0;
for (i = 0; i < 10; i++)
{
result = calculation (value, divisor);
total += result;
printf (“%d divided by %d is %f. The sum of the results is %f. n”, value, divisor value, result, total);

divisor++;
value–;
}
return 0;
}

To compile this program saved as “erro.c”:

$ gcc —g error.c —the error

The “-g” option compiles the program with the information needed for debugging.

This program should execute a loop ten times and calculate the cumulative value of successive divisions. However, when running it, an error will abort its execution:

$. /error 
10 divided by 4 is 2,000000. The sum of the results is 2,000,000.
9 divided by 2 is 4,000,000. The sum of the results is 6,000,000.

Floating Point Exception

To perform the debugging it is necessary to run the program through GDB:

$ gdb 
GNU error gdb 5.3.92
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type 'show copying' to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for details.
This GDB was configured as “i586-suse-linux”...

(gdb)

The program can be run within the GDB with the “run” command:

(gdb) run 
Starting program: /root/systems/error
10 divided by 4 is 2,000000. The sum of the results is 2,000,000.
9 divided by 2 is 4,000,000. The sum of the results is 6,000,000.
Program received SIGFPE signal, Arithmetic exception.

0x0804835e in calculation (number1=8, number2=8) at
gdb.c:7 7 result = number1/difference;

The GDB indicated that the program performed an illegal mathematical operation on line 7 precisely in the calculation function:

The values of the variables number1 and number2 are 8. We can list the program’s source code to see what it’s doing with the “list” command:

(gdb) list 
2 float calculation (int number1, int number2)
3 {
4 int difference;
5 float result;
6 difference = number1 - number2;

7 result = number1/difference;
8 return result;
9}
10 int main (int argc, char *argv [])
11 {

The list command will list the code every 10 lines. It can be repeated until all of the code is displayed.

As a first step, it is interesting to examine the content of the variables with the “print” command:

(gdb) print number1 $1 = 8 (gdb) print number2 $2 = 8 (gdb) print difference $3 = 0

In line 7 of the program where the error occurred, it can be seen that the operation “result = number1/difference”. Analyzing the value of the variables and the instruction, it can be deduced that the program is trying to divide by zero.

We can continue processing the program with the “continue” command:

(gdb) continue 
Continuing.
Program terminated with SIGFPE signal, Arithmetic exception.
The program no longer exists.

Because the division by zero error aborts execution, the program will not continue. It will be necessary to use the breakpoints and run the program again. It is interesting to install the breakpoint in the main function before the function calculus is called.

(gdb) list 
10 int main (int argc, char *argv [])
11 {
12 int value, divisor, i;
13 float result, total;
14 value = 10.1;
15 & nbsp; divisor = 6;
16 total = 0;
17 for (i = 0; i < 10; i++)
18 {
19 result = calculation (value, divisor);
20 total += result;
21 & nbsp; printf (“%d divided by %d is %f. The sum of the results is %f. n”, = value, divisor value, result, total);
22 divisor++;
23 value--;
24}
25 return 0;

We can install the stop point on line 12 at the start of the main function and run the program again:

(gdb) break 12 
Breakpoint 1 at 0x8048384: gdb.c file, line 12.

(gdb) run
Starting program: /root/systems/error
Breakpoint 1, main (argc=1, argv=0xbfffd874) at gdb.c:14
14 value = 10.1;

The processing will stop at line 14 which contains significant instructions after line 12. We can advance the processing line by line with the “next” command:

(gdb) next 15 divisor = 6; (gdb) next 16 total = 0; (gdb) next 17 for (i = 0; i < 10; i++)

The contents of the variables can be displayed with the “print” command followed by the variable name:

(gdb) print value $5 = 10 (gdb) print divisor $6 = 6

The value of all the instantiated variables can be seen with the “info locals” command:

(gdb) info locals value = 10 divisor = 6 i = 0 result = -1.99878407 total = 0

The next step is to run the program line by line until the content of the value and divisor variables is 8. The “display” command allows the content of a variable to be displayed with each instruction processed:

(gdb) display value 1: value = 10 (gdb) display divisor 2: divisor = 6

The instructions can be advanced with the “next” command:

(gdb) next 
20 total += result;
2: divisor = 6
1: value = 10
(gdb) next
21 printf (“%d divided by %d is %f. The sum of the results is %f. n”, value, divisor value, result, total);
2: divisor = 6
1: value = 10
(gdb) next
10 divided by 4 is 2,000,000. The sum of the results is 2,000,000.
22 divisor++;
2: divisor = 6
1: value = 10
(gdb) next
23 value--;
2: divisor = 7
1: value = 10
(gdb) next
17 for (i = 0; i < 10; i++)
2: divisor = 7
1: value = 9
(gdb) next
19 & nbsp; result = calculation (value, divisor);
2: divisor = 7
1: value = 9
(gdb) next
20 total += result;
2: divisor = 7
1: value = 9
(gdb) next
21 printf (“%d divided by %d is %f. The sum of the results is %f. n”, value, divisor value, result, total);
2: divisor = 7
1: value = 9
(gdb) next
9 divided by 2 is 4,000,000. The sum of the results is 6,000,000.

22 divisor++;
2: divisor = 7
1: value = 9
(gdb) next
23 value–;
2: divisor = 8
1: value = 9
(gdb) next
17 for (i = 0; i < 10; i++)
2: divisor = 8
1: value = 8

At this point, the calculation function will return dividing by zero. The value of the variable can be changed during execution to overcome the error with the “set” command:

(gdb) info locals value = 8 divisor = 8 i = 1 result = 4 total = 6 (gdb) set value = 10 (gdb) info locals value = 10 divisor = 8 i = 1 result = 4 total = 6

The program will continue processing until it finds another division by zero.

(gdb) next 
19 result = calculation (value, divisor);
2: divisor = 8
1: value = 10
(gdb) next
20 total += result;
2: divisor = 8
1: value = 10
(gdb) next
21 & nbsp; printf (“%d divided by %d is %f. The sum of the results is %f. n”, value, divisor value, result, total);
2: divisor = 8
1: value = 10
(gdb) next
10 divided by 2 is 5,000,000. The sum of the results is 11,000,000.
22 divisor++;
2: divisor = 8
1: value = 10
(gdb) next
23 value--;
2: divisor = 9
1: value = 10
(gdb) next
17 for (i = 0; i < 10; i++)
2: divisor = 9
1: value = 9
(gdb) next
19 & nbsp; result = calculation (value, divisor);
2: divisor = 9
1: value = 9
(gdb) next
Program received SIGFPE signal, Arithmetic exception.

0x0804835e in calculation (number1=9, number2=9) at
gdb.c:7 7 result = number1/difference;

In the case of this example, the program declares variables as integers and does not allow the rest of a division.

GDB is a powerful program debugger. We encourage you to install a graphical interface for it to make it easier to use. Other scrubbers are also available.

Uirá Endy Ribeiro

Uirá Endy Ribeiro is a Software Developer and Cloud Computing Architect with a 23-year career. He has master's degrees in computer science and fifteen IT certifications and is the author of 11 books recognized in the IT world market. He is also Director at Universidade Salgado de Oliveira and Director of the Linux Professional Institute - LPI Director's Board.

Uirá Endy Ribeiro

Uirá Endy Ribeiro is a Software Developer and Cloud Computing Architect with a 23-year career. He has master's degrees in computer science and fifteen IT certifications and is the author of 11 books recognized in the IT world market. He is also Director at Universidade Salgado de Oliveira and Director of the Linux Professional Institute - LPI Director's Board.

Share
Published by
Uirá Endy Ribeiro

Recent Posts

Sudo command on Linux (privilege scale) [Basic Guide]

The sudo command on Linux executes a given command as if it were another user.…

2 years ago

SS command on Linux (investigate the network) [Basic Guide]

The ss command on Linux is extremely useful for investigating sockets, providing various information about…

2 years ago

Free Linux command (memory usage) [Basic Guide]

Free Linux command shows the amount of total memory in use and available, as well…

2 years ago

Linux while command (loop – while) [Basic Guide]

The shell has structures for testing conditions and executing certain program sequences several times (loop),…

2 years ago

Linux fstab file (disk mount setup) [Basic Guide]

The /etc/fstab file stores the configuration of which devices should be mounted and what is…

2 years ago

Netcat command on Linux (Swiss network knife) [Basic Guide]

The Netcat Command in Linux or nc is a utility used to do “almost anything”…

2 years ago

This website uses cookies.