How to determine where a program is spending its time during execution