Debugging Strategies

IB Syllabus: B2.1.4 — Describe and apply debugging strategies: print statements, trace tables, breakpoints.

Table of Contents

  1. Key Concepts
  2. Strategy 1: Print Statements
    1. Example — Finding a Logic Error
  3. Strategy 2: Trace Tables
    1. Example — Manual Trace
    2. Example — Tracing a Loop
  4. Strategy 3: Breakpoints and Step-Through
  5. Common Bug Patterns
    1. Off-by-one Errors
    2. Integer Division
    3. Confusing = and ==
    4. String Comparison with ==
  6. Quick Code Check
  7. Trace Exercise
  8. Trace Exercise 2 — Find the Bug
  9. Spot the Bug
  10. Practice Exercises
    1. Core
    2. Extension
  11. GitHub Classroom
  12. 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:

  • i reaches 5, causing ArrayIndexOutOfBoundsException → fix <= to <
  • sum / scores.length uses 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:

  1. Set a breakpoint — click the line number to mark where execution should pause
  2. Run in debug mode — the program runs until it hits the breakpoint
  3. Step through — execute one line at a time and inspect variable values
  4. 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;
Lineabc
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);
Iterationisum 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

  1. 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;
    
  2. 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);
    }
    
  3. Add debug prints — Given a program that calculates the average of an array, add print statements to track i, arr[i], and sum at each iteration.

Extension

  1. 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();
    }
    
  2. 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

Debugging Exercises
Practice trace tables, finding bugs, and using print statements for debugging.

Connections

Prerequisites:

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.


Back to top

© EduCS.me — A resource hub for IB Computer Science

This site uses Just the Docs, a documentation theme for Jekyll.