Debugging is that wonderful time when your expectations don't line up with reality. You set things up just so, making sure they make sense, and then reality hits you with an unexpected truth; you are wrong.
But you eat some humble pie, interrogate your expectations, and revisit your assumptions in the light of this new reality. After you've done all that (and save some pie for me!), you find a problem, adjust your expectations and assumptions, change your implementation and now you and reality see eye to eye once again.
Of course, other things get in the way as well - bugs in third-party code, or any dependencies your code or toolchain requires. Always check your own code first. I don't care how many compiler bugs have bitten you before, you know your code, so it's quick to check. Once all that's done, find the bugs, create patches, and forward them to the appropriate maintainers.
Don't let your ego get in the way of successful debugging. What you thought should be true is not, and no amount of "But it should work!" will make it so.