How to debug a program using GDB in Linux ?

In this post, we will cover all basics how to use gdb for debugging any binary program and what all options available during debugging.

Create Program for Debugging
To understand gdb working and its options, we will create a sample C program below and then debug it.

[root@nglinux c_programs]# cat 2forloop.c 
#include 
int main()
{
    int num, count, sum = 0;

    printf("Enter a positive integer: ");
    scanf("%d", &num);

  //for loop terminates when value of n is less than count
      for(count = 1; count <= num; ++count)
          {
                  sum += count;
                      }
 
                          printf("Sum = %d", sum);
 
                              return 0;
                              }

[root@nglinux c_programs]# ./a.out 
Enter a positive integer: 4
Sum = 10[root@nglinux c_programs]# 

Start Debugging

1. Compile the program using -g option to include debugging symbols.

[root@nglinux c_programs]# gcc -g 2forloop.c 

[root@nglinux c_programs]# ls -ltr
total 20
-rw-r--r--. 1 root root   58 Aug  4 19:34 1hello.c
-rw-r--r--. 1 root root  417 Aug  5 04:22 2forloop.c
-rwxr-xr-x. 1 root root 6098 Aug  5 04:22 a.out
[root@nglinux c_programs]# 

2. Run GNU Debugger with the compiled object code to debug the program.

[root@nglinux c_programs]# gdb a.out 
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-92.el6)
Copyright (C) 2010 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 "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /root/c_programs/a.out...done.
(gdb)

3. Start the program execution

(gdb) start
Temporary breakpoint 1 at 0x804841d: file 2forloop.c, line 4.
Starting program: /root/c_programs/a.out 

Temporary breakpoint 1, main () at 2forloop.c:4
4	    int num, count, sum = 0;

4. List the program

(gdb) list
1	#include 
2	int main()
3	{
4	    int num, count, sum = 0;
5	
6	    printf("Enter a positive integer: ");
7	    scanf("%d", &num);
8	
9	  //for loop terminates when n is less than count
10	      for(count = 1; count <= num; ++count)

5. Press enter to repeat the last command and list the next 10 lines of code.

(gdb) 
11	          {
12	                  sum += count;
13	                      }
14	 
15	                          printf("Sum = %d", sum);
16	 
17	                              return 0;
18	                              }
(gdb) 
Line number 19 out of range; 2forloop.c has 18 lines.
(gdb) 

6. Debug program using step and next commands.

Since we came to the end of the program, re-run the program using start command again.
(gdb) start
Temporary breakpoint 2 at 0x804841d: file 2forloop.c, line 4.
Starting program: /root/c_programs/a.out 

Temporary breakpoint 2, main () at 2forloop.c:4
4	    int num, count, sum = 0;
(gdb) step
6	    printf("Enter a positive integer: ");
(gdb) next
7	    scanf("%d", &num);
(gdb) 

7. Print local variables using "p" and "info locals" command.

(gdb) next
Enter a positive integer: 4
10	      for(count = 1; count <= num; ++count)
(gdb) p count 
$7 = 134513835
(gdb)

(gdb) info locals 
num = 4
count = 134513835
sum = 0
(gdb) 

8. Step by Step Compile and check the local variables value.

(gdb) next
10	      for(count = 1; count <= num; ++count)
(gdb) next
12	                  sum += count;
(gdb) 
10	      for(count = 1; count <= num; ++count)
(gdb) 
12	                  sum += count;
(gdb) 
10	      for(count = 1; count <= num; ++count)
(gdb) 
12	                  sum += count;
(gdb) info locals
num = 4
count = 4
sum = 6
(gdb) 
num = 4
count = 4
sum = 6
(gdb) next
10	      for(count = 1; count <= num; ++count)
(gdb) 
15	                          printf("Sum = %d", sum);
(gdb) info locals
num = 4
count = 5
sum = 10
(gdb) next
17	                              return 0;
(gdb) 
18	                              }
(gdb) 


(gdb) 
Sum = 10
Program exited normally.

9. Check memory location
We can check the memory location of any variable using "x" command.
The first column value is the location and the second column value is the data.

(gdb) info locals
num = 134513504
count = 134513835
sum = 10817524

(gdb) x num
0x8048360 <_start>:	0x895eed31

(gdb) next
6	    printf("Enter a positive integer: ");
(gdb) 
7	    scanf("%d", &num);
(gdb) 
Enter a positive integer: 4
10	      for(count = 1; count <= num; ++count)
(gdb) info locals
num = 4
count = 134513835
sum = 0

(gdb) x num
0x4:	Cannot access memory at address 0x4
(gdb) x count
0x80484ab <__libc_csu_init+11>:	0x1251c381
(gdb) x sum
0x0:	Cannot access memory at address 0x0
(gdb) 

If you have observed above the location data of any variable can be read in starting, however once the variable is initialized, the debugger is not able to get its location.

10. watch and rwatch command

(gdb) watch sum
Hardware watchpoint 4: sum
(gdb) next
12	                  sum += count;
(gdb) 
Hardware watchpoint 4: sum

Old value = 0
New value = 1
main () at 2forloop.c:10
10	      for(count = 1; count <= num; ++count)
(gdb) 
12	                  sum += count;
(gdb) 
Hardware watchpoint 4: sum

Old value = 1
New value = 3
main () at 2forloop.c:10
10	      for(count = 1; count <= num; ++count)
(gdb) 

11. Set a breakpoint at line 11:- Return to debugger without executing next line now.

(gdb) break 11
Breakpoint 5 at 0x8048451: file 2forloop.c, line 11.
(gdb) 

12. Checking all breakpoints and watchpoints

(gdb) info watch
Num     Type           Disp Enb Address    What
4       hw watchpoint  keep y              sum
	breakpoint already hit 2 times

(gdb) info break
Num     Type           Disp Enb Address    What
4       hw watchpoint  keep y              sum
	breakpoint already hit 2 times
5       breakpoint     keep y   0x08048451 in main at 2forloop.c:11
(gdb) 

Deleting breakpoint
(gdb) info break
Num     Type           Disp Enb Address    What
4       hw watchpoint  keep y              sum
	breakpoint already hit 2 times
5       breakpoint     keep y   0x08048451 in main at 2forloop.c:11
(gdb) delete break 5
(gdb) info break
Num     Type           Disp Enb Address    What
4       hw watchpoint  keep y              sum
	breakpoint already hit 2 times
(gdb) 

13. Get all call frames/functions of our program.

bt - show the call frames for your program
(gdb) bt
#0  main () at 2forloop.c:10
(gdb) 

14. Switch to a particular frame/function of our program.

frame # - set the current frame to #. Variables you reference etc. will be those within that context.

(gdb) frame
#0  main () at 2forloop.c:10
10	      for(count = 1; count <= num; ++count)
(gdb) 

15. Quit the debugger

(gdb) q
A debugging session is active.

	Inferior 1 [process 6031] will be killed.

Quit anyway? (y or n) y
[root@nglinux c_programs]# 

Leave a Reply

avatar
  Subscribe  
Notify of