All the options above nice and can help you. But i can't see how setting TracePoing with mouse can help you in case you code have thousands of functions.
This kind of thing should be part of your regular programming work. When you writing a function you should think what trace message will help you to debug it.
You need to write/use existing logger that can be spitted to section (reader thread, worker thread, etc... )and different logging levels (error, warning,trace, verbose etc.. ). The good logger should be designed in the way it's not hurt you performance, this usually harm the verbosity, but complex synchronization problems usually can be reproduced unless the logging is very fast, like assigning a string pointer to the array that can be dumped after problem is reproduced. I usually start debugging with full trace dumped to the screen and if i lucky and bug reproduced this way, fixing the bug is trivial because i already have enough information, the fun starts when problem goes away and you need to play with verbosity in order to reproduce the problem.
I actually find debugging more creative and satisfying than code writing, but this is just me :).