The search terms you seek are "Semihosting" and "Segger RTT". From the name, you can guess that one company kind of drove the adoption, but it's a simple array of circular queues that allows for separate streams for stdin, stdout, files, console, and more.
I've not reviewed these articles in depth at this moment, but seemingly providing reasonable overviews at a glance, we have (at least):
https://www.codeinsideout.com/blog/stm3 ... #debugging
https://www.segger.com/products/debug-p ... -transfer/
https://www.segger.com/news/231109-pr-j-link-vscode/
https://stackoverflow.com/questions/380 ... bugging-fr
... and more. With a little work, you can create your serial console to shove data into the semihosting system, have openocd/jlink/gdb noticed that the tail pointers moved, shovel them over DMA, and then have clever software on the host side format it, syntax highlight it, display errors, or whatever floats your boat.
The basic process seemed to first be popularized on STM parts, but it's now on CH32, most ESP32 devices, and multiple RISC-V devices and cores. Each has some funky rules, but the process is recognizable everywhere.