Lab 07 Data Display Debugger (DDD)

Objective

bullet Use DDD for program debugging
bullet Assertion

Lab Work

The purpose of debugger such as DDD is to allow you to see what is going on "inside" another program while it executes ---- or what another program was doing at the moment it crashed.

Summary of DDD

DDD can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:

bullet Start your program, specifying anything that might affect its behavior.
bullet Make your program stop on specified conditions.
bullet Examine what has happened, when your program has stopped.
bullet Change things in your program, so you can experiment with correcting the effects of one bug and go on to learn about another.

A sample DDD session

Download the program sample.cpp. Compile it to generate executable file: sample

Normally, sample should sort and print its arguments numerically, as in the following example:

>> ./sample 8 7 5 4 1 3

1 3 4 5 7 8

However, with certain arguments, this goes wrong:

>> ./sample 8000 7000 5000 1000 4000

0 1000  4000 5000 7000

Let us use ddd to see what is going on:

bullet

First, you must compile ‘sample.c’ for debugging, giving the ‘-g’ flag while compiling: (see compiling for debugging)

           >> gcc -g -o sample sample.cpp

bullet

Then, you can invoke ddd on the sample executable: (see getting in and out of DDD)

           >> ddd sample

 

And then begin debugging ... ...

 

Getting In and Out of DDD

bullet

Type ‘ddd’ to start ddd

bullet

Use ‘File> Exit’ or Ctrl+Q to exit

The DDD Windows

ddd is composed of three main windows. From top to bottom, we have:

bullet

The Data Window shows the current data of the debugged program.

bullet

The Source Window shows the current source code of the debugged program.

bullet

The Debugger Console accepts debugger commands and shows debugger messages.

Navigating through the Code

Compiling for Debugging

In order to debug a program effectively, you need to generate debugging information when you compile it. This debugging information is stored in the object file; it describes the data type of each variable or function and the correspondence between source line numbers and addresses in the executable code.

To request debugging information, specify the ‘-g’ option when you run the compiler.

Note: When you debug a program compiled with ‘-g -o’, remember that the optimizer is rearranging your code; the debugger shows you what is really there. Do not be too surprised when the execution path does not exactly match your source file! An extreme example: if you define a variable, but never use it, ddd never sees that variable—because the compiler optimizes it out of existence.

Stopping the Progran

bullet

Breakpoints

bullet

setting breakpoints by location

If the source line is visible, click on the left of the source line and then on the ‘Break’ button.

or, you can simply right click on the left of the source line and select the ‘Set Breakpoint’ item from the line popup menu.

or,  you can simply double-click on the left of the source line to set a breakpoint.

 

bullet

setting breakpoints by name

Click on the function name. The function name is then copied to the argument field. Click on the ‘Break’ button to set a breakpoint there.

or, you can simply right click on the function name and select the ‘Break at’ item from the popup menu.

or, you can click on ‘Break...’ from the Breakpoint editor (invoked through ‘Source>Breakpoints’) and enter the function name.

 

bullet

deleting breakpoints

 

Right click on the breakpoint and select the ‘Delete Breakpoint’ item from the popup menu.

or, you can select the breakpoint and click on ‘Delete’ in the Breakpoint editor (invoked through ‘Source>Breakpoints’).

or, you can simply double-click on the breakpoint while holding 'Ctrl' button.

 

bullet

Watchpoints

bullet

setting watchpoints

If the variable name is visible, click on the variable name. The variable name is copied to the argument field.

Otherwise, enter the variable name in the argument field. Click on the ‘Watch’ button to set a watchpoint there.

 

bullet

deleting watchpoints

To delete a watchpoint, enter the name of the watched variable in the argument field and click the ‘Unwatch’ button.

 

bullet

Interrupting

If the program is already running, you can interrupt it any time by clicking the ‘Interrupt’ button.

‘Interrupt’ and 'ESC' button also interrupt a running debugger command, such as printing data.

 

Assertion

Instead of using debugger in C++. Many of the techniques used in writing robust in C++ code. For example, if you have a function that is supposed to be passed a person's name, as a char*, it would be wise to say:


#include <assert.h>

void f (char* name)
{
       assert(name && *name);

...
}

to perform basic checks on the passed-in pointer. assert() is a function (actually a macro) that checks whether its argument is true (non-zero), and aborts the program if not.


C++ offers additional opportunities to the designer interested in producing quality code. For example, consider a common problem in C++, where array boundary index are not checked during a dereference operation, and a bad location is accessed or written to.

int arr[3];
i = 103;
assert (i < 3);
arr[i] = 151;

Then assert () will abort the program and report the line of error occur as the index of this array is out of bound.

 

Task

Download program: test2.cpp and file mark.txt (input file in the program).

Try to use the debugging tools to find out the error in the program and correct it.  The output file should be: grade.txt.

Here is the solution.