Lab 7 - Squishing Bugs
This lab is all about debugging. You will fix a program, which you did not write, but are somehow now responsible for. This program does not remotely work! I tried to make it a simple program, but one with some non-obvious errors. The real point of the lab is not so much the program, but rather to learn how to use a new tool.
You will be using ddd, the "Data Display Debugger", which is a graphical frontend to the gdb debugger. In fact, if you watch the debug console closely as you use ddd, it will more or less teach you how to use the text based gdb. It also provides some nice extensions, and it really is a great thing to know how to use the graphical tool. You'll really be happy with ddd when you have a data structures class!
The Sample Program
The program you will debug is intended to compute the sum of all natural counting numbers less than some given n. For instance, if the user enters 3, it should compute 1+2+3=6. Or if you enter 5, 1+2+3+4+5=15, and so on.
Of course, if you know your math stories, you know it has a closed form solution (n*(n+1))/2, but we are going to pretend we don't know that and sum it using a loop. The program code which does this, or attempts to do this is provided for you. You will be using the debugger to fix it!
The first thing to do is configure ddd. The default interface, is a little unwieldy, and you wind up not having much space to see everything at once. But the good news is, with a little minor tweak, we can fix it! So here's what we'll do. Open a terminal and run the command:
You will see get a window which looks like is:
This is the defult interface which ddd presents to you. All of the sections of ddd are stacked in a vertical window and the debugger controls are all in a little floating tool window. This gets old really fast, so what we want to do is change ddd so that it uses multiple windows, and puts the debugger tools at the top of the source window. To start the process, go to the edit menu and select "preferences"
This will pop open a dialog. Click on the "source" button and then check the box on the "Command Tool" line which says "Source Window"
Now, in the same dialog, select "startup" and then check the box on "Window Layout" which says "Separate Windows"
Click "Ok" and you'll be greeted with a dialog asking if you want to restart ddd. Click "Yes"
ddd will now restart, and you'll see just one lone gdb console window. This is just fine, you don't have any source code open. Go ahead and close this window to exit ddd.
Congratulations! You've now configured ddd to have a better interface. So long as you don't kill your mclive key, you'll never have to do this again!
Debugging a Program with ddd
Now that you have ddd all configured, let's learn how to use it. The first step will be to download the program, so go ahead and download the following file:
This will download the file to your ~/Downloads folder. To unzip it, change into your cs1 folder and execute the following:
When you do this, you will get the following output
Archive: /home/pngwen/Downloads/Cs1-lab7.zip creating: lab7/ inflating: lab7/sumnum.cpp inflating: lab7/Makefile
You will now have a lab7 directory with the program in it. Change into lab7 directory and then build the program:
cd lab7 make
Notice how when it built the sumnum program, it compiled with the -g option. Take a look in the makefile to see how I told make to compile with -g. Of course, if you like manual compilation with g++, you can always just put the -g option on the command line. The -g option includes some special information in the executable file which allows the debugger to associate machine code instructions with their corresponding C++ source code instructions. This is how it's able to show you which line of code is being executed, and is generally a nice thing to have during development.
Now, let's run the debugger on the sumnum program. Execute the following:
You will be greated with this set of windows
Of course, you may have to drag them around to get them in this shape. Go ahead and arrange them as shown.
The top window is your source window, the bottom is your console window. The source window, of course, shows the source code of your program, and the console window shows gdb's output as well as all input and output for your program.
Understanding Debuggers (a summary of commands)
Ok, so now we're all set to debug our program! The thing is, debuggers are rather complex animals, and you're probably a little overwhelmed by the strange words, buttons, and symbols you are now looking at. Fear not fellow ape! You'll never use all of these things in one session, and we're only going to look at the essentials.
The first thing to look at is breakpoints. A breakpoint is just a stoping place in a program. If you were to run the program without setting breakpoints, it would run at normal speed and not show you any new information. This would not be helpful! Fortunately, setting a breakpoint is as easy as double clikcing on a line of code. Let's try that now. Double click on the line shown below, and you'll get this nifty stopsign graphic as a reward:
Now, ddd will stop at this line of code when it executes. Before we do anything else, let's go over the control buttons, and what they do. The basic controls for the debugger and their meanings are outlined below:
- Basic Debug Controls
- Starts/Restarts the program
- Stops the program. This is great if your program gets stuck in a loop!
- Executes the next program statement. If you are about to call a function, this will step into the function being called.
- Executes the current machine code instruction, stepping into functions as needed. This is an advanced technique which we will not use for quite some time.
- Executes the current line of code and stops at the beginning of the next. This will execute functions without entering them.
- Executes the current machine code instruction, but it will not step into functions. This is also an advanced button which you should avoid.
- Executes until some condition is met. This is also advanced, but it may be fun to play with!
- Executes until the current function returns. It "finishes" the current function.
- Continues execution until the next breakpoint is reached.
- Kills the current program. Handy for when you've seen enough.
- Moves up the function stack. More on this later this semester!
- Moves down the function stack.
- Same as in any other editor
- Alter your code
- Rebuild your code
So now, click run and have at it! You'll get a green arrow on the line the debugger stops on.
Now, double click on some variables, and you'll get a data window:
This will let you see your variables. Try the command buttons out and run through the program. Note that when the program needs input, you'll have to type it in the console window.
Find the Bugs
Now it's all you! Explore, find the errors and fix them. HINT: The edit and make buttons may be worth trying out. Watch the program execute and work out where it goes wrong. When you get it done, raise your hand and I will come to you to grade it.