Don't Panic
Carve out the scenario of the bug
Gather all hard facts about the behavior of the bug and not make assumptions about it. Try to define the scope of the bug to be as precise as possible.
Take the gathered hard facts and use them to construct the scenario in which the bug occurs.
Reproduce the bug
Validate the scenario by reproducing the bug based on it. If the scenario has many steps, design a failing test for it to run the scenario with only one command (the test command).
Debug the bug
carefully read the message error
is the bug a crash or a bad result?
use the stack trace to go between program states and find the unexpected behavior or the bug
get a copy of the data that caused the crash
use binary chop to identify the root of the bug (take the middle and see if the error is there. no? then you need to take the 2nd half of the stack trace and halve it as well. yes? then you take the 1st half of the stack trace and halve it)
apply it to the stack trace to find the function that outputs the wrong value
apply to releases, when you do not know which release introduced the bug
investigate the trace statements/logging
Special Techniques
rubber ducking (explain step-by-step the behavior of the system and the bug)
process of elimination
don't make assumptions about how the code works, but prove it