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

Debugging source code with GNU Debugger

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.

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.

[[email protected] ~]# gdb
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 <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)

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

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

Note the difference between the two commands step and next. The next command does not go inside function if next line is a function call. Whereas step command can go in inside function and see what happens there.

A sample session with GDB

Consider the following source code.

// 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; 
}

In order to debug the output file we need to compile the same with -g option to gcc as follows.

$ gcc -g sum.c -o sum

The output file sum can be attached to gdb via either of the following 2 ways:

1. By specifying the output file as an argument to gdb.

$ gdb sum

2. Running output file inside gdb using file command.

$ gdb
(gdb) file sum

The list command lists lines in the source code file and moves the pointer. So first list will display the first 10 lines and next list displays the next 10 and so on.

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

To start execution, issue the run command. Now the program gets executed normally. But we forgot to put some breakpoints in the source code for debugging, right? These breakpoints can be specified for functions or at specified lines.

(gdb) b main

Note: I have used an abbreviation b for break.

After setting break point at main function, rerunning the program will stop at the line 11. The same thing can be made into effect if the line number is known before.

(gdb) b sum.c:11

Now step through the lines of code using the next or n command. It is important to note that next command does not go inside function code unless a break point is set on the function. Let’s try out the print command now. Set break point on function sum as below.

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

If the program being run requires command line parameters then provide the same along with the run command as.

(gdb) run   . . .

Shared library files associated with the current running program can be listed as.

(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

Modifying Variables

GDB is also capable of modifying variables throughout the execution of program. Let’s try this out. As mentioned above set break point at line 16 and run the program.

(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

Now a = 1, b = 2 and result should be z = 3. But here we changed the final result to z = 4 in the main function. In this way debugging can be made easier using gdb.

Enable/Disable Breakpoints

To get the list of all breakpoints type info breakpoints.

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

Here there is only one break point and it is To. enabled disable the breakpoints specify the breakpoint number along with the disable command. To enable afterwards use the enable command.

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

You can also delete the breakpoints with delete command.

Debugging running Processes

Numerous processes are running in background in a GNU/Linux system. To debug a running process first of all we need to find the process id of that particular process. pidof command gives you the pid of a process.

$ pidof <process_name>

Now we need to attach this pid to gdb. There are 2 ways.

1. By specifying pid along with gdb.

$ gdb -p <pid>

2. Using attach command from gdb.

(gdb) attach <pid>

That’s all for now. These are only basics of gdb to get a good start in debugging source code and it is much more than the things explained above. For example, we can debug using the stack information, environment variables and lot more. Try to play around with all these stuffs…

Best Affordable Linux and WordPress Services For Your Business
Outsource Your Linux and WordPress Project and Get it Promptly Completed Remotely and Delivered Online.

If You Appreciate What We Do Here On TecMint, You Should Consider:

  1. Stay Connected to: Twitter | Facebook | Google Plus
  2. Subscribe to our email updates: Sign Up Now
  3. Get your own self-hosted blog with a Free Domain at ($3.45/month).
  4. Become a Supporter - Make a contribution via PayPal
  5. Support us by purchasing our premium books in PDF format.
  6. Support us by taking our online Linux courses

We are thankful for your never ending support.

Anoop C S

I am basically a FOSS enthusiast interested in working under GNU/Linux and system administration. Looking forward to become a part of an open source initiative. Currently pursue Computer Science & Engineering.

Your name can also be listed here. Got a tip? Submit it here to become an TecMint author.

RedHat RHCE and RHCSA Certification Book
Linux Foundation LFCS and LFCE Certification Preparation Guide

You may also like...

3 Responses

  1. ajay says:

    Thank you for such a great tutorial.
    Its well explained

  2. littlenoodles says:

    I used to use the dbx debugger on AIX, and it had a really nice feature that I wish gdb had. There was a ‘call’ command that allowed you to call any function in the app from a breakpoint. I would add functions to my libraries specifically to allow printing out complex data in variables during debugging – and then use another nice dbx feature, macros, to define simple shortcuts to make it all easy. For example, the system in question used a weird binary date format, but the date library had a DisplayFormattedDate(mydate) function, and I set up a dd(x) alias to it to make this even easier. And of course there was more complex binary stuff similarly displayable. Of course, a nice graphical IDE that wrapped dbx might’ve been even nicer, but this call thing was really powerful. It’d be nice if gdb had something similar – and if IDE’s based on gdb gave you a way to access it (I think kdebug has a command window where you could do that).

  3. Bill Lawhorn says:

    Thanks for this great introductory tutorial … just what I needed.

Got something to say? Join the discussion.

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.