Notes on Debugging | Computer Programming I | CS A201, Study notes of Computer Science

Material Type: Notes; Class: Programming Concepts I; Subject: Computer Science ; University: University of Alaska - Anchorage; Term: Unknown 1989;

Typology: Study notes

Pre 2010

Uploaded on 03/28/2010

koofers-user-87l
koofers-user-87l 🇺🇸

10 documents

1 / 6

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CS201, Mock
Debugging
Some have said that any monkey can write a program – the hard part is debugging it.
While this is somewhat oversimplifying the difficult process of writing a program, it is
sometimes more time consuming and frustrating to debug a program than it was to write
it in the first place. However there are tools to help you! The purpose of this lecture is to
introduce you to some of these tools.
In this lecture we’ll look at two methods of debugging:
1. Adding print statements, which has the benefit of working in any programming
language and in any environment, but is very tedious and can sometimes actually
lead to errors
2. Using the debugging utilities in NetBeans (similar tools exist in most IDE’s)
There is also a debugger in Unix called jdb for the Java environment. We won’t cover it
here, but you should be aware that it exists if you plan to do more development under
Unix.
Debugging with Print Statements
You have probably already used this method for debugging. The basic idea is very
simple. If your program is not working correctly, try inserting print statements (in Java,
this would be System.out.println statements) to narrow down where the error is. The
print statements could be used to locate the section of code that contains the problem, and
they might output the values of some variables that would aid in debugging.
As one example, consider the program below:
class DebugTest {
public static final String STR = "some string here";
public static void main(String[] args) {
String s;
s = STR.substring(0,3);
// Do some processing of the string
s = STR.substring(1,5);
// Do some processing of the string
s = STR.substring(8,3);
// Do some processing of the string
s = STR.substring(22,4);
// Do some processing of the string
s = STR.substring(2,3);
// Do some processing of the string
return;
}
}
pf3
pf4
pf5

Partial preview of the text

Download Notes on Debugging | Computer Programming I | CS A201 and more Study notes Computer Science in PDF only on Docsity!

CS201, Mock

Debugging

Some have said that any monkey can write a program – the hard part is debugging it.

While this is somewhat oversimplifying the difficult process of writing a program, it is

sometimes more time consuming and frustrating to debug a program than it was to write

it in the first place. However there are tools to help you! The purpose of this lecture is to

introduce you to some of these tools.

In this lecture we’ll look at two methods of debugging:

1. Adding print statements, which has the benefit of working in any programming

language and in any environment, but is very tedious and can sometimes actually

lead to errors

2. Using the debugging utilities in NetBeans (similar tools exist in most IDE’s)

There is also a debugger in Unix called jdb for the Java environment. We won’t cover it

here, but you should be aware that it exists if you plan to do more development under

Unix.

Debugging with Print Statements

You have probably already used this method for debugging. The basic idea is very

simple. If your program is not working correctly, try inserting print statements (in Java,

this would be System.out.println statements) to narrow down where the error is. The

print statements could be used to locate the section of code that contains the problem, and

they might output the values of some variables that would aid in debugging.

As one example, consider the program below:

class DebugTest { public static final String STR = "some string here"; public static void main(String[] args) { String s; s = STR.substring(0,3); // Do some processing of the string s = STR.substring(1,5); // Do some processing of the string s = STR.substring(8,3); // Do some processing of the string s = STR.substring(22,4); // Do some processing of the string s = STR.substring(2,3); // Do some processing of the string return; } }

Upon running this program, it crashes and aborts. Something is wrong! (Of course, this

program doesn’t do much anyway, but it’s just an example :)

Fortunately, Java usually tries to give a message about what went wrong. Sometimes this

message is useful, and sometimes it isn’t. In this case the message is quite useful:

C:\homeworks>java DebugTest Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: - at java.lang.String.substring(String.java:1525) at DebugTest.main(DebugTest.java:10)

This tells us that something is wrong on line 10 That line is:

s = STR.substring(8,3);.

String index out of range: -5 is a bit cryptic, but the error here is that the parameters are

invalid. The first parameter is the index of the start character, while the second parameter

should be the index of the end character. However, since 3 is five less than 8, we get an

error. Most likely the programmer made this error thinking that the first parameter was

the index of the start character, and that the second parameter was the number of

character to include as the substring. (This is the way substring works in C++, so it is not

an uncommon error for programmers that learned C++ first!)

In this case, the Java interpreter told us where the error was. In many cases we don’t

know exactly where we are going wrong. Consider the program below, which tries to

convert Fahrenheit to Celsius:

import java.util.Scanner; class DebugTest { public static void main(String[] args) { int fahr, celsius; Scanner keyboard = new Scanner(System.in);

System.out.println("Enter temperature in Fahrenheit."); fahr = keyboard.nextInt(); celsius = 5 / 9 * (fahr - 32); System.out.println("The temp in Celsius is " + celsius); } }

When run, it compiles and executes but gives incorrect outputs. For example, on an input

of 100 F, we get 0 C, which is incorrect. What is wrong?

To figure out what is going wrong, we could start adding some print statements:

import java.util.Scanner; class DebugTest { public static void main(String[] args) { int fahr, celsius;

The NetBeans Debugger

Users of NetBeans, or virtually any IDE for that matter, have the benefit of a nice,

graphical-based debugging environment. The debugger will allow us to set breakpoints,

view the contents of variables, and trace through a program one line at a time in a nice

GUI environment.

To invoke the debugger, compile the program and then run it in debug mode by selecting

R)un, Debug Main Project, or hit the icon.

NetBeans programs run in one of three modes – design mode, run mode, or break mode.

Design mode is where you design and write the code for the program. Run mode is

when you run the program. Break mode is when you pause the program to debug it.

If we return to the original program with the bugs, one way to enter break mode is to add

a breakpoint. A breakpoint stops execution at a particular line of code and enters Break

mode. This is useful when you know that a particular routine is faulty and want to

inspect the code more closely when execution reaches that point.

To set a breakpoint, click in the border to the left of the code. A red square will appear.

Click the same square to turn the breakpoint off.

When we run the program and reach this code, the program automatically enters Break

mode and stops. Execution stops before the line with the breakpoint is executed. The

current line is indicated by a green arrow and green highlight:

The first thing we can do is inspect the value of variables. One way to do this is to hover

the mouse over the variable or constant, and a popup window will display its contents:

In the above screenshot I have hovered over the “fahr” variable and the pop-up shows

that its value is 100. You can also highlight some code and the evaluated expression of

that code will be display. In this case I highlighted the “5 / 9” code and it shows the

result to be zero:

This by itself would give us enough information to debug the program. Note that we did

not have to add any print statements!

We can also immediately see the contents of all the active variables by looking in the

“Local Variables” tab at the bottom of the screen:

We can also step through the program one line at a time using the buttons:

These buttons are used respectively to step over a subroutine, step into a subroutine, or

step out of a subroutine. The last button is used to run to the cursor location. We can

use these buttons and view our variables change as we run the program. When we define

our own subroutines this will make more sense, but for now the first two buttons do the

same thing when we’re executing code within a subroutine (i.e. method).

Click on the “Step Into” or “Step over” buttons in our example and we get: