@pervognsen When writing C/C++, I mostly find myself using a debugger when things go wrong and I'm likely in UB territory. At this point, I'm mostly looking at the disassembly and all of the source/variable mapping of the debugger is a mere convenience, and it's understandable why some things don't work.
When I see people (mostly from or inspired by the Windows gamedev world) talk about continuous usage of debuggers, I do wonder a bit what they're doing with it. Is it a nice interface for getting traces of execution? Do they just want to set a breakpoint in a function for an input doing something they don't understand then step through it until they do understand? Do they actually want to execute newly compiled code from the debugger like a REPL?
@jc @pervognsen In a low-level language, it's not really possible for the toolchain to provide a uniform tracing solution (because there's no runtime to manage the trace buffer).
However, operating systems provide debugger interfaces, which allow external programs to interpose at the userspace/kernel boundary, which barring the use of binary instrumentation (the other solution @pervognsen mentioned with a different set of tradeoffs) is the only way to provide universal tracing. Or at least almost universal tracing, because ptrace() and friends have all sorts of bugs/quirks that prevent them from working completely reliable, but you're unlikely to create an alternative with higher reliability for uncooperative programs.
This would be my main use for debugging (rather than e.g. actually executing new code with side effects in a debugger context), so given a slightly greener field perhaps it would be better to target this directly?