If you were to take the pain points of debug by print, and address them, you'd come up with a debugger. Being able to put those "print" statements anywhere without recompiling, being able to go step-by-step in the code, etc. And sure, that's not always available.
Both end up having impacts on the thing they observe. A print() call can cause microscopic delays that are enough to cause a race condition not to trigger, as can waiting on a breakpoint, etc. If you compile with debug symbols, that can cause some bugs not to surface, as they are only visible when you compile with -O3 or whatnot (eg. a bug involving reading unallocated memory).
Both are just tools. Sometimes one is better in a given situation. Sometimes the other is. I just don't get how this is like an emacs vs vim thing.