Debugging is a fundamental programming skill. It's also one of the least fun and least glamorous tasks a programmer faces. In order to reduce time spent debugging, I've invested time in examining my debugging methods. Below, I've documented the techniques that most reliably lead me to a solved problem.
I'll avoid getting into the gritty details of particular tools and instead stick to basic principles that can be applied in almost any situation.