Lolpro Lab
📖 Tutorial

Smarter Breakpoints in GDB: How Source-Tracking Keeps Your Debugging on Track

Last updated: 2026-05-01 06:51:24 Intermediate
Complete guide
Follow along with this comprehensive guide

Overview

Ever spent a debugging session setting careful breakpoints, only to have them become useless after a quick edit and recompile? With GDB’s experimental source-tracking breakpoints, that frustration disappears. This feature remembers the exact source lines you set breakpoints on by capturing a small window of surrounding code. When you edit, recompile, and reload the executable, GDB automatically adjusts breakpoints to their new line numbers. No more disabling old breakpoints or hunting for the right location.

Smarter Breakpoints in GDB: How Source-Tracking Keeps Your Debugging on Track
Source: fedoramagazine.org

Source-tracking works by saving a text snippet (default three lines) around each breakpoint set with file:line notation. After recompilation, GDB compares the saved snippet with the new source file and relocates the breakpoint if the content matches but the line number shifted. This guide walks you through enabling and using the feature, plus common pitfalls.

Prerequisites

  • GDB version: GDB 14.0 or later with the experimental source-tracking feature. Check your version with gdb --version. If missing, upgrade to a recent release.
  • Executable and source code: A program compiled with debug symbols (-g flag) so GDB can map addresses to lines.
  • Basic GDB familiarity: You should know how to start GDB, set breakpoints, and run programs.
  • Editor access: You will modify the source code between debug cycles to see the breakpoint adjustment.

Step-by-Step Instructions

1. Enable Source-Tracking in GDB

Before setting any breakpoints, turn on the feature. Inside GDB, run:

(gdb) set breakpoint source-tracking enabled on

GDB confirms the change by updating the prompt or showing no error. You can verify the setting with:

(gdb) show breakpoint source-tracking

It should print enabled on.

2. Set a Source-Tracking Breakpoint

Use the familiar file:line syntax. For example, in myapp.c line 42:

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

Notice GDB didn’t print anything about source tracking yet. Check the breakpoint details with info breakpoints:

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

The line source-tracking enabled (tracking 3 lines around line 42) confirms GDB captured the source snippet. The default window size is three lines (the breakpoint line, one above, one below). You can change this with set breakpoint source-tracking context-lines N (N must be odd).

3. Edit the Source and Recompile

Leave GDB running (do not exit). Open myapp.c in another terminal or editor. Add a few blank lines or function calls above line 42. For instance, insert two new lines before the line you set the breakpoint on. The breakpoint now logically resides at line 44 or 45, depending on your edits. Recompile the program with the same debug flags:

gcc -g -o myapp myapp.c

4. Reload the Executable in GDB

Back in GDB, use the run command (or file to load the new binary, then run). GDB automatically detects the executable changed and attempts to re-symbolicate:

(gdb) run
Breakpoint 1 adjusted from line 42 to line 45.
[Starting program ...]

The message “Breakpoint 1 adjusted from line 42 to line 45.” shows the feature worked. GDB found the three-line snippet somewhere else (line 45) because the added lines shifted it. Now list the breakpoints again:

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

The address also updated automatically. You can continue debugging without manual intervention.

5. What If Adjustment Fails?

Source-tracking is not magic. It relies on an exact text match of the captured lines (including whitespace and comments). If the editor reformatted the code or changed the snippet substantially, GDB cannot find a match. It will warn you:

Smarter Breakpoints in GDB: How Source-Tracking Keeps Your Debugging on Track
Source: fedoramagazine.org
(gdb) run
warning: Breakpoint 1 source code not found after reload, keeping original location.

The breakpoint stays at the old line number (which no longer corresponds to the intended code). You must manually delete or disable it. We discuss such pitfalls in the next section.

Common Mistakes and How to Avoid Them

Whitespace and Formatting Changes

The matching algorithm compares exact strings. If you change indentation, add or remove spaces, or rewrap comments, the snippet won’t match. Even a single trailing space difference breaks it. Solution: Avoid reformatting the tracked lines between debug cycles. Use consistent indentation and consider disabling auto-formatters on those lines.

Large Code Shifts Beyond the Search Window

GDB only searches within a 12-line window centered on the original breakpoint line (the default 3-line context plus 9 lines of wiggle room). If you insert more than 12 lines above the breakpoint, the snippet will fall outside this window and never be found. Solution: Delete and re-set the breakpoint after major code reorganizations. You can also increase the context-lines (e.g., set breakpoint source-tracking context-lines 21) to widen the window, but that may cause performance overhead and false matches.

Pending Breakpoints

If you use set breakpoint pending on and set a breakpoint on a function or line that hasn’t been loaded yet (e.g., from a shared library), GDB cannot capture source context because no symbol table is available. The breakpoint will be created but without source-tracking. Solution: Either avoid pending breakpoints when you need tracking, or set the breakpoint after the library is loaded (e.g., after start or run).

Multiple Files with Same Name

GDB uses the file name as part of the tracking key. If your project has two files named utils.c in different directories, GDB may capture context from the wrong one. Solution: Use full or relative paths when setting breakpoints, e.g., break src/parser/utils.c:10.

Summary

GDB’s source-tracking breakpoints dramatically reduce friction in iterative development. By enabling this experimental feature, you can edit, recompile, and reload your program without manually repositioning breakpoints. The feature captures three lines of context (configurable) around each breakpoint and re‑locates them when line numbers shift. However, it requires exact textual matches, a small search window, and cannot handle pending breakpoints. For typical edit‑compile‑debug loops, it’s a game changer. Try it today and stop wasting time on breakpoint maintenance.