CS253: Software Development with C++

Spring 2020

Debugging

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:                

  1. Copy & paste the program to bad.cc.
    If you don’t know how to copy & paste, then this is a fine opportunity to learn.
  2. Compile it, like this: g++ -Wall bad.cc
  3. Execute it, observe the segmentation fault, obviously caused by v[100000003]
  4. Compile it, with the C++ library debugging flag, like this: g++ -Wall -D_GLIBCXX_DEBUG bad.cc
  5. 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.
  6. Fix the offending line by changing [100000003] to [3].
  7. Compile & execute, see the assert() failure.
  8. Compile it, like this: g++ -Wall -DNDEBUG bad.cc
  9. Execute it, observe that the assertion failure vanished (and the program still doesn’t work).
  10. Compile for the debugger gdb: g++ -Wall -ggdb bad.cc
  11. Execute the debugger: gdb ./a.out
  12. Set a breakpoint at the assertion: b 16 (your line number may vary)
  13. Run the program: r
  14. Print the value of filename, like this: p filename
  15. Figure out why filename has that value. Fix the source.
  16. Recompile for the debugger.
  17. Set a breakpoint at if (prefix == "search") line.
  18. Run the program to that breakpoint, inspect s and prefix the same way that you printed the value of filename.
  19. Fix the call to string::substr().
  20. Recompile, see that the program works correctly.

For extra fame & glory:                 

  1. Debug the program using ddd.