So rather than something technical like "process crashed", most of my investigations begin with "user is frustrated because they did not accomplish their task". Then my why-tree will have branches for, say, "the label on this control was unclear", "there was no documentation for this feature", "it was not clear how to get to the correct documentation page", "user was afraid to click it -> because there was no Undo", "user didn't know this feature already exists", etc.
Usually, I have to go a few questions deep before I get to a geeky technical solution that can be solved by more programming. I'll typically come up with 4 to 6 actionable improvements, and half will be completely non-technical, and most of the rest will be less than one line of code (e.g., to rearrange or clarify).
Users don't like going to the effort of filing bug reports, so whenever someone does, it's a good indicator to me that 10 or 100 other people also failed at a similar task with my software, or will soon. Users are also resourceful, and will try 2 or 3 ways to solve something, so if they ultimately fail, it means the software failed at every path they tried. By attacking every problem at multiple levels, it's possible to improve results for a whole lot of people at once.
5 Whys's also needs to be preceded by a detailed representation of what happened and followed by multiple next actions that are tracked to completion.