The stop count and trivia

ICorDebug maintains a stop-count, and so if you call ICorDebugProcess::Stop() twice in a row, the 1st stop does the real asynchronous-break, and the 2nd stop is basically a nop that just increments a counter. You’ll then need to call ICorDebugProcess::Continue() twice. The first Continue() call just decrements the stop-counter; and then the 2nd call does the real continue.

More trivia:
1) A debugger implements Async-break by calling ICDProcess::Stop().  That API is synchronous and will block until the debuggee stops. In fact, that is one of the few synchronous invasive methods in all of ICorDebug. Once it successfully returns, the debuggee is synchronized and you need to call an extra Continue() to resume it. 
2) Dispatching a callback bumps up the stop-counter, and so it takes 1 call to Continue() to resume from a managed event callback. So if you call stop inside a callback, then you’ll need to call an extra Continue.
3) You can also call both Stop + Continue on any threads.

Why have a stop-count?
You could call Stop() on thread 1 which could race with ICD’s thread dispatching a managed debug event. This scenario is a motivation for the stop-count. If we didn’t have the stop-count, then Continuing the Stop() on thread 1 may accidentally continue the debug event too.

Comments (4)

  1. j.stagner says:

    Is this stop count reflected in the results from ICorDebugProcess.IsRunning ?

    I should probably know the answer to this I suppose, but the debugger UI I am building doesn’t currently allow the user to stop the debuggee without actually terminating and doesn’t do so itself (it only stops on debug events) so it hasn’t been an issue so far.

  2. IsRunning just yields a bool, so you can’t use it to determine the stop-count.

    IsRunning is also very dangerous in a multi-threaded scenario because the results may get invalidated by another thread. Similar issues with IsBadReadPtr().

    Your UI will probably need some sort of async-break event. Somebody’s going to write an infinite loop and want to figure out why their program is hung. They async-break, look at the call stacks and hopefully then notice the problem.

  3. j.stagner says:

    I notice that Mdbg tracks the stop count itself, so I guess that’s the recommended way?  

    I know I’ll need async-break eventually, I just haven’t implemented it yet, as there are so many "interesting" things to do with a debugger.

    ICD is huge, and has a whole lot of power and functionality, and I’m just taking it a step at a time 😉

    Once again, very glad that you have an active blog!!!