# What are good sample programs for learning to use a debugger?

One skill I teach students in Java 1 is how to use a debugger, specifically:

• single-stepping through code
• using breakpoints
• viewing the values of variables
• going up and down the call stack

I have been unable to come up with good programs for them to use when learning to use the debugger. Specifically, I would like to provide them with a program with a bug that they're unlikely to find just by looking at the code but can find with a debugger.

• Real programmers don't use debuggers, or pre: real-programmer. post: debugger not used. We use contracts, it reduces bugs, and makes the remainder easy to find. – ctrl-alt-delor Mar 30 '18 at 15:22
• Contacts are a huge help . I wish I could track down the study circa 1980 that tracked progress of university students learning traditionally versus with debuggers first. The speed at which students really understood the course material was much better with debuggers than without – pojo-guy Apr 1 '18 at 1:12
• @pojo-guy I assume you accidentally left off the "r" in the first word of your response? Surely you're not suggesting it's who you know, not what you know. :-) – Ellen Spertus Apr 1 '18 at 20:16
• Lol yes, responding on a cell phone is always fun. At least automisspell didn't embarrass me this time. – pojo-guy Apr 2 '18 at 0:32

A few Java specific examples come to mind:

• Using % with a negative number - I recently came across this and had to remember how Java treats modulus v. remainder (cf. this thread)

• Listing switch statements without the proper break; at the end of each case - maybe something that can be seen right away, but stepping through each line would be good to visualize this process

• Integer division is also a classic - using the conventional Celcius-to-Fahrenheit (or vice versa) conversion program with the formula broken down over several lines would force them to see line by line what is happening when you evaluate 9/5 or 5/9

• Operations with increment/decrement operators in prefix and/or postfix position throughout a program - I like this one a lot because of how variables may change without that change always being seen

I'll edit and add ideas as more occur to me.

• The second one is, in my opinion, a very, very good one. – ItamarG3 Jun 3 '17 at 5:44

I would try to focus in on the kinds of errors that beginner programmers get stuck on, to imitate as closely as possible the kind of situation that they would want a debugger for. So, I might code this method, which contains exactly the sort of subtle mistake 101 students regularly make, right in front of them:

public static boolean compare (String a, String b){
boolean same  = true;
for(int k = 0; k < a.length(); k++){
if (a.charAt(k) != b.charAt(k))
same = false;
}
return same;
}


...If someone starts to mention some errors, pretend that you are simply too focused on coding to deal with them right now. Please don't interrupt! We are creating very important code right now, and it takes concentration!

I would then follow up by putting in some tests, one at a time. Have a big reaction when the first two tests go well, appear to get a little flustered by the third test, and become quite upset when the fourth test crashes.

public static void main(String[] args) {
System.out.println(compare("",""));
System.out.println(compare("cat","dog"));
System.out.println(compare("car","carport"));
System.out.println(compare("fortress","for"));
}


Then I would announce that, as a mistake has clearly been made, and as there is clearly no one in the room even remotely smart enough to figure out what it is, this is now a moment to go to the debugger.

The theatrics are a bit of my own manner in the classroom, but also serve a purpose here. I want to get around the handful of quicker students who will spot the error right away with a bit of a wink that lets them know that they are perfectly smart, but not to ruin this for everyone else. I want to keep them quiet long enough to let us get through the debugging process together.

Afterwards, I would acknowledge that anyone who saw the error was perfectly clever, but that the debugger is important because they will, without any doubt, encounter bugs that they will have trouble locating. The debugger is one important part of the toolset that they will need to right the ship when it starts to go askew in the future.

An interesting bug occurred during a practice job interview when creating a method that tests whether a substring (the needle) is in a string (the haystack). You can play with the code on repl.it or see it here.

import java.util.Objects;

class Main {

public static void main(String[] args) {
String[] needles = {"a", "a", "ab"};
String[] haystacks = {"a", "b", "ba"};
for (int i = 0; i < needles.length; i++) {
boolean expected = haystacks[i].contains(needles[i]);
boolean actual = isSubstring(needles[i], haystacks[i]);

System.out.println(String.format(
"%s -- isSubstring(\"%s\", \"%s\") has expected value %b" +
" and actual value %b",
expected == actual ? "PASS" : "FAIL",
needles[i], haystacks[i],
expected, actual));
}
}

/**
* Tests whether the given substring (the needle) is in the full string
* (the haystack).
*
* @param needle the substring
* @param haystack the full string
* @return true if the substring is contained in the full string, false otherwise
*/
public static boolean isSubstring(String needle, String haystack) {
Objects.requireNonNull(needle);
Objects.requireNonNull(haystack);

if (needle.isEmpty()) {
return true;
}

for (int i = 0; i < haystack.length(); i++) {
// Check if next haystack character matches first haystack character.
if (haystack.charAt(i) == needle.charAt(0)) {
// If so, see if the rest of the strings match.
if (isSubstringHelper(haystack, needle, i + 1)) {
return true;
}
}
// If not, advance the haystack index and try again.
}
return false;
}

private static boolean isSubstringHelper(String haystack, String needle, int hi) {
for (int ni = 1; //  The character with index 0 has already been tested.
ni < needle.length() && hi < haystack.length();
ni++, hi++){
if (haystack.charAt(hi) != needle.charAt(ni))
return false;
}
return true;
}
}


I would suggest removing all but the first pair of test cases before assigning to students.

I found this nice Java example on Horstmann's web site. A complete example with a variety of exercises. Very well written, as are his books.

• No, you shouldn't have answered this. “There's an answer on this site over there” is not an answer. The content of this site may make a good answer, but just stating its existence does not answer the question. – Gilles 'SO- stop being evil' Mar 30 '18 at 4:54
• Actually, a more complete answer would have been fine. But as @Gilles suggests, simple links are not highly valued here. If you can say more about the example and why it works and with whom, it will find better acceptance. But "Go look over there" isn't considered a "real" answer here. be as complete as you can be. Explore the site and see which answers get up-voted. They generally contain good explanations. You can edit your answer, of course, and down-votes can then be withdrawn. – Buffy Mar 30 '18 at 12:49
• Your comment above with the link was very appreciated. Thank you. – Ellen Spertus Mar 30 '18 at 16:53