Mastering GDB's Source-Tracking Breakpoints: A Hands-On Guide

From Codenil, the free encyclopedia of technology

Overview

Debugging with GDB is a daily ritual for many C/C++ developers, but the traditional workflow can be frustrating when you edit source code between debug sessions. Every time you make a change and recompile, your carefully placed breakpoints become misaligned because line numbers shift. You then have to manually disable old breakpoints and set new ones—a tedious cycle that breaks your concentration.

Mastering GDB's Source-Tracking Breakpoints: A Hands-On Guide
Source: fedoramagazine.org

GDB’s experimental source-tracking breakpoints feature solves this by capturing a snapshot of the source code around each breakpoint. When you reload a recompiled executable, GDB automatically adjusts breakpoints to their new line positions. This guide walks you through enabling, using, and troubleshooting this feature, so you can debug faster with fewer interruptions.

Prerequisites

What You’ll Need

  • GDB version 11.0 or later – source-tracking breakpoints are experimental and require at least GDB 11. Check your version: gdb --version
  • A C or C++ project that you can recompile while keeping a GDB session alive (e.g., using make or gcc from within GDB)
  • Basic familiarity with GDB commands (e.g., break, run, info breakpoints)

Enabling the Feature

Source-tracking must be explicitly turned on. Inside GDB, run:

(gdb) set breakpoint source-tracking enabled on

This setting is not persistent across sessions. To make it permanent, add the line to your .gdbinit file:

echo 'set breakpoint source-tracking enabled on' >> ~/.gdbinit

Step-by-Step Instructions

Step 1: Set a Breakpoint Using File:Line Notation

Only breakpoints defined with the file:line format are eligible for source-tracking. Avoid using function names or addresses if you want automatic adjustment.

(gdb) break myfile.c:42
Breakpoint 1 at 0x401234: file myfile.c, line 42.

GDB immediately captures a small context window around line 42. By default, it stores 3 lines (the breakpoint line plus one above and one below). You can verify tracking with info breakpoints:

(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000401234 in calculate at myfile.c:42
        source-tracking enabled (tracking 3 lines around line 42)

Step 2: Edit Your Source Code

While GDB remains running, modify the relevant file. For example, insert a few lines above line 42 (e.g., an additional debug print). Save the file and recompile (using make or gcc from another terminal or a GDB shell command).

(gdb) shell gcc -g -o myprogram myfile.c

Step 3: Reload the Executable

Reload the newly built binary with run (or file followed by run). GDB detects that the executable has changed and attempts to match the saved source context.

(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Breakpoint 1 adjusted from line 42 to line 45.

The adjustment message confirms that GDB found the new location. You can double-check with info breakpoints:

(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000401267 in calculate at myfile.c:45
        source-tracking enabled (tracking 3 lines around line 45)

The breakpoint now points to line 45, where your original line of interest ended up after the edits.

Step 4: Troubleshooting When Adjustment Fails

If the source context cannot be matched—either because the surrounding lines changed significantly or the shift exceeded the search window—GDB issues a warning and preserves the original location. For instance:

warning: Breakpoint 1 source code not found after reload, keeping original location.

In that case, you must manually reassign the breakpoint. This is expected for large-scale edits (see Limitations).

Common Mistakes and How to Avoid Them

Using a Breakpoint Set by Function Name or Address

Source-tracking only works with file:line breakpoints. If you set a breakpoint with break calculate, no source context is captured and the breakpoint will not adjust. Always use break filename.c:linenumber.

Mastering GDB's Source-Tracking Breakpoints: A Hands-On Guide
Source: fedoramagazine.org

Whitespace Changes to Tracked Lines

The matching algorithm requires an exact string match of the captured lines. Changing indentation, adding/removing spaces, or reformatting (e.g., from tabs to spaces) will cause the match to fail. Avoid cosmetic changes to the lines immediately surrounding your breakpoint.

Edits That Shift Code Beyond the Search Window

GDB searches for the captured context within a 12-line window (6 lines before and 6 lines after the original location). If you insert dozens of lines above the breakpoint, the new location will fall outside this window. In such cases, GDB gives up and keeps the old address. Plan your edits to avoid massive shifts near breakpoints, or manually recreate the breakpoint after large refactoring.

Setting Breakpoints While Pending

If you use set breakpoint pending on (which defers resolution until the symbol table is available), no source context can be captured because GDB lacks the source at the time of creation. Always ensure the relevant source file is compiled and loaded before enabling source-tracking on that breakpoint.

Not Re-enabling Source-Tracking After a Restart

The set breakpoint source-tracking enabled on setting does not persist across GDB sessions. If you quit and restart, you must turn it on again (or use .gdbinit as mentioned earlier).

Known Limitations of Source-Tracking Breakpoints

  • Exact match only: Any change to the tracked lines (even a single whitespace character) breaks matching.
  • Limited search range: GDB only inspects ±6 lines from the original location for a best-guess match. Edits beyond this range are not handled.
  • No support for pending breakpoints: Breakpoints created before symbols are loaded cannot capture source context.
  • Experimental status: This feature is under active development. Behavior may change in future GDB versions, and it may have edge cases not yet ironed out.

Summary

GDB's source-tracking breakpoints automate one of the most repetitive tasks in debugging: manually adjusting breakpoints after editing code. By enabling this experimental feature with set breakpoint source-tracking enabled on and setting breakpoints via file:line, you can let GDB handle line-number shifts automatically. While the feature has limitations—strict string matching and a 12-line search window—it works well for small, localized edits. Mastering it will save you time and keep your debugging flow smooth.

For further details, refer to the GDB manual on breakpoints.