#1. Understand the problem before you fix it
It is essential to know what is the root cause of the bug you are about to fix.
#2. Check for common defects
It is usual to find a defect duplicated again in a similar abstraction.
#3. Refine the test cases that produce the error.
Now is the time to write so unit test if you haven't cover this piece of code properly. And you surely didn't :)
So write a test to reproduce the defect, fix it, verify it's working and keep testing for regressions.
#4. Narrow the suspicious region of the code. / Expand the suspicious region of the code.
Depending on what you are digging for.
#5. Be suspicious of classes and routines that have had defects before.
Related to the first point.
#6. Check code that’s changed recently.
This is very important as some minor thing could have sneaked in.
#7. Set a maximum time for quick and dirty debugging => rewrite the code
We always want to make it fast and unnoticeable but sometimes the digging is prolonged enough to think about rewriting the code then.
#8. Change the code only for good reason AND Make one change at a time
Resist the temptation to change this and that just because you are about to fix something really wrong.
These other changes could result in a rollback of the main fix. Never know.
#9. Never debug standing up :)
Inspired by Code Complete