You don't put printf() in critical sections, instead you collect some statistics. Once critical section is over you can freely print collected data for further analyzis. Or you can print it once a second. This simple technique works well for debugging racing conditions, performance issues (profiling), memory leaks, kernel drivers and bare-metal stuff where timing is a concern. So, yes "Print debugging always works...", but must be used wisely. :-)