I don't use a debugger
I spiral around the problem with a test, the smallest test possible that demonstrates the symptom of the bug.
Once I have my test, I go through a phase of analysis where I add print or log statements to see what is going on and find the cause of the bug. I run the test and add/modify the print statements in loop until I understand the cause.
Once the cause is found, it's time for the fixing phase. Again, running the test and modifying the code, but this time until the bug is fixed.
The next phase is running the test suite or a relevant subset of it to make sure the fix didn't break something elsewhere.
The print/log statements introduced in the first phase are slowly discarded in the second phase. Sometimes they stay, but commented out.
I like to leave commented out variants or explanations, for when I come back to the code in later developments or for fellow programmers.
I find it tedious to fire a debugger and tinker with breakpoints. In the time necessary to do 1 debugger cycle, I think I can do 5 cycles of analysis (add print statements, run, analyse, repeat).
Tight feedback loop.
Development is lots of debugging, so I treat debugging as development. Me, the editor, the code and its test suite.
I don't use a debugger, but I know how to use one and I won't hesitate to use it if my debug routine is not effective in given circumstances. Debugger or not, the test reproducing the bug is a necessary by-product.
Triggered by this tweet.