You can trivially add printf-like statements on the fly with debuggers; with GDB, one method I often use is the ability to attach commands to breakpoints, to be executed when the breakpoint is hit.
break SourceFile.cpp:123
command
pp var1
pp var2
continue
end
With that `continue` at the end there, this breakpoint will not pause execution (except to run the commands).