Debug Like a Scientist
When you're working on a bug your goal is to figure out why things aren't working as you'd expect them to be (and hopefully correct this issue). If the source of this issue isn't obvious it can be useful to approach your problem like a scientific discovery.
To avoid randomly thrashing around your codebase you should come up with a hypothesis, test it, keep notes about what you've learned, and keep refining until you understand why your code doesn't work the way. Coming up with a good hypothesis is crucial. You need to take what you know and come up with a good question and theory about the answer that will provide useful information when tested. You will likely need to take a few steps back and figure out explanations for sub-problems before you can full answer your original question.
You can make better hypotheses by knowing your codebase better and just getting more experience tackling bugs.
The most important part of testing your hypothesis isn't whether or not it was right but what you learned from it. To this end, make sure you keep a lab notebook (this can be anything from a text file where you keep notes while you're working to an actual notebook with notes and diagrams) and write down everything you learn along the way. As you explore your problem you might need new "lab equipment" to get the information you need. This could be anything from "print debugging" to building custom tools to get insights into how your program is running and the data it produces.
Approaching a problem in a scientific manner can be a powerful tool when faced with unknowns.