I've worked in fields where no debugger where available, not even printf. (embedded software, interrupt driven)
I had to write ad-hoc debugging tools with difficult contraints.
I grew the habit of debugging by reading the code first, then using traces, then writing custom tests or ad-hoc tools as last resort solution. (extremely rare)
I used Visual Studio debugger and GDB a few times, but I've not been convinced by the productivity gains, quite the contrary, but I am probably not using them well.
In practice, the most difficult bugs are often tied to concurrency issues, and I haven't found much help with those general purpose tools.
I mean, these are orthogonal, not mutually exclusive. You need to use whatever combination of tools makes sense for your tasks. Sometimes it's a debugger, sometimes it's printf, sometimes it's a hard reboot, sometimes it's an infinite loop, etc... and sometimes there just isn't any great solution. Nobody was suggesting you have to use a debugger everywhere or that a debugger is the solution to every problem. Just like none of the solutions you mentioned is. I'm just saying if you are using a debugger/IDE (which I can assure people use quite seriously, even if you don't come across such situations personally), then you might want to watch out for the repercussions.
I've worked in fields where no debugger where available, not even printf. (embedded software, interrupt driven)
I had to write ad-hoc debugging tools with difficult contraints.
I grew the habit of debugging by reading the code first, then using traces, then writing custom tests or ad-hoc tools as last resort solution. (extremely rare)
I used Visual Studio debugger and GDB a few times, but I've not been convinced by the productivity gains, quite the contrary, but I am probably not using them well.
In practice, the most difficult bugs are often tied to concurrency issues, and I haven't found much help with those general purpose tools.