CSCI 2170 LAB A
Debugging using NetBeans

Objectives: 
To become familiar with "bug" and "debugging" concepts
To learn debugging techniques
To learn NetBeans debugger 
CREATE ANSWER SHEET for LAB A
A.  Buggy Problems
B.  Debugging Techniques
C.  Using the NetBeans Debugger

You have solved a problem, designed a solution, and implemented the solution in C++.  Assume you compile the source and the compiler finds no errors. Next you start execution of your program but it does not work correctly.  Maybe it gives the wrong answer or goes into an infinite loop.  Maybe it "aborts" and a message similar to the following is printed:
"segmentation fault: core dumped"

For whatever reason, the outcome of executing the program does not produce the expected results.  There is an error in your program.  Historically these errors have been called "bugs."  The term bug was first coined by Grace Hopper, the inventor of COBOL and the first assembly language.  In 1945, the famous Mark I computer came to a halt.  Workers found a moth inside the computer, removed the offending beast and the computer was fine!  From then on, all mysterious problems with computing were called bugs.  All programmers run into problems related to bugs.  Therefore, let's now address how to avoid and deal with "bugs".
 
 
 

A. Buggy Problems

There are numerous famous bugs in computing.  For example, the Russians lost a space ship in mid-flight when an erroneous command transmitted from mission control sent the space ship into a test routine from which it never recovered.  There should have been some safety "switch" that prevented the accidental execution of such a test sequence.

A multi-million dollar X-ray machine killed at least two people by administering excessive doses of radiation.   The cause of the error was traced to a certain sequence of editing commands.  One day programmers may need "malpractice insurance" like physicians do today to protect themselves in such situations.

Can bugs be avoided?  Yes and no.  Software Engineering is dedicated to developing techniques for building better software.  Our goal is to be as good at building software as an engineer is at building a bridge.  Bridges rarely fail just as software should rarely fail.  To help reduce errors in software we have developed paradigms of software development.  A paradigm is a method with all its related steps and techniques (i.e., an approach).  In the 1970's, a software development paradigm called the Waterfall paradigm was developed.  It was so named because each step or phase supplies information to the next like water flows over a waterfall.  The phases are as follows:
 

Analysis



Design



Implementation



Testing



Maintenance

In the analysis phase, requirements describing what the software product is to do are determined by interviewing the client.  The requirements are analyzed and a specifications document is produced.  In the design phase, the specifications document is turned into an architectural design in which the software is broken down into modules.  The modules are designed in a more detailed fashion that focuses on procedural detail.  The data structures are defined at this point.  During the implementation phase, the modules are coded and tested.  The modules are integrated and tested as a whole in the testing phase.  The maintenance phase includes making changes to the software including corrections and enhancements.   Many methods such as step-wise refinement and structured programming have been developed to improve the process of software development.  We will focus in this lab (and in this course) on the Waterfall paradigm for software development.  The object oriented paradigm is another popular method in use today.

Errors can occur at any phase of software development.  Any of these errors can lead to serious problems and result in software that does not function as desired.  Given the disastrous results with the software in the X-ray machine, we must take every precaution possible to be sure there are no errors in our systems.  Several things have been done.

"Formal languages" have been developed in which requirements can be expressed instead of expressing them in ambiguous and imprecise English.  The design can be reviewed by a team of professionals for potential problems.  Prototypes can be used to clarify requirements or difficult design algorithms.  An appropriate high-level language choice will reduce errors.  Code walkthroughs help the developer locate many errors.  A code walkthrough is a line-by-line reading of a unit of code by a team of professionals.  The purpose of each line in the given program is explained.  Good documentation habits and good naming conventions decrease errors too.  A good design and a good programmer are the best way to avoid coding errors.

Finally, careful testing must be done before software is released.  A later lab will address testing.  Testing is the process of showing that errors exist and debugging is the process of localizing, analyzing, and removing suspected errors in the code.

If an instruction is written incorrectly it is called a syntax error and will be caught by the compiler.  If an incorrect formula or algorithm is used it is called a logic error and must be caught by the programmer or tester.  Errors that are exposed at run time are called run time errors (i.e., dividing by zero or array index out of range).
 
 
 

B. Debugging Techniques

A theory of debugging was developed by Poston that is based on Most Probable Errors (MPEs).  MPEs are the most frequent mistakes made by programmers.  The most likely place to contain an error is in an IF - THEN - ELSE conditional expression. The second most likely place for errors is in input/output statements and the third is in loops.  According to this theory, you should check the conditional expression in any If statement first.  Then I/O statements should be checked and finally loops should be examined.

How does one localize and analyze an error? There are standard debugging techniques that can be used.  You will practice these in this lab.  They are as follows:

  1. Get a hard copy of your program.
    Read the code and think about what it does. (Desk check)
  2. Use print statements to pinpoint the source of an error.
  3. Use a debugger to help locate an error.

A program is written only once but is read many times.  Donald Knuth has developed a system, called CWEB , that helps one develop software as a work of literature.  Explaining CWEB is beyond the scope of this lab exercise but we must learn to read our programs for debugging purposes and write programs that are readable.  If we read our code to ourselves we often read over our errors.  It is a good idea to read our code to another knowledgeable person explaining how each line contributes to the solution.



When reading through program code, often just looking at the code d oes not help us identify the logic error(s). To help us locate logic errors, we can insert output (cout <<) statements at strategic places in the code to localize errors.  These output statements allow us to trace the path of execution or to trace the value of certain variables as the program is executed to determine what part of the code is not functioning correctly.  There are 3 types of traces that can be implemented by placing output statements in the code - subprogram trace, statement trace, and variable trace.  A subprogram trace is used to determine the order in which subprograms are called.  An output statement that outputs the name of the subprogram is placed at the start of every subprogram to implement a subprogram trace.  A statement level trace is used to determine where the execution of the program halts.  An output statement can be placed after different statements in the code to determine which instructions are executed before the program halts.

If an answer produced by the program is wrong, we look at variables used to calculate this answer.  To implement a variable trace, we print the value of variables involved in the calculation at different places to see where one or more of them became incorrect. When a variable of interest is changed, the new value should be printed with the name of the enclosing block and a line number to help identify where the change occurred.  All input to the program as well as input to all subprograms should be checked to make sure the values are valid.

Once we locate and fix the problem, the output statements are no longer needed.  They can be removed with the editor and the code recompiled. In some languages such as "C++" there is a mechanism by which the output statements can physically be left in the source code but directions can be given to the compiler to omit them when the last compile is done.  If the statements are needed later they do not have to be retyped.


NOTE: For each of the following exercises, indicate answers on the answer sheet.


The program used in Exercise 1 makes use of command line arguments. If you are unfamiliar with command line arguments, after looking at the program code referenced in Excerice 1, you should read Getting Command Line Arguments in C++



Exercise 1: Copy inlabAa.cc to your account. If you haven't already, bring up your Answer sheet for this lab---to do this, click on the link at the very top of this web page. For this exercise you will copy a program to your account, add cout statements to help you debug the logic of the program and correct the logic errors contained in the program. A description of three different types of program traces can be found immediately above this Exercise. You will need to use statement trace and variable trace cout statements. When you finish correcting the program, you are asked to give the lab assistant a hardcopy of the corrected program which includes your cout statements.


Exercise 2: Continue to test the program given in Exercise 1. Be sure to test the program with different numbers (including zero, no numbers) to make sure you realize there is more than one logic error.  Use cout output statements to locate the errors in the program.  You and your partner should turn in to the lab assistant a printout of the corrected program (inlabAa.cc) containing the "cout's" you added for debugging.  Put your names in the heading of the debugged code.  List/identify the bugs that you found on the printout using pen or pencil.

C. Using NetBeans -- Integrated Development Environment (IDE)

NetBeans is an integrated developement environment that allows a developer to edit, compile/build, debug, and run projects with components written in multiple languages. It provides simplified code reuse and has good debugging support. A debugger is a program that controls the execution of another program for the purpose of locating (and/or repairing) errors.

NetBeans documentation beyond what is found in this lab can be found at http://www.netbeans.org/kb/index.html

In this lab, we will learn to develop a project written in C++ using NetBeans. In particular, we will learn to use the built-in debugger. With the debugger, you can:

To practice using the NetBeans debugger, we must first create a new C++ project in NetBeans

Start by logging into ranger using an NX client. See the previous lab if you need to review this process.

Next from the command window, enter/type "netbeans&"

A window similar to the following should appear

Exercise 3: Follow the steps 1 through 3f as given below so as to create an empty C++ project:
  1. Click on  File from the top menu bar
  2. Click on New Project from the pull down menu

  1. From the pop up window:
    1. select C/C++ projects from the left hand side list
    2. select C/C++ Application from the right hand side list and click Next
    3. fill in the project name in the upper part of the window (this will also serve as the name of  folder containing all files of your new project).
    4. Take a look at the line showing the directory of where the project directory will be located in your computer. IF you want your project to be located in your CLA directory, then you need to change the path..use the browse button
    5. Note: If your see "Create Main File" with a checkbox above "Set as Main Project", uncheck the box for Main File by clicking on it.
    6. Now, click Finish.

Exercise 4: Now, create a new C++ file to be part of this project. Follow the instructions below to create a new C++ file.

  1. Click on Source Files for your project
  2. Click on New from the pull down menu
  3. Select Main C++ File....
  4. For this project main C++ file, just choose the defaults,i.e., main.cpp
  5. Next we want to use a program found in the $CLA folder, inlabAc.cc.
    1. First bring up a new terminal window in your NX session--locate the terminal icon near the top of your NX window and click on the icon.
    2. In this terminal window, cd to where your NetBeans project was created... possibly in ./NetBeansProjects or ./CLA/NetBeansProjects.
    3. Now in your NX terminal window, locate the project name, i.e.,
      enter the command: ls
      you should see the project folder such as CppApplication_1.
    4. Now cd to that folder and enter the command: ls
      You should see the main.cpp file -- if you don't, then you need to locate the main.cpp file before proceeding
    5. We are now ready to copy the program file: inlabAc.cc.
      cp $CLA/inlabAc.cc main.cpp
  6. After you have copied the program inlabAc.cc, in the NetBeans session double click on "main" in the project listing under the folder "Source Files". The newly copied file should appear in your window listing.

 Exercise 5: Read the main program code to get an idea of what the program should do. Compile and run this program by:

  1. Click Build from the top menu bar
  2. Click on "Build Main Project". The program should compile properly and display the message "Build Successful ..." in the bottom window labeled "Output". 

  3. Run the program by clicking "Run" followed by "Debug Main Project" from the top menu. A new window should appear that prompts for you to enter the number of values and the values to use. At the prompts enter indicate there are 2 numbers in the list both with a value of 22. The window will remain open with the program output. 

Look at the results. Are they correct? Which results are wrong? Once you realize a program has errors, you may use the debugger to find out where the errors are in your program.

Let's practice debugging this program. First we need to set a breakpoint on a line of code that could potentially show us what the problem is. It should be a line of executable code. Scroll through the code and find the line in main

	total = sum(listOfNumbers, howMany);

Set a breakpoint at this line by clicking on the gray area to the left of the line. A red dot should appear as shown below. (If you wish to delete a breakpoint, click on it again. Do not delete the breakpoint you just set. If you accidentally deleted it, then simply reset it.)

Let's run the program and see what happens. Click on the Start the debugger shortcut button across the top of the window (or again do a build and start the debugger from the previous menu choices). Use the same input as you did when you ran the program before.

 

 

After you enter the input, the debugger will execute the program up to the breakpoint. It places a green arrowi/line on the break code line.

The current values of different variables are displayed in the right bottom "Output" window under the tab Local Variables View. For example, variable howMany currently has large value (indicating it has not been initialized).


Exercise 6: Write the answers to the following questions on the answer sheet .  The blank lines are there to remind you that an answer is expected.

A. What is the current value of the variable total?___

B. What are the current values of the first 4 elements of array listOfNumbers? ________

C.  Look at the cout << statement which is two lines below the current program statement (breakpoint). This statement will output the average. Given the current value of the variables, what is the problem with this statement?___

D.   From reading the comment before the call to readNumbers(listOfNumber, howMany) in main(), and from reading the header comments in the function readNumbers(), what did the programmer intend for readNumbers() to do to the variable howMany?___


    Now let's continue to determine the cause of the error using the debugger: The value of the variables howmany, total and listOfNumbers are not what you have expected, right? This suggests that error(s) occurred before the current line in the program. So lets back up and put a break next to the previous statement :
       readNumbers(listOfNumbers, howMany);
Run the debugger again. (You need to stop the debugger from the previous run, and start again). This time, when the debugger stops, try step into the function being called (e.g., readNumbers) by clicking on the Step Into debugging short cut button.


    The debugger should move to the first executable statement in function readNumbers. Step throught the first two statements by clicking Step Over short cut button twice. (add short cut here). Enter the same information in the input window when prompted as before.


Exercise 6 Continued

E.   What is the current value of howMany?___
F.   Why is the value of howMany in function "readNumber" differ from its value in the main function right after the call to function "readNumber"? How would you fix it?___


    Click on the "Step Over" short cut button until the debugger moves back to the main function.

Exercise 6 Continued

G. How many times is the body of the for loop executed?____ How would you fix it?___

    Click on the "Start/Continue" short cut button. This will continue execution of the program from the breakpoint. You should see Program exited normally in the "Output" window. Save the changes, build and execute the program again to make sure that the program is free of run time errors. You should enter different data to test the program.
Exercise 6 Continued

H.  How do you set a breakpoint in NetBeans?___

I.  Once all the breakpoints are set, how do you begin execution of the program?___

J.  How do you inspect the value of a variable during debugging?___

K. How do you continue the execution of the program after a breakpoint has been reached?___

L. This part of the lab requires you to print out the program from NetBeans. To print the program from NetBeans :

            Your program should be printed from the lab laser printer. Collect the print out and write down your name on the front page.
   
Exercise 6 Continued

M.  In a terminal window (not NetBeans) on ranger change to the directory that contains your copy of the inlabAc.cpp that was used in NetBeans. Create a script file that contains a listing of the program, a compile of the program, and the run of the program. Print the script file on the printer. Turn in this print out.

	  This can be done by using the following commands in a terminal session

	   ranger $ cd ---location of your main.cpp file----
	   ranger $ script claA.log      # for starting script with name claA.log
	   $ ls -l                       # for showing the list of the current directory
	   $ c++ newmain.cpp             # if the name of the program is newmain.cpp
	   $ a.out                       # to compile the program
	   $ exit                        # to exit from script
	   ranger $ lph claA.log         # to send the script file to the printer

Turn in your answer sheet and the printouts from exercises 1, 2, 6L, and 6M. Be sure to mark the errors on the printout from Exercise 1 and the new "couts" on the printout of exercise 2.


 
----- End of Lab A - Debugging  -----
Complete the Exercises on the Answer Sheet
Turn in the Answer Sheet and the printouts required by the exercises.

 
 
Return to the top of this lab
Return to the link page for all 2170 labs