In this part, I will describe which events the debugger has to deal with and how it should respond to them. Additionally, we will create few COM wrappers for
ICorDebug* interfaces. Let’s first examine the
ICorDebugManagedCallback interface (imported from COM object – more in part 1). You may notice that each event handler has its own set of parameters, but the first parameter is always of type either
ICorDebugController which allows you to control the debuggee.
In part 1, we ended with an application that could start a new process or attach to the running one and then stop it. We will now find a way to make the process running and log all events coming from it. Let’s introduce a simple
HandleEvent method which will be called from all other event handlers (except
void HandleEvent(ICorDebugController controller)
All events handlers bodies (except
ICorDebugManagedCallback.ExitProcess) will now look as follows:
If we now execute our application, it will print few “event received” messages and then stop. Under the debugger, we will see that the debugging API throws a COM exception:
System.Runtime.InteropServices.COMException crossed a native/managed boundary
Message=Unrecoverable API error. (Exception from HRESULT: 0x80131300)
at MinDbg.NativeApi.ICorDebugController.Continue(Int32 fIsOutOfBand)
It took me some time to figure out why this error occurred. It seems that in order to be able to receive all managed events, the debugger must be attached to the debuggee appdomains. So I needed to modify the
ICorDebugManagedCallback.CreateAppDomain handler by adding one new instruction:
(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain)
Finally, our debugged process executes normally without any interruption from the debugger side.
Let’s now focus on the second topic of the post: ICorDebug COM wrappers. As COM objects are not very comfortable in use and certainly we don’t want to pass them outside the bounds of the assembly, we need to create a way to represent them in our application. For each used ICorDebugName interface we will create a CorName class that will implement methods and properties which will give access to the inner COM object API. Additionally these wrappers should be comparable so we could later check whether the object returned from a callback function is the same as the one that we already have. This is even better explained in the mdbg source code – look at the comment for the
WrapperBase class. Our
WrapperBase class would be actually almost the same as the one in mdbg sources:
That’s all for today. The source code for the second part is available here. You may also connect to the TFS repository and download the 54704-th revision of the code.
Filed under: CodeProject