Things you can do with a debugger but not with print debugging

Hardware breakpoints & watchpoints

  • Several commenters highlight hardware watchpoints (aka data breakpoints) as a killer feature: break on read/write/exec of a specific memory address or symbol, ideal for tracking memory corruption or invariant violations.
  • On common MCUs and CPUs, a debug unit can raise an interrupt when a watched address is touched; debuggers surface this directly at the offending instruction.
  • Expression/watch debugging (e.g., breaking when bufpos < buflen is violated) is cited as another powerful capability, especially combined with reverse execution.

Time‑travel & historical debugging

  • Time‑travel / record‑replay tools (rr, UndoDB, WinDbg TTD) are repeatedly praised: record once, then step backward in time to see when corruption occurred.
  • This is contrasted with logging, where you often need multiple “add logs, rerun many times” iterations.
  • Some note “offline” debugging systems that log everything (or traces with GUIDs per scope) to reconstruct and compare runs over long periods.

Print vs debugger: tradeoffs

  • One camp treats debuggers as essential, faster than iterating on printf once configured, especially for unknown codebases, third‑party libraries, and large projects where rebuilds are slow.
  • Another camp prefers print/logging for most bugs, using debuggers only for very low‑level or hard‑to-isolate issues (assembly, watchpoints). Arguments:
    • Logs persist, diff easily, can be shared with others or from production.
    • Printing is universal across languages and environments.
    • Debugger UIs/CLIs can be clumsy or unreliable.
  • Some emphasize tracepoints/logpoints as a “best of both worlds”: debugger-managed printing without code edits or cleanup.

Race conditions & timing effects

  • Multiple commenters note that both debuggers and print statements can perturb timing and hide races; prints are often seen as less intrusive, but not always.
  • Suggestions include ring-buffer logging, binary logs formatted off-device, ftrace/defmt-style approaches, and hardware tools (ICE) for precise timing.

Tooling quality & environment constraints

  • Debugger experience varies widely: Visual Studio and browser debuggers are praised; gdb/lldb CLIs and some language ecosystems are seen as painful.
  • Constraints cited: remote/locked-down systems, kernels and drivers, embedded targets, proprietary libraries, multi-language stacks, and enormous debug builds.
  • In such cases, logging, REPLs, structured tracing, and profilers (time/memory, SQL planners, GPU tools, etc.) often become primary tools.

Culture, learning & mindset

  • Many remark that debuggers are under-taught; some developers simply don’t know modern features (watchpoints, conditional breakpoints, tracepoints).
  • Others frame the debate as mindset: understanding systems via interactive introspection vs encoding that understanding into persistent logs/tests.
  • Broad consensus: both debuggers and print/logging are important; effective engineers know when to reach for which.