Working in Opposite Land
There are a number of interesting things that come up in computer science and computer engineering where reasoning suddenly jumps into opposite land. It seems that the more human the operation, the more likely we are to go to opposite land. For example, it has been measured that it is more efficient to send your engineers home at a reasonable hour when a project is late than it is to have them work long hours. Efficiency doesn't scale with time spent, but exhaustion sure does.
My trip into opposite land has to do with finding and fixing bugs. From experience (and I wish I had the time to set up a proper study to examine this), I have noticed that I am more efficient in finding and fixing bugs by reading code. Just reading - not time spent in the debugger.
Don't get me wrong - debuggers are awesome tools and I've spent enough time working on systems where the debugger was the equivalent of printf or worse, and I don't really miss that.
Debuggers, however, are good for isolating and reproducing bugs, but not for finding and fixing. The downside to debuggers is that they tend to narrow your vision. This can be a good thing - if your bug is an off-by-one error, swapped parameters, or a typo. These bugs are trivial in nature. The more significant bugs are those that are caused by faulty logic, poor design, hurried or incomplete coding, and so on. With narrow vision, it is natural to apply the fix at the point of failure rather than making the actual fix. More's the pity, because putting a fix at the point of failure makes a fragile fix and can simply hide the problem. This isn't debugging - it's hacking.
Instead, you should read code with the goal of seeing the big picture as well as the little picture. Could this be better fixed with a design change in the model than with a point fix? Is the problem that there is a break in the contract between API and client? Reading code lets you fix not just this bug but to also defend against bugs of the same type in the future. Maybe it's a good time to apply a debug assert or a throw for parameters out of range and set the right unit test on it. Reading also lets you get a better feel for flow than stepping with the debugger. You can divide and conquer chunks of code by factoring if statements on assumptions and use that to devise further tests to make sure that you're fixing what you are intending.
And above all, recidivation is not an option.
In sum, when you've reproduced your bug, stop before you apply a spot fix. Read. Ask questions about the big picture and defend for future bugs.