> Like I said, different tools for different uses, and really depends on the context
We totally agree, and I'm not sure what we're arguing about--perhaps you can fill me in.
I'm arguing that print is almost always worse than any specialized tool. (After all, who would use a specialized tool worse than print?) There is not a one-size-fits-all tool, and print is not a one-size-fits-all tool.
Indeed almost every seasoned developer has a story about print failing. Whether it's the mysterious "Heisenbug" that disappears when you measure it (like the sync issues you mention) -- my personal story is when I was trying to debug a (class project) kernel scheduler. Printing to the console was so slow that by the time I'd printed anything, the scheduler had moved on to the next time slice!
It's worth nothing that "print debugging" is not literally just using the "print" function; it's a style of debugging that involves logging specific information using some logging function (usually, but not always, print) and then analyzing it after the fact (usually, but not always, by reading the printed output).
This strategy of "get data out, then analyze it" is the general form of print debugging, and in the small-memory case, or the sync Heisenbug case, this often means collecting data in the appropriate variables before outputting it to be visible. Isn't this still print debugging, even though it doesn't use a "print" function?