Mastering GDB Source-Tracking Breakpoints: A Step-by-Step Guide
By
<h2 id="introduction">Introduction</h2>
<p>Have you ever been deep in a debugging session with GDB, setting breakpoints on several source lines, inspecting values, and forming hypotheses? You edit your code, recompile, and type <code>run</code> to test the new build—only to find your carefully placed breakpoints have shifted because line numbers changed. Without source-tracking, you must manually disable old breakpoints and set new ones. GDB's experimental source-tracking breakpoints eliminate this hassle. When enabled, GDB captures a snippet of surrounding source code at the breakpoint location. After recompilation and reloading, GDB automatically adjusts breakpoints whose lines moved due to code changes. This guide walks you through enabling and using this feature effectively.</p><figure style="margin:20px 0"><img src="https://fedoramagazine.org/wp-content/uploads/2026/04/GDB_Archer_Fish_by_Andreas_Arnez-300x127.jpg" alt="Mastering GDB Source-Tracking Breakpoints: A Step-by-Step Guide" style="width:100%;height:auto;border-radius:8px" loading="lazy"><figcaption style="font-size:12px;color:#666;margin-top:5px">Source: fedoramagazine.org</figcaption></figure>
<h2 id="what-you-need">What You Need</h2>
<ul>
<li><strong>GDB</strong> version that supports source-tracking breakpoints (experimental feature introduced in recent releases). Check with <code>gdb --version</code>.</li>
<li>A <strong>C/C++ (or other supported language) source file</strong> you can edit and recompile.</li>
<li>A compiled executable with debug symbols (<code>-g</code> flag for GCC).</li>
<li>Basic familiarity with GDB commands: <code>break</code>, <code>run</code>, <code>info breakpoints</code>.</li>
<li>A text editor to modify source code between debug sessions.</li>
</ul>
<h2 id="step-by-step-instructions">Step-by-Step Instructions</h2>
<h3 id="step1">Step 1: Enable Source-Tracking</h3>
<p>Before setting breakpoints, you must activate the source-tracking feature. Inside GDB, run:</p>
<pre><code>(gdb) set breakpoint source-tracking enabled on</code></pre>
<p>This command tells GDB to capture and track source context for all future breakpoints set with <code>file:line</code> notation.</p>
<h3 id="step2">Step 2: Set a Breakpoint Using File:Line</h3>
<p>Place a breakpoint with the familiar <code>file:line</code> syntax. For example, if your source is <em>myfile.c</em> and you want to stop at line 42:</p>
<pre><code>(gdb) break myfile.c:42
Breakpoint 1 at 0x401234: file myfile.c, line 42.</code></pre>
<p>GDB now stores a small window of lines around line 42. The default window size is 3 lines above and below, but you can adjust it (see Tips).</p>
<h3 id="step3">Step 3: Verify Tracking Is Active</h3>
<p>Always confirm that source-tracking is enabled for your breakpoint. Use the <code>info breakpoints</code> command:</p>
<pre><code>(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)</code></pre>
<p>The “source-tracking enabled” message confirms GDB will adjust this breakpoint after source changes.</p>
<h3 id="step4">Step 4: Edit and Recompile Your Source</h3>
<p>Leave GDB running (do not exit). Open your source file in a text editor and make changes <em>above</em> the breakpoint line. For instance, add a few lines of code before line 42. Save the file and recompile your program with debug symbols, e.g.:</p>
<pre><code>gcc -g -o myprogram myfile.c</code></pre>
<p>Keep the same executable name so GDB can reload it.</p>
<h3 id="step5">Step 5: Reload the New Executable</h3>
<p>Back in GDB, type <code>run</code> (or <code>r</code>) to restart the program with the new binary. GDB automatically reloads the executable and scans the source code for each tracked breakpoint. If the code has shifted, GDB prints a message like:</p>
<pre><code>Breakpoint 1 adjusted from line 42 to line 45.</code></pre>
<p>Now, when the program hits breakpoint 1, it will stop at the correct new line 45, preserving your debugging session.</p>
<h3 id="step6">Step 6: Confirm the New Location</h3>
<p>Run <code>info breakpoints</code> again to see the updated breakpoint details:</p>
<pre><code>(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000401256 in calculate at myfile.c:45
source-tracking enabled (tracking 3 lines around line 45)</code></pre>
<p>The line number and address have changed, but the breakpoint remains active and tracked.</p><figure style="margin:20px 0"><img src="https://fedoramagazine.org/wp-content/uploads/2026/04/GDB_Archer_Fish_by_Andreas_Arnez.jpg" alt="Mastering GDB Source-Tracking Breakpoints: A Step-by-Step Guide" style="width:100%;height:auto;border-radius:8px" loading="lazy"><figcaption style="font-size:12px;color:#666;margin-top:5px">Source: fedoramagazine.org</figcaption></figure>
<h2 id="handling-limitations">Handling Limitations</h2>
<p>Source-tracking is powerful but has constraints you should understand:</p>
<ul>
<li><strong>Exact string matching:</strong> The tracking algorithm compares the captured source snippet exactly with the new source. Whitespace-only changes or trivial reformatting of the tracked lines can cause a mismatch. <strong>Tip:</strong> Avoid reformatting the lines immediately around your breakpoint between compilations.</li>
<li><strong>12-line search window:</strong> GDB only searches within a window of 12 lines around the original breakpoint location. If your code shifts by more than that (e.g., a large block inserted above), the breakpoint will not be found. GDB will keep the original location and issue a warning:</li>
</ul>
<pre><code>warning: Breakpoint 1 source code not found after reload, keeping original location.</code></pre>
<ul>
<li><strong>Pending breakpoints:</strong> Breakpoints set with <code>set breakpoint pending on</code> (where no symbol table is yet available) cannot capture source context. <strong>Tip:</strong> Only use source-tracking breakpoints after the executable is loaded and symbols are resolved.</li>
</ul>
<h2 id="tips">Tips for Success</h2>
<ul>
<li><strong>Adjust the tracking window size:</strong> Use <code>set breakpoint source-tracking lines N</code> before setting breakpoints to control how many lines around your target are captured (minimum 1, maximum 10). A larger window reduces the chance of mismatch from whitespace changes, but increases the risk of collisions if many lines are identical.</li>
<li><strong>Keep GDB running:</strong> The feature shines when you stay in the same GDB session. Do not exit GDB after recompilation; just type <code>run</code> to reload.</li>
<li><strong>Test with trivial changes first:</strong> Before relying on this feature in complex debugging, practice with small edits to understand the matching behavior.</li>
<li><strong>Disable when not needed:</strong> If you prefer manual breakpoint management, turn off source-tracking with <code>set breakpoint source-tracking enabled off</code> to avoid unnecessary overhead.</li>
<li><strong>Use file:line syntax only:</strong> Source-tracking works only with breakpoints set by file and line number. Breakpoints set by function name or address are not tracked.</li>
</ul>
<p>By following these steps and tips, you can streamline your debugging workflow and avoid the frustration of resetting breakpoints after every code change. Source-tracking breakpoints make iterative editing and debugging much smoother.</p>
Tags: