Saturday, November 10, 2007

Using the GNU Debugger

The GNU debugger(gdb) comes standard with any Linux installation(Okay maybe not, but its can be selected during installation).Also, it comes with the Bloodshed Dev-CPP C/CPP IDE for Windows. Its a very useful but often overlooked tool for C/CPP development.Most programmers resort to multiple printfs at various points in the code to trace out the error. This approach seems paleolithic when you see the advantages offered by gdb.
For one thing, the printfs make the code messy.Secondly, debugging is a very painstaking process when using printfs.This comes from personal experience of course.
Also after you are done debugging,you have to cleanup those print statements.
These are just a few reasons.Start using gdb and more will become obvious to you.

Thats why I emphasize the use of gdb.

Now a lot of people have come to me asking me the procedure for using gdb. I guess from now on I can just throw the blog at them

Lets look at the steps involved.
(For Linux only, Bloodshed offers a GUI interface,which is pretty straight forward.If you still want a tute.Leave a comment)

1.Compile with symbol table information

You can use either "cc" or "g++" depending on your language of choice.For the sake of simplicity,we will assume cc for the duration of this discussion.Similar arguments apply to g++.
When compiling use the "-g" option/flag.This allows your program to be debugged by gdb.

Basically, this tells the compiler to store symbol table information (source level symbols) in your
object file or load module.

For example,suppose we are trying to a compile are C source file dfs_ops.c. This file is standalone and does not link with any other object files other than the standard C library.
The Command to execute is

:> cc dfs_ops.c -g -o dfs_ops

This will tell the compiler to compile dfs_ops.c into an executable file dfs_ops and also store the symbol table information in the file.
As is obvious, storing the symbol table in your executable increases its physical size. So make sure you dont do this in your final deliverable.(Which will hopefully be thoroughly tested. :-))

2. Start a debugging session for your program with gdb

Next, you need to enter into a session with gdb, to interactively debug your program with gdb.
This means the program must be started under control of gdb.
To do this you can do either of the following in a shell...

i) :> gdb
In this approach , you start gdb but do not specify any program to debug.In this case you must run a program expicitly from the gdb prompt to start a debugging session.
This can be done as follows.
gdb:> run <program_name>

Here is the name of a program that you want to debug.This could be a full path or just the program name in the current directory.

ii) :> gdb <program_name>

In this approach, you explicitly specify the program which you want to debug.

After you have entered in a session with gdb, you should see a gdb prompt. Similar to this..

gdb:>

3.Setting a breakpoint

Now that you have entered in a session with gdb, using either of the two approaches in step 2, you must set an execution break point.This is a point in the program where the gdb will pause execution and give control to you.You can then perform various actions like looking at variable values,register values, funtion returns,step wise execution etc.
To set a break point, use the "break" command at the gdb prompt.
You can set a break point either by specifying a line number or function name.

gdb:> break <line_num>
gdb:> break <func_name>

Note: Pressing TAB here, will list available functions and class methods

For example :

gdb:> break 80 // Pauses execution at Line 80 w.r.t to the Source file line numbers
gdb:> break main //pause execution when program control enters function main

You can specify multiple break points

More to come...just wait....

No comments: