Here are some random notes about specific ICorDebug breaking changes between .NET v1.1 (Everett) and .NET 2.0 (Whidbey). (I came across these as I was cleaning out old documents in preparation for my upcoming move). This would have been more timely 2 years ago, but better late than never.
This can be viewed as the checklist for migrating a managed debugger from v1.1 to v2.0. This is pretty detailed. But I’m not 100% sure if this is quite authoritative enough to put my “This should be in MSDN” tag on, it’s not necessarily complete, and it’s based off notes I had lying around that are several years old. Disclaimers aside:
- ICorDebugThread::GetCurrentException return code changed from E_FAIL to S_FALSE when the current thread has no exceptions.
- ICorDebugEnum return values changed to be COM compliant.
- More aggressive enforcement of object lifetimes. This means calls that used to succeed (though possibly provide wrong information) will now fail with CORDBG_E_OBJECT_NEUTERED.
- Client Debuggers must implement ICorDebugManagedCallback2 to debug v2.0 apps.
- The timeout to ICorDebugController::Stop is now ignored.
- Callstacks may now include ICorDebugInternalFrame instances. So the assumption that any frame could be successfully QIed for either ICorDebugILFrame or ICorDebugNativeFrame is now false.
- You may no longer call EnableJITDebugging on Modules whenever you please or even on attach. The only time this is valid is during the real ModuleLoad callback. Other calls will return various error codes explaining what you did wrong. We recommend that people begin using ICDModule2::SetJITCompilerFlags instead.
- We now track JIT info all the time, which is not really a “breaking change” but still something that may confuse people if they try to turn it off and it remains on. One place this may break is if you try to use the presence of the “Track Jit Info” flag to tell if code is debuggable or not.
- CorDebug is no longer a coclass. It is now instantiated by mscoree!CreateDebuggingInterfaceFromVersion.
- Order of LoadClass and UpdateModuleSyms callbacks changed.
- Interop: Native Thread-exit debug event is now Out-Of-Band.
- Interop: OOB-breakpoints / single-step events are now automatically cleared, and not rewound. Debuggers should use ICorDebugProcess2::SetUnmanagedBreakpoint instead of calling WriteProcessMemory(“int 3”) themselves.
Some areas of intensive bug fixing that could be perceived as behavior changing:
- Fixes to handling debugging dynamic modules.
- Fixes to add-ref release bugs which were heavily flushed out by Mdbg. (These bugs were part of the reason that MDbg can’t run on 1.1)
See also “What’s new in .Net 2.0.” for cool new things in 2.0.