Exercise 2.0: Introduction to the Debugger
1 Purpose
The purpose of this exercise is to introduce you to the fundamentals of interactive debugging using the Visual Studio Code debugger. You will learn how to pause your program’s execution, inspect its state, and step through the code line-by-line. Mastering the debugger is a critical skill for efficiently finding and fixing bugs in your code.
2 What You’ll Accomplish
By the end of this exercise, you will have successfully:
- Set a breakpoint to pause your program at a specific line.
- Launched a debug session for a Java application in VS Code.
- Used the “Step Over” control to execute your code line-by-line.
- Observed how variable values change during execution in the “Variables” panel.
- Added a variable to the “Watch” panel to monitor its state.
This exercise maps to the following program and course learning outcomes:
- Program Learning Outcomes (PLOs):
- 2. Use current tools: You will use the integrated debugger in VS Code.
- 4. Use system software: You will interact with the Java runtime environment.
- 6. Maintain environment: You will learn a core process for troubleshooting a computer system environment.
- Course Learning Outcomes (CLOs):
- 2. Compile, debug, and test: This exercise is a foundational component of debugging and testing programs.
This exercise will help you develop the following skills and knowledge, which align with the O*NET SOC Code 15-1251.00 for Computer Programmers.
| Learning Objective | O*NET KSAs | Technologies Used |
|---|---|---|
| Set and hit breakpoints to pause execution. | Skills: Programming, Monitoring Abilities: Problem Sensitivity |
Program testing software: Symbolic debugger software |
| Use step controls (Step Over, Step Into) to navigate code. | Skills: Critical Thinking Abilities: Selective Attention |
Program testing software: Symbolic debugger software |
| Inspect variable states in the ‘Variables’ and ‘Watch’ panels. | Skills: Monitoring, Critical Thinking Abilities: Information Ordering |
Development environment software: VS Code |
3 Introduction to Debugging
So far, you have been finding errors by reading compiler messages or by adding System.out.println() statements to see what your program is doing. While this works for simple cases, it quickly becomes inefficient for complex problems. A debugger is a professional tool that gives you full control over your program’s execution, allowing you to inspect its state at any moment.
In this exercise, we will use the App.java file from your project to practice these skills.
3.1 1. Prepare Your Code
First, let’s ensure your App.java file has some variables to inspect. Open src/main/java/edu/pstcc/citc/App.java and make sure it contains the following code. This simple program declares a few variables and prints them.
package edu.pstcc.citc;
public class App {
public static void main(String[] args) {
String name;
if (args.length > 0) {
name = args[0];
System.out.println("Hello, " + name + "!");
} else {
System.out.println("Hello, World!");
}
String message = "Hello, Debugger!";
int number = 42;
System.out.println(message);
int result = number * 2;
String finalMessage = "The result is: " + result;
System.out.println(finalMessage);
}
}Adding new output lines to App.java causes the program output to change and may break existing unit tests. The JUnit test files contain assertions that check the exact text printed to the console. The JUnit test will fail due to the change in output. We’ll fix the tests later so they pass. For now, you can just comment them out temporarily while you work on this exercise.
Select the entire code block with the two tests shown below and comment them out all at once using the Ctrl-/ keyboard shortcut. Don’t forget to also comment out the JavaDoc comments above each test as well so the JavaDoc generator does not pick them up as part of the documentation.
// /**
// * Tests that the application prints the correct greeting when a command-line
// * argument is provided.
// */
// @Test
// public void testAppPrintsCorrectOutputWithArgument() {
// String expectedOutput = "Hello, TestUser!\n";
// App.main(new String[] { "TestUser" });
// assertEquals(expectedOutput, outContent.toString());
// }
// /**
// * Tests that the application prints the default greeting when no command-line
// * argument is provided.
// */
// @Test
// public void testAppPrintsCorrectOutputWithoutArgument() {
// String expectedOutput = "Hello, World!\n";
// App.main(new String[] {});
// assertEquals(expectedOutput, outContent.toString());
// }Once your code compiles correctly, you can proceed to the next section.
3.2 2. Set a Breakpoint
A breakpoint is a signal that tells the debugger to pause execution at a specific line of code, before that line is executed.
- In your
App.javafile, find the lineString message = "Hello, Debugger!";. - To the left of the line number, you will see a faint red dot when you hover your mouse there. Click in the gutter to the left of the line number to set a breakpoint. A solid red dot will appear.
3.3 3. Start the Debugger
Instead of running the program with Maven, we will use the debugger.
- Go to the Run and Debug view in the VS Code Activity Bar (the icon looks like a play button with a bug).
- Click the green Run and Debug button at the top. VS Code will build your project and start the debugger.
- The program will start, and its execution will immediately pause at the breakpoint you set. The line will be highlighted, indicating this is the next line to be executed.
If the program finishes before the debugger has a chance to fully attach, you can force it to stop immediately upon execution. Modify launch.json and add “stopOnEntry”: true to your configuration. The updated configuration will have an entry similar to this:
{
"type": "java",
"name": "App",
"request": "launch",
"mainClass": "edu.pstcc.citc.App",
"projectName": "hello-world",
"stopOnEntry": true
}3.4 4. Inspect Variables
With the program paused, you can inspect its state.
- Look at the VARIABLES panel on the left side of the VS Code window.
- You will see a
Localscope. Expand it. - You should see the
argsvariable. Themessageandnumbervariables have not been created yet, because we are paused before their lines have run.
Now, let’s add a Watch Variable. This is useful for tracking a specific variable or expression.
- In the WATCH panel (just below VARIABLES), click the + icon.
- Type
resultand press Enter. It will say<error: result is not defined>because we haven’t reached the line whereresultis declared yet. This is expected.
3.5 5. Step Through the Code
At the top of the editor, a debug toolbar has appeared. This toolbar allows you to control the execution of the program.
- Continue (F5): Resumes running the program until the next breakpoint or the end.
- Step Over (F10): Executes the current line and moves to the next line in the same function.
- Step Into (F11): If the current line is a method call, it moves into that method’s code.
- Step Out (Shift+F11): Finishes executing the current method and returns to the line where it was called.
- Restart (Ctrl+Shift+F5): Restarts the debugging session.
- Stop (Shift+F5): Ends the debugging session.
Now, let’s step through the code:
- Click the Step Over button (or press F10). The debugger will execute the line
String message = "Hello, Debugger!";and pause on the next line.- Observe: In the VARIABLES panel, the
messagevariable now appears with the value"Hello, Debugger!".
- Observe: In the VARIABLES panel, the
- Click Step Over again. The line
int number = 42;is executed.- Observe: The
numbervariable now appears with the value42.
- Observe: The
- Click Step Over two more times, moving past the
System.out.printlnand onto the lineString finalMessage....- Observe: The
resultvariable now appears in the VARIABLES panel, and its value (84) is also shown in the WATCH panel.
- Observe: The
- Click Step Over one last time.
- Observe: The
finalMessagevariable appears.
- Observe: The
3.6 6. Continue to the End
You have stepped through the core logic. Now, click the Continue button (the blue play icon) to let the program run to completion. The program will finish executing, and the debug session will end.
Congratulations! You have successfully used the VS Code debugger to step through a program, inspect its variables, and watch their values change. This is a fundamental skill you will use throughout your programming career.
4 Reflect and Review
Now that you have completed this exercise, take a moment to reflect on your learning. In your Microsoft Teams Student Notebook, create a new page for this exercise if necessary and write down the following:
- 3 things you learned about using the VS Code debugger.
- 2 ways you think the debugger will be more helpful than using
System.out.println(). - 1 question you still have about debugging and how you will go about learning more about it.
This reflection is for your instructor to review and helps solidify your understanding of the concepts.
Test your understanding with the following questions. These questions provide retrieval practice and reinforce key concepts covered in this exercise. In your Microsoft Teams Student Notebook, create a new page for this exercise if necessary and answer the following:
- What is the purpose of setting a breakpoint in your code?
- You are paused at a line of code that calls a method (
myObject.doSomething();). If you want to execute this line and move to the next line without going inside thedoSomething()method’s code, which debug control should you use? - Describe the difference between the “Variables” panel and the “Watch” panel in the VS Code debugger. When would you use the “Watch” panel?
- If you set a breakpoint on a line that declares and initializes a variable (e.g.,
int x = 10;), when does the variablexfirst appear in the “Variables” panel: before or after you “Step Over” that line? Why?