This post has already been read 2705 times!

GDB

A debugging tool to debug errors in C and C++ programs. A debugger is the best friend of a software programmer.This tutorial assumes you already know how to program in C and C++ and you can compile and execute programs.

GNU Debugger which is called gdb is the most popular debugger for UNIX systems to debug C and C++ Programs.

GNU Debugger helps you in finding out followings:
If a core dump happened then what statement or expression did the program crash on?
If an error occurs while executing a function, what line of the program contains the call to that function, and what are the parameters?
What are the values of program variables at a particular point during execution of the program?
What is the result of a particular expression in a program?

How GDB Debugs?
GDB allows you to do things like run the program up to a certain point then stop and print out the values of certain variables at that point, or step through the program one line at a time and print out the values of each variable after executing each line.

GDB uses a simple command line interface.
Note the Followings:

Before you go for installtion,check if you already have gdb installed on your Unix system by issuing following command

$gdb -help

If GDB is installed then it will display all the available options within your GDB. If GDB is not installed then proceed for a fresh installation.

Its very easy to install GDB on your system. This session will guide you steps by step to install GDB.

Make sure you have the prerequisites for installing gdb:
An ANSI-compliant C compiler ( gcc is recommended - note that gdb is capable of debugging code generated by other compilers )
115 MB of free disk space on the partition you're going to build gdb on.
20 MB of free disk space on the partition you're going to install gdb on.
GNU's decompression program, gzip
The make utility - the GNU version is known to work without a problem, others probably do as well.

Download the gdb source distribution from ftp.gnu.org/gnu/gdb. (I used gdb-6.6.tar.gz for these instructions.) Place the distribution files in your build directory.

In your build directory, uncompress gdb-6.6.tar.gz and extract the source files from the archive. Once the files have finished extracting, change your working directory to the the gdb-6.6 directory that was automatically created in your build directory.

$ build> gzip -d gdb-6.6.tar.gz

$ build> tar xfv gdb-6.6.tar

$ build> cd gdb-6.6

Run the configure script to configure the source tree for your platform.

$ gdb-6.6> ./configure

Build gdb using the make utility.

$ gdb-6.6> make

Login as root, and install gdb using following command.

$ gdb-6.6> make install

If desired, disk space can be reclaimed by deleting the gdb build directory and archive file after installation is complete.

$ gdb-6.6> cd ..

$ build> rm -r gdb-6.6

$ build> rm gdb-6.6.tar

Now gdb is now installed on your system and ready for use.

A Debugging Symbol Table maps instructions in the compiled binary program to their corresponding variable, function, or line in the source code. This mapping could be something like:

Program instruction => item name, item type, original file, line number defined.

Symbol tables may be embedded into the program, or stored as a separate file. So if you plan to debug your program then it is required to create Symbol table which will have required information to debug the program.

We can infer a few facts about symbol tables:

A symbol table works for a particular version of the program –if the program changes, a new table must be made.
Debug builds are often larger and slower than retail (non-debug) builds; debug builds contain the symbol table and other ancillary information.
If you wish to debug a binary program you did not compile yourself, you must get the symbol tables from the author.

To let GDB be able to read all that information line by line from the symbol table, we need to compile it a bit differently. Normally we compile things as:

gcc hello.cc -o hello

Instead of doing this, we need to compile with the -g flag as such:

gcc -g hello.cc -o hello

There is a big list of GDB commands but following commands are among the more useful gdb commands:

b main - Put a breakpoint at the beginning of the program
b - Put a breakpoint at the current line
b N - Put a breakpoint at line N
b +N - Put a breakpoint N lines down from the current line
b fn - Put a breakpoint at the beginning of function "fn"
d N - delete breakpoint number N
info break - list breakpoints
r - Run the program until a breakpoint or error
c - continue running the program until the next breakpoint or error
f - Run until the current function is finished
s - run the next line of the program
s N - run the next N lines of the program
n - like s, but don't step into functions
u N - run until you get N lines in front of the current line
p var - print the current value of the variable "var"
bt - print a stack trace
u - go up a level in the stack
d - go down a level in the stack
q - Quit gdb

Getting Started: Starting and Stopping

gcc -g myprogram.c
Compiles myprogram.c with the debugging option (-g). You still get an a.out, but it contains debugging information that lets you use variables and function names inside GDB, rather than raw memory locations (not fun).
gdb a.out
Opens GDB with file a.out, but does not run the program. You’ll see a prompt (gdb) - all examples are from this prompt.
r
r arg1 arg2
r < file1 Three ways to run “a.out”, loaded previously. You can run it directly (r), pass arguments (r arg1 arg2), or feed in a file. You will usually set breakpoints before running. help h breakpoints List help topics (help) or get help on a specific topic (h breakpoints). GDB is well-documented. q - Quit GDB

Stepping Through Code

Stepping lets you trace the path of your program, and zero in on the code that is crashing or returning invalid input.

l
l 50
l myfunction
List 10 lines of source code for current line (l), a specific line (l 50), or for a function (l myfunction).
next
Run program until next line, then pause. If the current line is a function, execute the entire function, then pause. Next is good for walking through your code quickly.
step
Run the next instruction, not line. If the current instructions is setting a variable, it is the same as next. If it’s a function, it will jump into the function, execute the first statement, then pause. Step is good for diving into the details of your code.
finish
Finish executing the current function, then pause (also called step out). Useful if you accidentally stepped into a function.

Breakpoints and Watchpoints

Breakpoints are one of the keys to debugging. They pause (break) a program when it reaches a certain location. You can examine and change variables, then resume execution. This is helpful when seeing why certain inputs fail, or testing inputs.

break 45
break myfunction
Set a breakpoint at line 45, or at myfunction. The program will pause when it reaches the breakpoint.
watch x == 3
Set a watchpoint, which pauses the program when a condition changes (when x == 3 changes). Watchpoints are great for certain inputs (myPtr != NULL) without having to break on every function call.
continue
Resume execution after being paused by a breakpoint/watchpoint. The program will continue until it hits the next breakpoint/watchpoint.
delete N
Delete breakpoint N (breakpoints are numbered when created).

Setting Variables

Viewing and changing variables at run-time is a huge part of debugging. Try giving functions invalid inputs or running other test cases to find the root of problems. Typically, you will view/set variables when the program is paused.

print x
Print current value of variable x. Being able to use the original variable names is why the (-g) flag is needed; programs compiled regularly have this information removed.
set x = 3
set x = y
Set x to a set value (3) or to another variable (y)
call myfunction()
call myotherfunction(x)
call strlen(mystring)
Call user-defined or system functions. This is extremely useful, but beware calling buggy functions.
display x
undisplay x
Constantly display value of variable x, which is shown after every step or pause. Useful if you are constantly checking for a certain value. Use undisplay to remove the constant display.


Backtrace and Changing Frames

The stack is a list of the current function calls - it shows you where you are in the program. A frame stores the details of a single function call, such as the arguments.

bt

Backtrace, aka print the current function stack to show where you are in the current program. If main calls function a(), which calls b(), which calls c(), the backtrace is

c <= current location b a main up down Move to the next frame up or down in the function stack. If you are in c, you can move to b or a to examine local variables. return Return from current function.


Handling Signals

Signals are messages thrown after certain events, such as a timer or error. GDB may pause when it encounters a signal; you may wish to ignore them instead.

handle [signalname] [action]
handle SIGUSR1 nostop
handle SIGUSR1 noprint
handle SIGUSR1 ignore
Tell GDB to ignore a certain signal (SIGUSR1) when it occurs. There are varying levels of ignoring.

Go through the following examples to understand the procedure of debugging a program and core dumped.

Debugging Example 1

This example demonstrate how would you capture an error which is happening because of an exception raised when dividing by zero.

Debugging Example 2

This example demonstrate a program that can dump a core due to non-initialized memory.

Both the programs are written in C++ nd generates core dump due to different reasons. After going through these two examples you should be in a position to debug your C or C++ programs generating core dumps.

Even though GDB can help you in finding out memory leakage related bugs but it is not a tool to detect memory leakages

GDB cannot be used for programs that do not compile without errors and it does not help in fixing those errors.

source : GNU Debugger - GDB

Comments are closed.

Post Navigation