Design Implications from boring details

You can discern a lot of information about an API from what appear to be subtle or irrelevant details For example, each ICorDebug object has a logical parent. (See here for a brief explanation of the different ICorDebug interfaces). Here’s a chart: ICorDebugProcess ICorDebugThread ICorDebugChain ICorDebugFrame, ICorDebugILFrame, ICorDebugNativeFrame ICorDebugAppDomain ICorDebugAssembly ICorDebugModule ICorDebugClass ICorDebugFunction ICorDebugCode ICorDebugBreakpoint…

2

Viewing the current Exception in the debuggeer

VS (and mdbg) expose the $exception pseudo-variable which shows you the most recent exception. (kudos to Shaykatc for mentioning this a year ago). Debugger authors can implement this with:     HRESULT ICorDebugThread::GetCurrentException([out] ICorDebugValue **ppExceptionObject) This will return an ICorDebugValue representing the current Exception object in the debuggee. Current exception means from the time the exception…

1

Random ICorDebugThread trivia

Here’s random information about ICorDebugThread that I hope eventually makes it into MSDN: 1. The managed CreateThread callback comes at the first bit of managed code that a thread runs. (I think this is a bad for these reasons, and instead it should come as soon as the CLR knows about the thread). This introduces the…

5

Multiple steppers on 1 thread and other trivia

ICorDebug has a nicely abstracted “Stepper” object, via ICorDebugStepper (I talked more about that here). You setup a stepper object (via CreateStepper), resume the process, and then get an aysnchronous “StepComplete” debug event when the stepper is finished. For example, you could setup a StepOut, Continue, and then get a StepComplete when the thread returns…

1

Debugabbility with Roundtripping Assemblies

I’ve gotten several questions about debugabbility IL round-tripping. Round-tripping is where you decompile an app (perhaps via ILDasm), potentially edit the IL, and then recompile it (perhaps via ILAsm). This is the backbone for rewriting an assembly, it’s what my Inline IL tool does, and I notice Dotfuscator does it too. Roundtripping between ILasm and…

5

Partition of ICorDebug

The ICorDebug API (the API for debugging managed apps) is about 70 total interfaces.  Here is how I’d group the interfaces together, along with my random comments about how various interfaces fit into the big picture. A quick comment about interface versioning:1. ICorDebug is a COM-classic unmanaged interface. Most of the interfaces are derived from…

2

Writing a debugger in VB

Some might consider writing a managed debugger in VB.Net to be an oxymoron. But maybe not. Here’s a VB.Net snippet that serves as a highly-specialized debugger to launch an app and print all the modules that get loaded. This is adapted from the C# sample snippet here that does the same thing. Although we know…

1

ICorDebug, MTA, STA.

ICorDebug (ICD) is a com-classic interface. In terms of COM threading models, ICorDebug is technically free-threaded (aka, should reside in the “neutral apartment”), which means that it manages its own threading. We go through great pains in the ICD to managed our own synchronization and takes internal locks accordingly. Also, calls to ICorDebug never block…

4

IL offset 0 vs. Native offset 0

Within a function, offset 0 into the native code stream corresponds to the very first native instruction in that function. Since the function is ultimately executed via native code (and not via interpreted IL), it’s safe to say that native offset 0 corresponds to the very start of the function.  When native-debugging, if you place…

5

ICorDebugStepper and using ICorDebugStepper2::SetJMC

We added Just-My-Code (JMC) stepping (the ability to step through just your code and skip code that’s not yours) in Whidbey. I blogged a demo from the end-user’s perspective here. In response to some email, I wanted to talk a little more about how a debugger can implement JMC from the ICorDebug level. Stepping basics:Managed…

4