FWIW, I've been working on some managed wrappers for the native debugging API (kernel32!WaitForDebugEvent,etc)

My goals are:

  1. Make it extremely easy to use the native debugging API. 
  2. Maintain fidelity to the native debug API. I didn’t want a super thick wrapper, but I was willing to track some extra state to make things easy.
  3. Smooth over various warts of native-debugging. Eg, dealing with the loader breakpoint, knowing what you’re supposed to close on ContinueDebugEvent, continuing OutputDebugString events.  It also gives me a chance to embed key API trivia in xml comments.
  4. Making it cross-plat, particularly working on both 32 and 64 bit. Importing DEBUG_EVENT for both 32 and 64 bit was annoying. If you put the abstractions at the right place, the debugging API is pretty cross-platform from the client end, although some implementations (eg, setting a single-step flag) are of course platform specific.
  5. Provide useful utility functions, like getting the module name from a LoadDll event or message string from a OutputDebugString event.

In my test app, the debugger's main loop could be something like:

        NativePipeline dbg = new NativePipeline();

while (true)
NativeEvent e = dbg.WaitForDebugEventInfinite();

Console.WriteLine("Event:{0}", e);

if (e is ExitProcessDebugEvent)

And that prints something like:

Event:Event Type:tid=2540, code=CREATE_PROCESS_DEBUG_EVENT
Event:DLL Load:Address 0x7c900000, ntdll.dll
Event:DLL Load:Address 0x79000000, C:\WINDOWS\system32\mscoree.dll
Event:DLL Load:Address 0x7c800000, C:\WINDOWS\system32\KERNEL32.dll
Event:Exception Event:Tid=2540, 0x80000003, first chance, address=0x7c901230
Event:DLL Load:Address 0x77dd0000, C:\WINDOWS\system32\ADVAPI32.dll
Event:DLL Load:Address 0x77e70000, C:\WINDOWS\system32\RPCRT4.dll
Event:DLL Load:Address 0x77f60000, C:\WINDOWS\system32\SHLWAPI.dll
Event:DLL Load:Address 0x77f10000, C:\WINDOWS\system32\GDI32.dll
Event:DLL Load:Address 0x77d40000, C:\WINDOWS\system32\USER32.dll
Event:DLL Load:Address 0x77c10000, C:\WINDOWS\system32\msvcrt.dll
Event:DLL Load:Address 0x79e70000, C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
Event:DLL Load:Address 0x78130000, C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0de06acd\MSVCR80.dll
Event:DLL Load:Address 0x7c9c0000, C:\WINDOWS\system32\shell32.dll
Event:DLL Load:Address 0x773d0000, C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2180_x-ww_a84f1ff9\comctl32.dll
Event:DLL Load:Address 0x5d090000, C:\WINDOWS\system32\comctl32.dll
Event:DLL Load:Address 0x60340000, C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\culture.dll
Event:Event Type:tid=4072, code=CREATE_THREAD_DEBUG_EVENT
Event:Event Type:tid=4120, code=CREATE_THREAD_DEBUG_EVENT
Event:DLL unload:Address 0x60340000,C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\culture.dll
Event:DLL Load:Address 0x790c0000, C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\mscorlib\634bc4cfaf50134f9bc49aedecf3b262\mscorlib.ni.dll
Event:DLL Load:Address 0x774e0000, C:\WINDOWS\system32\ole32.dll
Event:DLL Load:Address 0x79060000, C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorjit.dll
Event:OutputDebugString:tid=2540, message=cat
Event:OutputDebugString:tid=2540, message= :
Event:OutputDebugString:tid=2540, message=Hi!
Event:OutputDebugString:tid=2540, message=
Event:Event Type:tid=4120, code=EXIT_THREAD_DEBUG_EVENT
Event:Event Type:tid=4072, code=EXIT_THREAD_DEBUG_EVENT
Event:Event Type:tid=2540, code=EXIT_PROCESS_DEBUG_EVENT


There's still an open question about what I'll do about symbols. At the raw API level, everything's pretty much policy-free. But once you get symbols you get a whole head-ache of symbol paths, symbol loading policy, symbol servers, diagnosing symbol failures, which symbol API to use, how much of the symbol API to import, etc.

My plan is to roll these into the MDbg sample, and so interested parties will get the full source to them.

[Update:] Source is now available here.