gdb, being a CLI application, may not appeal to the eye, but my experience in using it, has proven that it is a very good debugger.
Step 1:
Compile your source code using the g++/gcc -g option. This tells the compiler to include debugging information in the compiled executable.
Step2:
While at the directory containing the freshly compiled executable, invoke gdb as follows:
Code: Select all
gdb executable-name
Set breakpoints as follows:
For the main source file, ie where main() is implemented, use:
Code: Select all
b 51
For other files, say parser.cpp, use:
Code: Select all
b parser.cpp:125
Step 4:
Run the program by typing 'r' and by pressing Enter.
The actual debugging.
- To step over a line of code use: 'n'.
Stepping a line a code forces the debugger to fully execute that line of code. That means, if there is a function call, say:the getMinimalLength function will be executed until it returns and the return value will be saved in length.Code: Select all
length = getMinimalLength(a, b, c);
- To step into a line of code, for instance, when a function is called, use 's'.
If you are unsure what is happening in your code, this is a best tool. Stepping into a line of code forces the debugger to step into any invoked functions. In our example, that means, the debugger will start debugging the code comprising the getMinimalLength function. - To list a few lines of code use: 'list'.
If you are unware which line of code the debugger is at, use list. This will list about ten lines of code showing the current line of code in the middle. - To watch variable values, use 'p variable-name'.
Debugging without being able to watch variable values is next to useless. This feature is central to any serious debugging. Let us assume, variable length is in the current scope and that we are debugging the line just after where getMinimalLength(..) function is called. To do this is as easy as:Code: Select all
p length
An Example:
For this example we will consider the following c++ program:
Code: Select all
#include <iostream>
using namespace std;
long double fact (int n)
{
int i;
long double r = 1.0;
for (i = 1; i <= n; i++)
r = r * i;
return r;
}
int main()
{
long double arr [100];
int i, j, z;
cout << "Start getting factorials from: ";
cin >> z;
cout << "Enter the number of iterations: ";
cin >> j;
if (j < 0 || j > 100)
{
cout << "Iteration count must lie within 0 and 100 including both ends\n";
return 0;
}
for (i = 0; i < j; i++)
{
arr[i] = fact(z);
z++;
}
for (i = 0; i < j; i++)
cout << arr[i] << '\n';
return 0;
}
Code: Select all
g++ -g test07.cpp -o test07
Now, invoke the gdb debugger. The latter needs to know what executable you want to debug - pass its name as a parameter.
Code: Select all
gdb test07
Code: Select all
$ gdb test07
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 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-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/edbarx/projects/test05/test07...done.
(gdb)
To insert a breakpoint we use the b command as follows:
Code: Select all
(gdb) b 7
Code: Select all
(gdb) b test07.cpp:7
Code: Select all
Breakpoint 1 at 0x4009f3: file test07.cpp, line 7.
(gdb)
Code: Select all
(gdb) r
Starting program: /path-to-our-program/test07
Start getting factorials from:
Code: Select all
(gdb) r
Starting program: /path-to-our-program/test07
Start getting factorials from: 1
Enter the number of iterations: 2
Breakpoint 1, fact (n=1) at test07.cpp:7
7 long double r = 1.0;
(gdb)
Code: Select all
(gdb) n
9 for (i = 1; i <= n; i++)
Code: Select all
(gdb) n
10 r = r * i;
Code: Select all
(gdb) p i
$1 = 1
(gdb) p n
$2 = 1
(gdb) p r
$3 = 1
(gdb)
Code: Select all
(gdb) n
9 for (i = 1; i <= n; i++)
(gdb) n
12 return r;
(gdb)
Code: Select all
(gdb) p r
$4 = 1
To list the code where return r is situated, we use the list command:
Code: Select all
(gdb) list
7 long double r = 1.0;
8
9 for (i = 1; i <= n; i++)
10 r = r * i;
11
12 return r;
13 }
14
15 int main()
16 {
(gdb)
Code: Select all
(gdb) n
13 }
(gdb) n
main () at test07.cpp:35
35 z++;
(gdb) n
32 for (i = 0; i < j; i++)
(gdb)
Code: Select all
(gdb) s
34 arr[i] = fact(z);
(gdb) s
Breakpoint 1, fact (n=2) at test07.cpp:7
7 long double r = 1.0;
(gdb) s
9 for (i = 1; i <= n; i++)
(gdb) s
10 r = r * i;
(gdb) s
9 for (i = 1; i <= n; i++)
(gdb) s
10 r = r * i;
(gdb) p i
$5 = 2
(gdb) s
9 for (i = 1; i <= n; i++)
(gdb) s
12 return r;
(gdb) p r
$6 = 2
(gdb)
Code: Select all
(gdb) c
Continuing.
1
2
[Inferior 1 (process 5331) exited normally]
To quit the debugger, use the q command as follows:
Code: Select all
(gdb) q
Enjoy.