CS 2 (Winter 2024) Lab 01: Explosive Debugging

This lab focuses on debugging JUnit tests for a Java class. The main focus of part one is on reading error messages to determine where a bug might be. The main focus of part 2 is using println’s and the debugger to determine where a bug might be. The main focus of part 3 is using the skills from part 1 and 2 to debug a text adventure we have written.

For labs in CS 2, you must work in pairs. For this lab, both partners must do the setup separately to be ready for the rest of the term. The main point of lab is to act as a bridge between lecture and the projects. We aim to give you an “intermediary” programming assignment which will help with the project. For this reason, all labs will be collaborative, and your lab TAs will be extremely helpful. If you get stuck, you should immediately ask for help rather than floundering. Lab is only an hour, and we want you to optimize the time you spend for maximum learning.

Register for the Lab

Register for the lab using grinch: https://grinch.caltech.edu/register and clone the repository as explained in the setup instructions.

Pair Programming

Since you are pair programming with another person, please quickly skim this page.

Goals and Outcomes

In this lab, you will enhance your code reading abilities by debugging an existing class called GradeHistogram, debugging two common Java errors, and finding the passwords to make a programmatic bomb not explode.

Afterwards, you will apply your code reading abilities to enhance your code debugging abilities by debugging a text adventure we have written. We’ll guide you through this process, but the intention is to make this a realistic debugging experience.

By the end of this lab, you will…

Grading in CS 2

Part 1: Debugging GradeHistogram

For this part of the lab, we will approach debugging the code by trying to understand where the tests are failing. To do that, we have to run the tests. Make sure “D Tests” is selected at the top of IntelliJ and click the green play button. The JUnit tests that we have written should run (and all fail!). Your job in this part is to fix the code to make them all pass.

Part 2: Da Bomb!

Using the IntelliJ Debugger

Up until now, you may have practiced debugging by placing print statements throughout your code to monitor the values of certain variables. When strategically placed, the output from these print statements may make the bugs obvious or help narrow down their location. This method is called print debugging. Though print debugging is a valid technique, it can be tedious deciding what to print and cleaning up your code after you are done.

Interactive debugging is a technique by which one debugs by using an interactive tool, or a debugger. We will show you the basics of how to use IntelliJ’s built-in debugger.

Setting Breakpoints

Before starting the IntelliJ debugger, you should set a few breakpoints. Breakpoints mark places in your code where you can suspend the program during a debug session and examine its state. This allows you to examine the values of multiple variables without needing to write print statements, and moreover, breakpoints are ignored when the program is executed normally.

To set a breakpoint at a line or a method, click in the gray area next to the line number.

setting-breakpoint

A red circle or diamond should appear where you clicked. When the debugger reaches this point in the program, it will pause before the execution of the line or method. If you click anywhere on a line of code that has a breakpoint, a lightbulb icon will appear on the left and you can click on it to find more options regarding that breakpoint.

Starting the Debug Session

Once you have set some breakpoints, you are ready to start a debugging session! Click on the debug icon in the top right of the IntelliJ interface. The selected program should run until it hits its first breakpoint. A debugger window should also appear on the bottom of the interface, where the console was.

debug-window

Under “Frames”, you will be able to see all current method calls, and under “Variables”, you will be able to see the values of instantiated variables at this point in the program (they will also be shown in gray text in the editor). From here, you have a few options:

More Breakpoint Options

Sometimes you may want to have your program pause only on certain conditions. To do so, create a breakpoint at the line of interest and open the “Edit breakpoint” menu (by clicking the lightbulb or right-clicking the breakpoint icon itself). There, you can enter a boolean condition such that the program will only pause at this breakpoint if the condition is true.

Another thing you can do is to set breakpoints for exceptions in Java. If your program is crashing, you can have the debugger pause where the exception is thrown and display the state of your program. To do so, click view-breakpoints in the debugger window and press the plus icon to create a “Java Exception Breakpoint”. In the window that should appear, enter the name of the exception that your program is throwing.

If you are curious to learn more about IntelliJ’s debugger, you can find the help guide at https://www.jetbrains.com/help/idea/debugging-code.html.

Part 3: Debugging the Text Adventure

Run the (broken) Game and the (failing) Tests

The very first thing you should do is run the main function in AdventureGame.java. This will give you a sense of what the program you are debugging is actually supposed to do. Then, after you’ve run the game, run the tests; they should fail on BirdCountingStage which will lead you into debugging the first error below.

Debug BirdCountingStage

When a runtime error occurs in Java, a stack trace is printed to the console to provide information on where the error occurred and what steps the program took to get there. When running the tests for the first time, your stack trace will look like this:

stacktrace

The first thing to note is what kind of error occurred; this is shown at the first line of the stack trace. In this case, our code threw a NullPointerException.

The lines beneath it represent the sequence of methods the program took to arrive at the error: the first line in the list is where the error occurred, and the line beneath it represents the line of code that called the method which threw the error, and so on.

trace-line

It turns out that this isn’t the only error in this class!

Debug PalindromeAnimalStage

Still Broken :(

Submitting Your Code for Credit

Your code will be autograded when you submit it to gitlab. You may submit to gitlab as many times as you like, and only the last submission will be counted.

Committing and Pushing to the Repository

A “commit” is version control language for a chunk of changes that mean something when grouped together. Importantly, commits will only stay locally on your machine until you push them to the gitlab server.

Checking the Results on gitlab

When you go to https://gitlab.caltech.edu, you should see your lab01 repository listed. Click on it. All the way on the right, there should be a red “X”, an orange “pause” symbol, a blue “time” symbol, or a green “check” symbol. This symbol indicates the status of the automated tests which will check the correctness of your code. Click on it. On the new page, you should see a table, and under “status”, there should be another symbol. Click on it. The new page will list the “categories” of tests for this repository. These will be some combination of “A”, “B”, “C”, and “D”. These letters indicate what grade you earned on the assessment for passing those tests. If you click on one of them, it will detail for you which sub-tests you passed and failed which might help you debug.

It is good practice to always check gitlab after submitting a project or lab in this course.