Debugging Strategies
IB Syllabus: B2.1.4 — Describe and apply debugging strategies: print statements, trace tables, breakpoints.
Table of Contents
- Key Concepts
- Strategy 1: Print Statements
- Strategy 2: Trace Tables
- Strategy 3: Breakpoints and Step-Through
- Common Bug Patterns
- Quick Code Check
- Trace Exercise
- Trace Exercise 2 — Find the Bug
- Spot the Bug
- Practice Exercises
- GitHub Classroom
- Connections
Key Concepts
Debugging is the process of finding and fixing errors (bugs) in a program. There are three main types of errors:
| Error Type | When it happens | Example |
|---|---|---|
| Syntax error | At compile time | Missing semicolons, mismatched braces |
| Runtime error | During execution | Division by zero, array index out of bounds |
| Logic error | Program runs but gives wrong results | Using < instead of <=, wrong formula |
Logic errors are the hardest to find because the program compiles and runs without crashing — it just produces incorrect results. The strategies below help you track them down.
Strategy 1: Print Statements
Add System.out.println() at key points to inspect variable values during execution.
Example — Finding a Logic Error
This code should find the average of an array, but gives the wrong answer:
int[] scores = {80, 90, 70, 85, 95};
int sum = 0;
for (int i = 0; i <= scores.length; i++) { // Bug here!
sum += scores[i];
}
double average = sum / scores.length; // Bug here too!
System.out.println("Average: " + average);
Add print statements to investigate:
int[] scores = {80, 90, 70, 85, 95};
int sum = 0;
for (int i = 0; i <= scores.length; i++) {
System.out.println("i = " + i); // DEBUG
System.out.println("scores[i] = " + scores[i]); // DEBUG
sum += scores[i];
System.out.println("sum = " + sum); // DEBUG
}
System.out.println("Final sum: " + sum); // DEBUG
double average = sum / scores.length;
System.out.println("Average: " + average);
Running this reveals:
ireaches 5, causingArrayIndexOutOfBoundsException→ fix<=to<sum / scores.lengthuses integer division → fix to(double) sum / scores.length
After fixing bugs, remove the debug print statements before submitting your code.
Strategy 2: Trace Tables
A trace table tracks the value of every variable after each line executes. This is a required skill for IB Paper 2.
Example — Manual Trace
int x = 5;
int y = 3;
int z = x + y;
x = z * 2;
y = x - z;
| Line | x | y | z |
|---|---|---|---|
int x = 5 | 5 | — | — |
int y = 3 | 5 | 3 | — |
int z = x + y | 5 | 3 | 8 |
x = z * 2 | 16 | 3 | 8 |
y = x - z | 16 | 8 | 8 |
Example — Tracing a Loop
int total = 0;
for (int i = 1; i <= 4; i++) {
total += i;
}
| Iteration | i | total (after body) |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 2 | 3 |
| 3 | 3 | 6 |
| 4 | 4 | 10 |
When tracing loops: write the loop variable first, then compute each expression using the current values. After the body runs, record the updated values.
Strategy 3: Breakpoints and Step-Through
In an IDE (like BlueJ, IntelliJ, or VS Code), you can:
- Set a breakpoint — click the line number to mark where execution should pause
- Run in debug mode — the program runs until it hits the breakpoint
- Step through — execute one line at a time and inspect variable values
- Watch variables — see values update in real-time as you step
| Action | What it does |
|---|---|
| Breakpoint | Pauses execution at a specific line |
| Step Over | Execute current line, move to next |
| Step Into | Enter a method call to trace inside it |
| Continue | Run until the next breakpoint or end |
In IB exams, you won’t have an IDE. Practice using trace tables on paper — they are the exam-equivalent of breakpoints.
Common Bug Patterns
Off-by-one Errors
// Bug: <= causes ArrayIndexOutOfBoundsException
for (int i = 0; i <= arr.length; i++) { // should be <
// Bug: starts at 1, skips first element
for (int i = 1; i < arr.length; i++) { // should start at 0
// Bug: misses last element
for (int i = 0; i < arr.length - 1; i++) { // should be < arr.length
Integer Division
int a = 7, b = 2;
double result = a / b; // Bug: result is 3.0, not 3.5
double result = (double) a / b; // Fix: cast to double first
Confusing = and ==
if (x = 5) { ... } // Bug: assignment, not comparison
if (x == 5) { ... } // Fix: use ==
String Comparison with ==
if (name == "Alice") { ... } // Bug: compares references
if (name.equals("Alice")) { ... } // Fix: compares content
Quick Code Check
Q1. A program compiles and runs but produces the wrong output. What type of error is this?
Q2. What is the purpose of a trace table?
Q3. What is wrong with for (int i = 0; i <= arr.length; i++)?
Q4. What does a breakpoint do in an IDE?
Trace Exercise
Trace this code — fill in the value of each variable after each line.
int a = 12;
int b = 5;
int c = a % b;
a = a - c;
b = a / b;
| Line | a | b | c |
|---|---|---|---|
int a = 12 | — | — | |
int b = 5 | 12 | — | |
int c = a % b | 12 | 5 | |
a = a - c | 5 | 2 | |
b = a / b | 10 | 2 |
Trace Exercise 2 — Find the Bug
This code should print the sum of 1 to 5 (expected: 15). Trace it to find the bug.
int sum = 0;
for (int i = 0; i < 5; i++) {
sum += i;
}
System.out.println("Sum: " + sum);
| Iteration | i | sum after body |
|---|---|---|
| 1 | ||
| 2 | ||
| 3 | ||
| 4 | ||
| 5 |
Output prints:
Bug: the loop adds instead of 1+2+3+4+5. Fix: change i = 0; i < 5 to i = 1; i <= 5.
Spot the Bug
This code should find the largest number in an array by comparing each element against a running maximum, but it initializes the maximum incorrectly. This tests a common debugging pattern: choosing the right initial value for accumulator variables. Find the bug.
int[] nums = {3, 7, 2, 9, 5};
int max = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] > max) {
max = nums[i];
}
}What is wrong and how do you fix it?
Practice Exercises
Core
- Trace practice — Complete a trace table for this code:
int a = 8; int b = 3; int c = a / b; a = a % b; b = c + a; - Find the bug — This code should print numbers 1 to 10 but doesn’t work correctly. Find and fix the bug:
for (int i = 1; i < 10; i++) { System.out.println(i); } - Add debug prints — Given a program that calculates the average of an array, add print statements to track
i,arr[i], andsumat each iteration.
Extension
- Trace a nested loop — Trace this code and write the complete output:
for (int i = 1; i <= 3; i++) { for (int j = 1; j <= i; j++) { System.out.print(i * j + " "); } System.out.println(); } - Fix three bugs — This program has three different bugs (syntax, runtime, and logic). Find and fix all three:
int[] data = {10, 20, 30, 40, 50} int sum = 0; for (int i = 0; i <= data.length; i++) { sum += data[i]; } double avg = sum / data.length; System.out.println("Average: " + avg);
GitHub Classroom
Connections
Prerequisites:
- Variables & Data Types — understanding variable values
- Exception Handling — runtime errors are a type of bug
Related Topics:
- Iteration — loops are a common source of off-by-one errors
- 1D Arrays — array bounds errors are frequent bugs
Trace tables are one of the most important exam skills. Practice them regularly — being able to manually trace any code is the foundation of understanding algorithms.