Good to see GDB's watchpoints (https://sourceware.org/gdb/download/onlinedocs/gdb/Set-Watch...) get a mention. Often called Data Breakpoints in IDEs (which then, confusingly, often also use "Watch" for a different concept - argh).
Watchpoints, when they're suitable, are an incredibly powerful way to query your program's runtime behaviour (When does this happen? Why does this value end up here?) instead of stepping through and printing things / logging stuff.
They also fast, provided you watch values suitable for the CPU's logic to handle them directly. They need to be small-ish and located in memory for hardware support to handle it, otherwise GDB needs to single step.
(the `-l` flag is also important here and even less well known - it tells GDB you really care about the memory address the expression is stored in, not the expression itself)