I've recently had the pleasure to drill down (from C) to single machine instructions in my quest to understand why a conditional branch was seemingly having no effect, on an architecture that I couldn't debug on. As it turns out, the compiler would sometimes use a memory addressing scheme that wasn't supported on this particular architecture. I had to work around this bug by writing assembly that correctly accesses the memory.
It's incredibly frustrating when you end up at a point where the only abstraction (and seemingly faulty) layer below you is nanometer-sized transistors. And all the more rewarding when you reveal the actual problem and get to extend your knowledge.
(Of course, this doesn't really apply to all the ridiculous pain points that annoy us by design. Things like browser compatibility come to mind.)