Debugging                
In this lab, you will learn to use debugging tools such as gdb,
assert()
, and -D_GLIBCXX_DEBUG
.
                
Consider the following program, bad.cc
. It opens resolv.conf
,
and prints out the line that starts with “search”. It has several errors
(don’t rob others of the joy of discovery—keep it to yourself):
                
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <cassert>
using namespace std;
int main() {
// First, some stupid code just to introduce an error:
vector<int> v = {2,42,165,253,1003};
cout << "My favorite number is " << v[10000003] << '\n';
string filename = "\etc\resolv.conf";
ifstream in(filename);
assert(in.is_open());
for (string s; getline(in, s); ) {
string prefix = s.substr(1,6);
if (prefix == "search")
cout << s << '\n';
}
return 0;
}
When the program works, it prints something like this:
                
search cs.colostate.edu colostate.edu
For this lab, you should:                
- Copy & paste the program to
bad.cc
.
If you don’t know how to copy & paste, then this is a fine opportunity
to learn.
- Compile it, like this:
g++ -Wall bad.cc
- Execute it, observe the segmentation fault,
obviously caused by
v[100000003]
- Compile it, with the C++ library debugging flag, like this:
g++ -Wall -D_GLIBCXX_DEBUG bad.cc
- Execute it, observe the more helpful error message.
It’s not perfect, but it beats “Segmentation fault”.
At least it gives a hint as to which container is having problems.
- Fix the offending line by changing
[100000003]
to [3]
.
- Compile & execute, see the
assert()
failure.
- Compile it, like this:
g++ -Wall -DNDEBUG bad.cc
- Execute it, observe that the assertion failure vanished
(and the program still doesn’t work).
- Compile for the debugger gdb:
g++ -Wall -ggdb bad.cc
- Execute the debugger:
gdb ./a.out
- Set a breakpoint at the assertion:
b 16
(your line number may vary)
- Run the program:
r
- Print the value of
filename
, like this: p filename
- Figure out why
filename
has that value. Fix the source.
- Recompile for the debugger.
- Set a breakpoint at
if (prefix == "search")
line.
- Run the program to that breakpoint, inspect
s
and prefix
the same way that you printed the value of filename
.
- Fix the call to
string::substr()
.
- Recompile, see that the program works correctly.
For extra fame & glory:
                
- Debug the program using ddd.