Assuming the bug is in a project I use regularly this is a great place to start. Adding features also works. I just think of an unusual string that I saw in the "interface" that's associated with the bug or feature. Unusual strings I look for incorporate infrequent words, long words, mispellings (beneficial!), non-idiomatic use of whitespace, etc. I avoid numbers since those tend to get printed with printf format strings (C-like code) or come from variables (the rest). I try to choose unusual strings that are as closely related to my desired bug/feature as possible. A well-crafted grep (and an SSD for large code repositories) will quickly find one or more of those and that's where I start reading the code.
The great thing about this method is I've already got context for this portion of the code without even reading it. I've used this code and know what behavior it produces (bug or not) -- often I even know enought about the data to help recognize variables and/or guess the likely control flow I care about. In fact, I suspect that adding a small feature is usually an easier route to start with the project's code. The problem is a small feature will not force me to gain a very deep understanding of the code like a difficult bug would -- so this is where it's critical to know my personal learning style and what I hope to get out of the experience (if anything more than an easy fix or small feature).
In contrast, without this context selecting a feature or fishing a bug out of bugzilla to get a cold read relies heavily on technical experience and conjecture to help me rapidly acquire context. For me hands-on experience with a project -- even non-technical hands-on experience -- really counts.
Of course this is also much harder if we're talking about code that's in lower layers of the "stack" (as with the kernel here). Those layers can often be reached with this method, a good packaging system (e.g. apt or yum on top of rpm or dpkg), and much patience.