Why Isn't Debugging Treated as a First-Class Activity?
One practice I don't think I've ever really seen properly discussed is exploratory debugging. Given a large codebase I'm not familiar with, I've found that this workflow is an incredibly fast way to get familiar with the overall flow and structure of the code:    - run the thing
    - grab an output string of some sort (either output proper or logs or whatever else)
    - grep for it
    - set a breakpoint where the string is generated
    - run again

From there, you can explore the stack, and you start to get your bearings. How is this particular thing generated? Find the place in the stack where it first shows up, set a break point, start over and debug from there. Repeat until you have a sufficiently solid grasp of the codebase that you can just navigate the source tree searching for where things are.