The protocol you've linked (or the similar gdbserver protocol) essentially implements an IDE <-> debugger mapping. Well, most of one: everything is basically being passed as strings, so if you want smart stuff, you kind of have to build in the smart stuff yourself. It doesn't help the other parts of the process; if you want to build a new gdb, you have to do all the parsing of debug info for C, C++, Drustzig, etc. yourself... and you have to integrate the compiler expression stuff yourself. If you want to build a better time-traveling debugger, or a better crash debug format, or something similar, well, the gdb remote protocol lets gdb talk to your tool so all you have to implement is essentially low-level program state (e.g., enumerate registers of a thread, read/write arbitrary memory locations, etc.). But this isn't covered by the thing you've listed either, and it still relies on the debugger supporting a particular protocol.
> I can implement the LSP and get support for IDEs essentially for free I mean, technically same is true for DAP... You can implement DAP and get support for IDE for free. But I agree that in general case implementing a good debugger is harder than implementing a good language server.
If Drustzig requires a special debugger (e.g. because it uses acustom format of debug information), then you'd need to implement it, yes. However, existing debuggers can support new languages relatively easy if those follow standard conventions (e.g. use PDB and DWARF). For example, Rust support in LLDB basically comes down to a custom demangler.
Again, I'm not saying that DAP is perfect and solves debugging, but IMO it's a step in the right direction. Make it popular, make it extensible. Debuggers can be mostly language agnostic (within reasonable bounds), but they don't _have_ to be.
Painfully. If you're on Linux, you get to use a mixture of poorly-documented (e.g., ptrace) and undocumented (e.g., r_debug) features to figure out the state of the program. Combine this with the debugging symbols provided by the compiler (DWARF), which is actually a complicated state machine to try to encode sufficient details of the source language, and careful reading of the specification makes you throw it out the window and just rely on doing a well enough job to keep compatibility with gdb.
> Why can't more compiled languages integrate debuggers inside of them so that you can debug the program without using a separate tool?
Because it's really painful to make debugging work properly. At least in the Unix world, the norm is for all of these tools to be developed as separate projects, and the interfaces that the operating system and the standard library and the linker and the compiler and the debugger and the IDE all use to talk to each other are not well-defined enough to make things work well.
> And why can't we create interfaces to debuggers so that other text editors can integrate with them, much like how we do we LSPs?
LSPs have the advantage of needing to communicate relatively little information. At its core, you need to communicate syntax highlighting, autocomplete, typing, and cross-referencing. You can build some fancier stuff on top of that information, but it's easily stuffed in a single box.
Debuggers need to do more things. Fundamentally, they need to be able to precisely correlate the state of a generated build artifact to the original source code of the program. This includes obviously things like knowing what line a given code address refers to (this is an M-N mapping), or what value lives in a given register or stack location (again an M-N mapping). But you also need to be able to understand the ABI of the source level data. This means you can't just box it as "describe language details to me", you also have to have the tools that know how to map language details to binary details. And that's a combinatorial explosion problem.
It's true that coming up with an interface for an abstract debugger is harder, but it's not impossible. Microsoft created Debug Adapter Protocol (https://microsoft.github.io/debug-adapter-protocol/), which is conceptually similar to LSP. It's not perfect, but covers most basic operations pretty well, while leaving to the debugger to deal with the implementation details.
That said, I still think there's quite a bit of improvement to be made, which is why I started building a new debugger for myself which puts a lot more focus on breakpoint-less workflow, speed of iteration and scripting ability: (demo) https://www.youtube.com/watch?v=qJYoqfTfuQk It's geared mainly for gamedev, but I also do use it many times to e.g debug itself.