You can’t debug yourself

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.



Comments (4)

  1. I could see having the "debugger" UI in a separate thread in the debugee process, and having the debugger enable that one thread to run for ui purposes. The only advantage in that would be to be able to access process data with low overhead. It "might" be possible to have the debugger run in-process if individual threads can be suspended when a break point is hit. But, it sounds like all threads break on a breakpoint (which of course is what is normally wanted). Given that the research direction is toward software isolation of light weight processes, using the current multi-process debugging experience may be the best approach. If the code under debug (plug-in) was running in a sub-process then the main UI process could host the debugger for the plug-in code at least. For the end-user debugger on script code this might work best.

  2. David Srbecky says:

    It actually may be a very useful feature. It basically means that you can debug a code running in an other thread. Imagine a 3D game (yes, we all love them). You run your code OnDoorOpen {monster.PlaceBehindDoor(); monster.Rotate(180);} in a separate thread, but it does not work. Traditional external debugger is going to give you a lots of numbers and raw data structures. However, if you just debug the separate thread from the main thread, you can keep playing the game while you are stepping though the code. So you can see the that PlaceBehindDoor works as expected but Rotate rotates the monster around the center of map.

    Other example is: You have a local variable Vector v = …; It should not be difficult for the main thread (ie our debugger) to get the variables and show them in the space. Much better than numbers.

    I am thinking along these lines for a quite long time and it is the main reason why I am making my debugger as .NET Remoting friendly as possible.

  3. I’ve gotten some questions about using a profiler to do inspection a managed process. The best blogs…

  4. Don’t have your non-debugger app use the debugging services just to get some cool functionality. The