Click here to Skip to main content
12,703,012 members (32,168 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


2 bookmarked

Writing a .NET debugger (part 2) – Handling events and creating wrappers

, 28 Oct 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
Writing a .NET debugger (part 2) – Handling events and creating wrappers

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 ICorDebugAppDomain or ICorDebugProcess. Both ICorDebugAppDomain and ICorDebugProcess implement 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 ICorDebugManagedCallback.ExitProcess):

void HandleEvent(ICorDebugController controller)
    Console.WriteLine("event received");

All events handlers bodies (except ICorDebugManagedCallback.ExitProcess) will now look as follows:

    HandleEvent(pAppDomain); // or HandleEvent(pProcess) if first parameter is pProcess

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)
       at ...

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:

void ICorDebugManagedCallback.CreateAppDomain
	(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:

/// <span class="code-SummaryComment"><summary>

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, Debugging


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Sebastian Solnica
Software Developer (Senior)
Poland Poland
Interested in tracing, debugging and performance tuning of the .NET applications.

My twitter: @lowleveldesign
My website:

You may also be interested in...


Comments and Discussions

-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170118.1 | Last Updated 28 Oct 2010
Article Copyright 2010 by Sebastian Solnica
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid