gdb debugger tutorial part 1 of 3

GDB Tutorial Command Line Walkthrough : Part 1

Part 2
Part 3

Master command line debugging with GDB

Whether you’ve spent hours fine-tuning printf statements to track down a persistent bug, or you just fancy impressing someone with your command line skills, GDB has the answers.

Introduction

This tutorial will take a walk-through approach to finding the bugs in two short C programs, covering around two dozen of the most useful GDB commands. This will get you used to using GDB against real code, which should leave you with enough knowledge to confidently approach debugging larger applications.

A word about GDB

You can skip this bit if you’re desperate to get started 🙂

The GNU Debugger (or GDB) is an incredibly powerful program. It may be free but don’t underestimate its capabilities. It can be used on dozens of processors, running a wide variety of Unix-based operating systems, from small embedded projects to large, multi-threaded applications, and it has a wide range of followers, from large teams of software professionals to students. Its appeal isn’t just in the price tag (did I mention it was free?), as GDB is just as capable, if not more so, than many commercial debuggers out there. The trick, as always, is in learning how to use it.

A lot of people are put off by the command line interface, especially those who are used to using a graphical front end that allows you to see variable values and switch threads with one mouse click. While there are GUIs available for GDB, and support for it in many IDEs, including SlickEdit, Eclipse and CodeBlocks, once you have learnt how to use it in its raw form, you will find that it is elegant, fast and robust.

Getting ready

Fedora should have GDB installed by default, but if you have an older or minimal distro, you can install it with:

yum install gdb

For this tutorial, you will also need the gcc compiler, which again you can install with yum:

yum install gcc

Ubuntu users can make sure they have the compiler and debugger by running:

sudo apt-get install build-essential

Simple first example

Right, let’s write some bad code and see what GDB can do. We’ll start gently with a very simplistic example. Compile the code in Listing 1 (you can copy or download the code from the bottom of this page):

gcc -g add.c -o add

The -g option tells gcc to include debugging information in the executable. If you run this program, you’ll see that it tells you:

Sum of 200 and 800 is 160000

Let’s use GDB to see what’s happening. On the command line, in the same directory as your executable, start up the debugger with your program name as an argument:

gdb add

You will see a (gdb) prompt, ready for the next instruction. For reference, the screenshot below displays the full output of the commands that follow.

gdb debugging session

GDB commands are usually whole words, but most of them have an abbreviated form. In this tutorial, I have used the abbreviated forms of all commands, where they apply, as this is a much more efficient way to work (much less typing!). For the most part, the longer form is obvious, but where it isn’t, I’ve added it in brackets so you know exactly what the abbreviation stands for. To make a start, insert a breakpoint at the main function:

(gdb) b main

Then run the program by typing r. If you wanted or needed to pass any command line arguments to your program, you would include them here, after the r. Press Return and GDB runs the program until it enters main, at which point it stops and waits for your next command. You can see it prints out the line of source code that is about to be executed.

Let’s move on by typing n. This moves us to the next line of code (and steps over any function calls). Now try pressing the Return key without any commands. GDB repeats the last command entered, so it moves us on to the next line again.

In the source code, our printf statement calls an Add() function, which might be a good place to look. Use the s command to step into the function. GDB enters Add() and shows the line that multiplies i by j. This is the source of our error, so now we know what to change to fix the problem.

If you enter a function and want to step back out again, use the command finish (which has no short form).

You can stop debugging your program with the ki command to kill it, which leaves you in GDB ready for another session; or you can exit GDB completely at any point with q for quit.

Now you’ve got the basics under your belt, let’s move on to Part 2.

Listing 1

Copy and paste, or download the add.c file here.

/* add.c  
 * Adds two integers and prints the result 
 */

#include <stdio.h>

int Add(int i, int j);

int main()
{
    int i = 200;
    int j = 800;
    printf("Sum of %d and %d is %d\n", i, j, Add(i, j));
    return 0;
}

int Add(int i, int j)
{
    return i * j;
}