Sometimes my method is instead to look at data output at a certain level of abstraction like system calls (which is usually not helpful except for detecting a network hang or a path config whose directory doesn't exist) or database queries or something. That is usually more helpful if I either already suspect I know where the problem is and need to know what model name or file name to `ag` for.
If (Hephaestus be praised) there is actually an automated test framework in place, I'll start by writing a failing test or copy-pasting an existing test and modifying it to fail, then (if it isn't JavaScript), inserting a debugger into a function the test calls.
All of this tends to be pretty successful.
But I've occasionally found myself on a project where I just have a sense that I don't know what is going on or how pieces fit together and I feel a strong temptation to stop and fix that sense of bewilderment. When I resist this urge is when it feels like I am trying things at random.