Debugging with GDB
Explore how to debug C++ programs effectively using GDB. Understand compiling with debug symbols, setting breakpoints, stepping through code, and inspecting variables to identify logic errors and crashes. Gain skills to systematically trace execution and fix bugs in real-world applications.
Up to this point, we have likely relied on console output to diagnose issues in our programs. While std::cout can be helpful, it is ultimately a blunt tool: it clutters the codebase, requires repeated recompilation, and provides no insight if the program crashes before reaching the print statements. To build reliable, production-quality software, we need a tool that allows us to pause execution, step through code line by line, and inspect program state as it runs. That tool is the debugger.
In this lesson, we will use GDB (the GNU Debugger), a widely used, professional-grade tool for diagnosing crashes and logic errors with precision.
The debugging mindset and preparation
Debugging is not guesswork. It is a structured process of comparing what the program should do with what it actually does. To debug effectively, we need visibility into the source-level behavior of the program while it is executing.
By default, compilers apply optimizations and remove many human-readable details to improve performance and reduce binary size. A debugger relies on additional metadata, called debug symbols, to map machine instructions back to source files, line numbers, and variable names. To include these symbols, we compile with the -g flag.
Compiling with debug symbols
To illustrate the workflow, we will examine a small program that contains a logic error. The goal is to compute the sum of the integers from 1 to 5, but the program produces an incorrect result.
#include <iostream>
int calculate_sum(int limit) {
int sum = 0;
// Intentional error: loop condition goes too far
for (int i = 1; i <= limit + 1; ++i) {
sum += i;
}
return sum;
}
int main() {
int result = calculate_sum(5);
std::cout << "Sum is: " << result << std::endl;
return 0;
}Let’s break this down step by step:
Lines 3–10: We define the
calculate_sumfunction, which loops from ...