Catch Memory Changes with GDB Watchpoints in C/C++
This guide explains how to set hardware watchpoints in GDB to monitor specific memory addresses, demonstrates the technique with a simple C++ program that modifies a variable via a thread, and shows how GDB reports the exact location and values of the change.
Memory management is a powerful feature for C/C++ developers, but bugs caused by unintended reads or writes can be hard to locate. GDB provides a watchpoint mechanism that stops program execution whenever a specified memory region is accessed, allowing you to pinpoint the exact code responsible for the modification.
Example Program
The following C++ code creates a local variable a, spawns a thread that changes its value, and prints the result:
#include <iostream>
#include <thread>
using namespace std;
// Thread function that writes to the given address
void memory_write(int* value) {
*value = 1;
}
int main() {
int a = 10;
int* c = &a; // address of a
for (int i = 0; i < 100; i++) {
a += i;
}
cout << a << endl; // prints 4960
thread t(memory_write, c);
t.join();
return 0;
}When run, the program prints 4960. After the thread modifies a, the value becomes 1. We want to discover which line performed the change.
Setting Up GDB
Compile the program (e.g., g++ -g a.cc -o a.out -pthread) and start GDB:
$ gdb a.out
(gdb) b a.cc:20
Breakpoint 1 at 0x400f23: file a.cc, line 20.
(gdb) r
Starting program: /bin/a
Breakpoint 1, main () at a.cc:20
20 cout << a << endl;After hitting the breakpoint, inspect the address of a:
(gdb) p &a
$1 = (int *) 0x7fffffffe508Set a hardware watchpoint on that address:
(gdb) watch *(int*)0x7fffffffe508
Hardware watchpoint 2: *(int*)0x7fffffffe508This tells GDB to monitor the 4‑byte region starting at 0x7fffffffe508 (size of an int).
Running and Capturing the Change
Continue execution:
(gdb) c
Continuing.
4960When the thread writes to a, GDB stops and reports:
[New Thread 0x7ffff6f5c700 (LWP 531823)]
[Switching to Thread 0x7ffff6f5c700 (LWP 531823)]
Hardware watchpoint 2: *(int*)0x7fffffffe508
Old value = 4960
New value = 1
memory_write (value=0x7fffffffe508) at a.cc:8
8 }
(gdb)The output shows the previous value (4960), the new value (1), and the exact source location ( a.cc:8) where the modification occurred – the thread function memory_write.
This demonstrates how GDB’s hardware watchpoints can act as a “memory crime scene investigator,” instantly revealing which instruction altered a specific memory location.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Tech Enthusiast
Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
