You can’t debug your own process. Both managed and native debugging are process-wide, and so the debugger would end up freezing itself.
The problem is that a debuggee generates some debug event (perhaps hitting a breakpoint), and then stops until the debugger calls some sort of Continue method. If the debugger was debugging itself, as soon as it hit a debug event, it would suspend itself, and thus be unable to call Continue. It’s like a thread calling SuspendThread on itself with nobody to resume it.
You can spawn a debugger that attaches to you. This is what happens at an unhandled exception. We call the scenario “JIT-attach”. But that’s still leaves you with separate debuggee and debugger processes.
On alternative would be to have the debugger be in a hidden “proxy” process. The gui would still be in the debuggee, but it would have some secret communication with the debugger. Specifically, when it generated a debug event:
1) the proxy debugger would get it,
2) use the debugging API to do SetValue / Func-eval to queue it in the debuggee,
3) suspend certain debuggee threads,
4) and then resume the debuggee so that the gui (in the debuggee process) could handle the event.
The gui would constantly need to be communicating with the hidden debugger process to do all the real debugging work. But it would present the user the facade of a single application with an embedded debugger. I’m not 100% convinced this will actually work – at least not until I write up a demo of it. Intuitively, it does seem that some combination of cross-process communication, thread suspension, and handshaking could make this illusion work. I’m not recommending it, I’m just mentioning it for completeness sake.
We may or may not add some sort of “partial-process debugging” in some future version, which may support this.